cutcutcodec.core.compilation.sympy_to_torch.lambdify.Lambdify¶
- class cutcutcodec.core.compilation.sympy_to_torch.lambdify.Lambdify(*args, **kwargs)[source]¶
Convert a sympy expression into an evaluable torch function.
Attributes¶
- argslist[str]
The ordered names of the input arguments of this function (readonly).
Examples¶
>>> from sympy import I, cos, exp, im, re, sqrt, sin, symbols >>> from torch import linspace, tensor >>> from cutcutcodec.core.compilation.sympy_to_torch.lambdify import Lambdify >>> >>> # case of Faucault pendulum >>> # angular earth speed, latitude, gravity, pendulum length, time >>> omega, theta, g, l, t = symbols("omega theta g l t", real=True) >>> z0, v0 = symbols("z_0 v_0", complex=True) # initial position and speed >>> w0 = sqrt(sqrt(g/l)**2 + omega**2*sin(theta)**2) >>> z = exp(-I*omega*sin(theta*t)) * ( ... z0*(cos(w0*t) + I*(omega*sin(theta)/w0)*sin(w0*t)) + (v0/w0)*sin(w0*t) ... ) >>> func = Lambdify( ... [z, z.diff(t)], cst_args={omega, theta, g, l}, shapes={(omega, theta, g, l), (z0, v0)} ... ) >>> print(func) \begin{align} \textbf{def}~f\left(g, l, omega, t, theta, v_0, z_0\right): \\ \quad x_{cst_3} \leftarrow \sin{\left(\theta \right)} \\ \quad x_{cst_0} \leftarrow \frac{1}{l} \\ \quad x_{cst_0} \leftarrow g x_{cst_0} \\ \quad x_{cst_1} \leftarrow x_{cst_3}^{2} \\ \quad x_{cst_2} \leftarrow \omega^{2} \\ \quad x_{cst_1} \leftarrow x_{cst_1} x_{cst_2} \\ \quad x_{cst_0} \leftarrow x_{cst_0} + x_{cst_1} \\ \quad x_{cst_0} \leftarrow x_{cst_0}^{0.5} \\ \quad x_{cst_1} \leftarrow \frac{1}{x_{cst_0}} \\ \quad x_{cst_2} \leftarrow i \omega \\ \quad x_{cst_3} \leftarrow x_{cst_2} x_{cst_3} \\ \quad x_0 \leftarrow t x_{cst_0} \\ \quad x_1 \leftarrow \sin{\left(x_{0} \right)} \\ \quad x_2 \leftarrow x_{1} x_{cst_1} \\ \quad x_0 \leftarrow \cos{\left(x_{0} \right)} \\ \quad x_3 \leftarrow t \theta \\ \quad x_4 \leftarrow \sin{\left(x_{3} \right)} \\ \quad x_4 \leftarrow - x_{4} x_{cst_2} \\ \quad x_4 \leftarrow e^{x_{4}} \\ \quad x_5 \leftarrow v_{0} x_{2} \\ \quad x_2 \leftarrow x_{2} x_{cst_3} \\ \quad x_2 \leftarrow x_{0} + x_{2} \\ \quad x_6 \leftarrow x_{2} z_{0} \\ \quad x_6 \leftarrow x_{5} + x_{6} \\ \quad x_6 \leftarrow x_{4} x_{6} \\ \quad x_5 \leftarrow v_{0} x_{0} \\ \quad x_0 \leftarrow x_{0} x_{cst_3} \\ \quad x_1 \leftarrow - x_{1} x_{cst_0} \\ \quad x_0 \leftarrow x_{0} + x_{1} \\ \quad x_7 \leftarrow x_{0} z_{0} \\ \quad x_7 \leftarrow x_{5} + x_{7} \\ \quad x_7 \leftarrow x_{4} x_{7} \\ \quad x_0 \leftarrow \cos{\left(x_{3} \right)} \\ \quad x_5 \leftarrow - \theta x_{0} x_{6} x_{cst_2} \\ \quad x_7 \leftarrow x_{5} + x_{7} \\ \quad \textbf{return}~\left[ x_{6}, \ x_{7}\right] \end{align} >>> >>> # parameters of the pantheon pendulum in Paris >>> position, speed = func( ... linspace(0, (23*3600+56*60+4)/4, 1_000_000), # a tour in 23h 56min 4s ... g=tensor(9.81), l=tensor(67.0), omega=tensor(7.292115e-5), theta=tensor(0.8524362), ... v_0=tensor(1+0j), z_0=tensor(0j), ... ) >>> print(position) tensor([ 0.0000+0.0000e+00j, 0.0215-2.8842e-08j, 0.0431-1.1534e-07j, ..., -2.1698+4.9477e-05j, -2.1583+4.6581e-05j, -2.1453+4.3373e-05j]) >>> print(speed) tensor([1.0000+0.0000e+00j, 1.0000-2.6776e-06j, 0.9999-5.3531e-06j, ..., 0.5574-1.4082e-04j, 0.5639-1.4032e-04j, 0.5711-1.3967e-04j]) >>>
Initialise and create the class.
Parameters¶
- exprsympy.core.basic.Basic
The sympy expression of the function.
- cst_argstyping.Iterable[sympy.core.symbol.Symbol], optional
Arguments that change infrequently enough to be cached. The subexpressions computed from this parameters will be cached as well. If the parameters change frequently, don’t specify them in
cst_args, This will slow down the function.- shapesset[frozenset[sympy.core.symbol.Symbol]], optional
If some parameters have the same shape, it is possible to give this information in order to find a more optimal solution for limited the allocations. It variable represents the set of all tensor subsets with the same shapes. For example, {frozenset({a, b, c}), frozenset({x, y})} means that a, b, and c are the same shape, and x and y as well.
- compileboolean, default=True
The default behavior is to translate the expression into C, compile it with gcc, import the compiled version and then use this function. If any of these steps fail, the calculation is performed dynamically via pytorch only. If False, the function is evaluated dynamically only. No compilation is performed. It’s faster to instantiate the first time but it’s generally slower to evaluate.
- safeboolean or set[sympy.core.symbol.Symbol], default=True
If True, the default behavior, then the tensors provided as input are not modified. This helps avoid unpleasant surprises but it is slower in certain cases. If False, no preventive copy is made. It is the fastest but the tensors provided as input can be modified in place. It is possible to be more precise by selecting only the variables to preserve, in this case, provide all the variables to be preserved.
- forward(**input_args: dict[str, Number | Tensor]) Number | Tensor | tuple[Tensor][source]¶
Fast evaluation of the expression.
No casts and verifications are performed here. For more flexible and safer use, please use the
cutcutcodec.core.compilation.sympy_to_torch.lambdify.Lambify.__call__function.Parameters¶
- **input_argsdict[str]
To each variable name present in the expression, associate the numerical value. All arguments have to be provided.
Returns¶
- result
The direct result of the underground function with compute the expression.