API Reference

This section contains a summary of QBee functions and variables.

qbee.polynomialize_and_quadratize(system: ~qbee.polynomialization.EquationSystem | list[sympy.core.symbol.Symbol, sympy.core.expr.Expr], input_free=False, input_der_orders=None, conditions: ~typing.Collection[~typing.Callable[[~qbee.quadratization.PolynomialSystem], bool]] = (), polynomialization_upper_bound=10, calc_upper_bound=True, generation_strategy=<function default_generation>, scoring: ~typing.Callable[[~qbee.quadratization.PolynomialSystem], int] = <function default_scoring>, pruning_functions: ~typing.Collection[~typing.Callable[[...], bool]] | None = None, new_vars_name='w_', start_new_vars_with=0) QuadratizationResult | None

Polynomialize and then quadratize a system of ODEs with the continuous right-hand side.

Parameters:
  • system – system of equations in form [(X, f(X)), …] where the left-hand side is derivatives of X.

  • input_free – if True the function will not introduce derivatives of input functions.

  • input_der_orders – a mapping of input variables to maximum order of their derivatives. For example, {T: 2} => T’ and T’’ are introduced.

  • conditions – a list of predicates PolynomialSystem -> bool the quadratized systems must comply with. For example, use partial(without_variables, [x1, x2]) to stop the algorithm from using x1 and x2 in new varaibles.

  • polynomialization_upper_bound – how many new variables the polynomialization algorithm can introduce.

  • calc_upper_bound – if True a non-optimal quadratization will be quickly found and used as upper bound. Disable if you already know an upper bound and add it in pruning_functions via pruning_by_vars_number.

  • generation_strategy – a function for proposing new variables during quadratization evaluation.

  • pruning_functions – a predicate indicating should the algorithm drop a current branch. Unlike conditions parameter, prunings apply to each intermediate result, not just to quadratizations. Check functions starting with pruning_by to see examples.

  • new_vars_name – base name for new variables. For example, new_var_name=’z’ => z0, z1, z2, …

  • start_new_vars_with – initial index for new variables. Example: start_new_vars_with=3 => w_3, w_4, …

Returns:

a container of a quadratized system and new variables introduced or None if there is nothing found

Example

>>> from qbee import *
>>> from sympy import exp
>>> x, y, u = functions("x, y, u")
>>> p = parameters("p")
>>> polynomialize_and_quadratize([(x, y / (1 + exp(-p * x))), (y, x * exp(y) + u)], input_free=True).print()
Introduced variables:
w_0 = 1/(1 + exp(-p*x))
w_1 = exp(y)
w_2 = exp(-p*x)
w_3 = w_1*x
w_4 = w_0*y
w_5 = w_0**2*w_2*y
w_6 = w_0**2*w_2

x' = w_4
y' = u + w_3
w_0' = p*w_4*w_6
w_1' = u*w_1 + w_1*w_3
w_2' = -p*w_2*w_4
w_3' = u*w_3 + w_1*w_4 + w_3**2
w_4' = p*w_4*w_5 + u*w_0 + w_0*w_3
w_5' = -p*w_4*w_5 + 2*p*w_5**2 + u*w_6 + w_3*w_6
w_6' = -p*w_4*w_6 + 2*p*w_5*w_6
>>> polynomialize_and_quadratize([(x, y**3), (y, x**3)], new_vars_name="c_", start_new_vars_with=1).print()
Introduced variables:
c_1 = y**2
c_2 = x**2
c_3 = x*y

x' = c_1*y
y' = c_2*x
c_1' = 2*c_2*c_3
c_2' = 2*c_1*c_3
c_3' = c_1**2 + c_2**2
>>> upper_bound = partial(pruning_by_vars_number, nvars=10)
>>> res = polynomialize_and_quadratize([(x, x**2 * u)], input_free=True, pruning_functions=[upper_bound, *default_pruning_rules])
>>> print(res is None)
True
qbee.quadratize(poly_system: list[sympy.polys.rings.PolyElement] | list[sympy.core.symbol.Symbol, sympy.core.expr.Expr] | ~qbee.polynomialization.EquationSystem, input_der_orders=None, input_free=False, conditions: ~typing.Collection[~typing.Callable[[~qbee.quadratization.PolynomialSystem], bool]] = (), calc_upper_bound=True, generation_strategy=<function default_generation>, scoring: ~typing.Callable[[~qbee.quadratization.PolynomialSystem], int] = <function default_scoring>, pruning_functions: ~typing.Collection[~typing.Callable[[...], bool]] | None = None, new_vars_name='w', start_new_vars_with=0) QuadratizationResult | None

Quadratize a system of ODEs with the polynomial right-hand side.

Parameters:
  • poly_system – system of polynomial equations in form [(X, p(X)), …] where the left-hand side is derivatives of X.

  • input_free – if True the function will not introduce derivatives of input functions.

  • input_der_orders – a mapping of input variables to maximum order of their derivatives. For example, {T: 2} => T’ and T’’ are introduced.

  • conditions – a list of predicates PolynomialSystem -> bool the quadratized systems must comply with. For example, use partial(without_variables, [x1, x2]) to stop the algorithm from using x1 and x2 in new varaibles.

  • calc_upper_bound – if True a non-optimal quadratization will be quickly found and used as upper bound. Disable if you already know an upper bound and add it in pruning_functions via pruning_by_vars_number.

  • generation_strategy – a function for proposing new variables during quadratization evaluation.

  • scoring – an ordering function for new variables.

  • pruning_functions – a predicate indicating should the algorithm drop a current branch. Unlike conditions parameter, prunings apply to each intermediate result, not just to quadratizations. Check functions starting with pruning_by to see examples.

  • new_vars_name – base name for new variables. For example, new_var_name=’z’ => z0, z1, z2, …

  • start_new_vars_with – initial index for new variables. Example: start_new_vars_with=3 => w_3, w_4, …

Returns:

a container of a quadratized system and new variables introduced or None if there is nothing found

Example

>>> from qbee import *
>>> x1, x2, u = functions("x1, x2, u")
>>> quadratize(([x1, x1 + x1 * u), (x2, x1**2 * u)], input_free=True).print()
Introduced variables:
w0 = x1**2

x1' = u*x1 + x1
x2' = u*w0
w0' = 2*u*w0 + 2*w0
qbee.polynomialize(system: EquationSystem | list[sympy.core.symbol.Symbol, sympy.core.expr.Expr], upper_bound=10, new_vars_name='w_', start_new_vars_with=0) EquationSystem

Transforms a system of nonlinear ODEs to a system of polynomial ODEs.

Parameters:
  • system – system of equations in form [(X, f(X)), …] where the left-hand side is derivatives of X.

  • upper_bound – how many new variables the polynomialization algorithm can introduce.

  • new_vars_name – base name for new variables. For example, new_var_name=’z’ => z0, z1, z2, …

  • start_new_vars_with – initial index for new variables. Example: start_new_vars_with=3 => w_3, w_4, …

Returns:

a container of a polynomialized system and new variables introduced

Examples

>>> from qbee import *
>>> from sympy import exp, sin
>>> x = functions("x")
>>> polynomialize([(x, sp.exp(x) + sp.exp(2 * x))]).print()
Introduced variables:
w_0 = exp(x)

x' = w_0**2 + w_0
w_0' = w_0*(w_0**2 + w_0)
>>> x, u = functions("x, u")
>>> p = parameters("p")
>>> polynomialize([(x, p* sp.sin(x * u))]).print()
Introduced variables:
w_0 = cos(u*x)
w_1 = sin(u*x)

x' = p*w_1
w_0' = -p*u*w_1**2 - u'*w_1*x
w_1' = p*u*w_0*w_1 + u'*w_0*x
qbee.quadratize_dimension_agnostic(system: list[sympy.core.symbol.Symbol, sympy.core.expr.Expr], input_der_orders=None, input_free=False, print_intermediate=False, verbose_output=True)

Find a dimension-agnostic quadratization for a linearly coupled family of ODE system

Parameters:
  • system – the symbolic representation of the input family, where Dx is the coupling term for the variables x

  • input_der_orders – maximal oders for the input variables (if defined, overwrites input_free)

  • input_free – if an input-free quadratization is sought

  • print_intermediate – if the quadratization of the auxiliary ODE system from Proposition 4.7 should be printed

  • verbose_output – if set to True, will print an explanation of how the found dimension-agnostic quadratization works

Returns:

dimension-agnistic quadratization of the input family

qbee.pruning_by_nodes_processed(algo: Algorithm, _: PolynomialSystem, *args, nodes_processed: int)

Stops a search when the algorithm checks ‘nodes_processed’ nodes.

Example

>>> from functools import partial
>>> pruning = partial(pruning_by_nodes_processed, nodes_processed=100000)
qbee.pruning_by_vars_number(_: Algorithm, system: PolynomialSystem, *args, nvars: int)

Search for quadratization with at most ‘nvars’ components

Example

>>> from functools import partial
>>> pruning = partial(pruning_by_vars_number, nvars=10)
qbee.pruning_by_declining_variables(a: Algorithm, part_res: PolynomialSystem, *args, excl_vars: list[Tuple])

Prune out systems with excl_vars in quadratization

Example

Tupples will correspond to variables ordering: z in Ring(‘x, y, z’) => (0, 0, 1)

>>> from functools import partial
>>> pruning = partial(pruning_by_declining_variables, excl_vars=[(0, 0, 1)])
qbee.pruning_by_elapsed_time(algo: Algorithm, system: PolynomialSystem, *args, start_t, max_t)

Stops a search after ‘max_t’ seconds.

Example

>>> from functools import partial
>>> pruning = partial(pruning_by_elapsed_time, start_t=time(), max_t=100) # 100 seconds
qbee.pruning_by_nodes_without_quadratization_found(algo: Algorithm, _: PolynomialSystem, *args, nodes_processed: int)

Stops a search when the algorithm can not find a quadratization after checking nodes_processed nodes.

Example

>>> from functools import partial
>>> pruning = partial(pruning_by_nodes_without_quadratization_found, nodes_processed=1000)
qbee.without_variables(part_res: PolynomialSystem, excl_vars: list[Tuple])

Deny quadratizations which have excl_vars.

qbee.default_generation(system, excl_vars=None)

Standard generation strategy with different scoring functions

qbee.functions(names, *, laurent=True, **kwargs)

Dependent and input variables in differential equations. The syntax is identical to sympy.symbols.

Examples
>>> x, y, z = functions('x, y, z')
qbee.parameters(names, **kwargs)

Parameter variables in differential equations. The syntax is identical to sympy.symbols.

Examples
>>> p, k = parameters('p, k')
qbee.INDEPENDENT_VARIABLE

Independent variable for functions.

Example:
>>> from qbee import *
>>> from qbee.experimental import to_odeint
>>> from sympy import sin
>>> x, u = functions("x, u")
>>> res = polynomialize_and_quadratize([(x, sin(x) + u)])
>>> t = INDEPENDENT_VARIABLE
>>> my_odeint = to_odeint(res, {x: 1}, inputs={u: sin(t)})