About

This notebook was created to follow the sympy code generation tutorial at this link


In [6]:
import sympy as sym
sym.init_printing()
x, y = sym.symbols('x y')
expr = 3*x**2 + sym.log(x**2 + y**2 + 1)
expr


Out[6]:
$$3 x^{2} + \log{\left (x^{2} + y^{2} + 1 \right )}$$

In [8]:
expr.subs({x: 17, y: 42}).evalf()
% timeit expr.subs({x: 17, y: 42}).evalf()


221 µs ± 948 ns per loop (mean ± std. dev. of 7 runs, 1000 loops each)

In [10]:
import math
f = lambda x, y:  3*x**2 + math.log(x**2 + y**2 + 1)
%timeit f(17, 42)


917 ns ± 2.67 ns per loop (mean ± std. dev. of 7 runs, 1000000 loops each)

In [12]:
g = sym.lambdify([x, y], expr, modules=['math'])
g(17, 42)


Out[12]:
$$874.6275443904885$$

In [13]:
%timeit g(17, 42)


906 ns ± 1.64 ns per loop (mean ± std. dev. of 7 runs, 1000000 loops each)

In [18]:
import numpy as np
xarr = np.linspace(17,18,5)
h = sym.lambdify([x, y], expr)
out = h(xarr, 42)
out


Out[18]:
array([ 874.62754439,  900.31920442,  926.38590757,  952.82765322,
        979.64444076])

lambdify constructs string representation of python code and uses python eval to compile


In [19]:
z = z1, z2, z3 = sym.symbols('z:3')

In [24]:
expr2 = x*y*(z1+z2+z3)
func2 = sym.lambdify([x, y, z], expr2)
func2(1,2, (3,4,5))
# Vector arguments can be done as tuples when using odeint... (see video/example)


Out[24]:
$$24$$

In [25]:
# How to efficiently deal with matrices without preconverting?
# Or just save as M, C, etc... What about pars? Third argument. Can it be dict or must it be tuple?
# How to efficiently save,

Chemistry...

In example, dict is converted to tuple, both for the constants used to define the lambda, and for the tuple for evaluation. So they are in the same order