Numerical Integration

You can quickly check the quadratization numerically by using a function qbee.experimental.to_odeint that turns the result into a numerical function that scipy understands. Let’s look at the in the example:

We define and quadratize a scalar system

\[ x' = p \sin(x) + u(t) \]

>>> import sympy as sp
>>> from qbee import *
>>> x, u = functions("x, u")
>>> p = parameters("p")
>>> system = [(x, p * sp.sin(x) + u)]
>>> res = polynomialize_and_quadratize(system, input_free=True)
>>> res.print(str_function=sp.latex)
Introduced variables:
w_{0} = \sin{\left(x \right)}
w_{1} = \cos{\left(x \right)}

x' = p w_{0} + u
w_{0}' = p w_{0} w_{1} + u w_{1}
w_{1}' = - p w_{0}^{2} - u w_{0}

Here we took advantage of the ability to both get a quadratic system in LaTeX and render it in the documentation.

\[ w_{0} = \sin{\left(x \right)}, w_{1} = \cos{\left(x \right)} \]
\[\begin{split} \begin{array}{l} x' = p w_{0} + u \\ w_{0}' = p w_{0} w_{1} + u w_{1} \\ w_{1}' = - p w_{0}^{2} - u w_{0} \end{array} \end{split}\]

Now we solve the system numerically for \(t \in [0; 100]\), \(p = 0.1\), \(u(t) = \sin(t)\):

>>> from qbee.experimental import to_odeint
>>> ts = np.linspace(0, 100, 10000)
>>> t = INDEPENDENT_VARIABLE
>>> my_odeint = to_odeint(system, {"x": 0.1}, {"p": 0.1}, {"u": sp.sin(t)})
>>> my_odeint_quad = to_odeint(res, {"x": 0.1}, {"p": 0.1}, {"u": sp.sin(t)})

>>> num_res = my_odeint(ts, rtol=1e-10)
>>> num_res_quad = my_odeint_quad(ts, rtol=1e-10)
>>> print("L-infinity distance between numerical solutions of the original ODE and the quadratized one: ",
>>>       np.linalg.norm(num_res[:, 0] - num_res_quad[:, 0], np.inf))
L-infinity distance between numerical solutions of the original ODE and the quadratized one: 1.5569859268538266e-07