4.4. Evaluating expressions#

SymPy expressions can be evaluated numerically in several ways. Let’s say you have an expression defined as follows:

a, omega, b, t = sym.symbols('a, omega, b, t')
f = sym.Function('f')
expr3 = a*sym.sin(omega) + sym.Abs(f(t))/sym.sqrt(b)
expr3
../_images/2063606ea6500e776b915b32a3413c2dbbdb7512de0a25ac497ecc912ba35b7b.png

And you have some values for which you want to evaluate of the expression:

values = {omega: sym.pi/4, a: 2, f(t): -12, b: 25}

You can evalute the expression using sym.subs:

expr3.subs(values)
../_images/d3f784e28dc75bd653ff4781627bc532dc7de546255f80ad4e629aca794d7407.png

Notice how the square root and fraction do not automatically reduce to their decimal equivalents. To do so, you must use the evalf() method:

expr3.subs(values).evalf()
../_images/0140548f5848b39485eda2a660030c9ad7eefec5a516afd1d8762aaec7cb1c67.png

To obtain machine precision floating point numbers directly and with more flexibility, it is better to use the sym.lambdify() function to convert the expression to a Python function. When using sym.lambdify(), all symbols and functions should be converted to numbers, so first identify what symbols and functions make up the expression.

eval_expr3 = sym.lambdify((omega, a, f(t), b), expr3)

sym.lambdify() generates a Python function and, in this case, we store that function in the variable eval_expr3. You can see what the inputs and outputs of the function are with help():

help(eval_expr3)
Help on function _lambdifygenerated:

_lambdifygenerated(omega, a, _Dummy_38, b)
    Created with lambdify. Signature:
    
    func(omega, a, f, b)
    
    Expression:
    
    a*sin(omega) + Abs(f(t))/sqrt(b)
    
    Source code:
    
    def _lambdifygenerated(omega, a, _Dummy_38, b):
        return a*sin(omega) + abs(_Dummy_38)/sqrt(b)
    
    
    Imported modules:

This function operates on and returns floating point values. However, it also support arrays of floats. For example:

eval_expr3(3.14/4, 2, -12, [25, 26, 27])
array([3.81365036, 3.76704398, 3.72305144])
Test yourself!

Create a symbolic expression representing Newton’s Law of Universal Gravitation. Use sym.lambdify() to evaluate the expression for two mass of 5.972E24 kg and 80 kg at a distance of 6371 km apart to find the gravitational force in Newtons. \(G\) equals \(6.67430\cdot 10 ^{-11}\)

All variables have been defined with:

G, m_1, m_2, r = sym.symbols('G, m_1, m_2, r')

Click –> Live Code to activate live coding!

from math import isclose
G, m_1, m_2, r = sym.symbols('G, m_1, m_2, r')
F = G*m_1*m_2/r**2
eval_F = sym.lambdify((G, m_1, m_2, r), F)
answer_correct = eval_F(6.67430E-11, 5.972E24, 80, 6371E3)
answer = 0

tolerance = 0.001
check_float = lambda a, b: isclose(a, b, rel_tol=0, abs_tol=tolerance)
answer = 
check_answer("answer",answer_correct, check_float)

4.5. Some examples#

SymPy has many possibilities. Check out the documentation if you’re curious. Some examples are shown below.

Take the derivative of \(\sin\left({x}\right) e ^ x\)

sym.diff(sym.sin(x)*sym.exp(x),x)
../_images/88611eda9401879419468b7500587c3015c489a63bc89f2aabd0b928b3462da4.png

Compute \(\int(e^x\sin{(x)} + e^x\cos{(x)})dx\).

sym.integrate(sym.exp(x)*sym.sin(x) + sym.exp(x)*sym.cos(x), x)
../_images/28d55be824980dc741ad40fc753a8617acf0e2bc0151d38183c60f184acb074d.png

Compute \(\int_{-\infty}^\infty \sin{(x^2)}dx\).

sym.integrate(sym.sin(x**2), (x, -sym.oo, sym.oo))
../_images/2ea61f491bea77a259ec499d541af4127d50eb61b5efd4cc20ed04bdd77394ae.png

Find \(\lim_{x\to 0}\frac{\sin{(x)}}{x}\).

sym.limit(sym.sin(x)/x, x, 0)
../_images/d81096050bd44ce57b5d5fe4208dfd494a47c011aecee7a2c422785cd87b6ef4.png

Solve \(x^2 - 2 = 0\).

sym.solve(sym.Eq(x**2 - 2,0), x)
../_images/9cbb813dd92da3329623663c900326d767d72e12f725ce314541001f5d472b5f.png

Find the eigenvalues of \(\left[\begin{smallmatrix}1 & 2\\2 & 2\end{smallmatrix}\right]\).

sym.Matrix([[1, 2], [2, 2]]).eigenvals()
../_images/4d8237f50001cee60c372bd1ec1f29797640d5d62955ab126f7ed6bc7c8221f5.png

Print \(\int_{0}^{\pi} \cos^{2}{\left (x \right )} dx\) using \(\mathrm{LaTeX}\).

sym.latex(sym.Integral(sym.cos(x)**2, (x, 0, sym.pi)))
'\\int\\limits_{0}^{\\pi} \\cos^{2}{\\left(x \\right)}\\, dx'

4.6. Gotchas#

Trial and error is an approach for many programmers, but you may want to prevent frequently made mistakes. Take a look at SymPy’s documentation on gotchas to accelerate your learning!

4.7. References#

[Moo23]

Jason Moore. Learn multibody dynamics, sympy. https://moorepants.github.io/learn-multibody-dynamics/sympy.html, 2023.

[SymPyDTeam23]

SymPy Development Team. Sympy documentation. https://docs.sympy.org/latest/tutorials/intro-tutorial/intro.html, 2023.