I'm doing some symbolic math with sympy, then generating a Python lambda function using eval
and sympy's lambdastr
utility. Here's a simplified example of what I mean:
import sympy
import numpy as np
from sympy.utilities.lambdify import lambdastr
# simple example expression (my use-case is more complex)
expr = sympy.S('b*sqrt(a) - a**2')
a, b = sorted(expr.free_symbols, key=lambda s: s.name)
func = eval(lambdastr((a,b), expr), dict(sqrt=np.sqrt))
# call func on some numpy arrays
foo, bar = np.random.random((2, 4))
print func(foo, bar)
This works, but I don't like the use of eval
, and sympy doesn't necessarily generate computationally-efficient code. Instead, I'd like to use numexpr
, which seems perfect for this use-case:
import numexpr
print numexpr.evaluate(str(expr), local_dict=dict(a=foo, b=bar))
The only problem is that I'd like to generate a callable (like the func
lambda), instead of calling numexpr.evaluate
every time. Is this possible?
You can make use of the lambdify
module, which allows you to transform SymPy expressions to lambda functions for efficient calculation. This is nice in its ability to return a function with an attached implementation.
Lambdify
ing your own function could look something like this:
func = lambdify((a,b),expr, dict(sqrt=np.sqrt))