Suppose you have computed fu
as a result of a sympy calculation:
fu= sy.cos(x)+sy.sin(y)+1
where
x,y = sy.symbols("x y")
are symbols. Now you want to turn fu
to a numpy function of (obviously) two variables.
You can do this by:
fun= sy.lambdify((x,y), fu, "numpy")
and you produce fun(x,y)
. Is there a way that lambdify
can produce fun(z)
with x,y=z
, i.e produce the following function:
def fun(z):
x,y=z
return np.cos(x)+np.sin(y)+1
According to the documentation of lambdify
you can nest the symbols in the first argument to denote unpacking in the signature:
import sympy as sym
x,y = sym.symbols('x y')
fu = sym.cos(x) + sym.sin(y) + 1
# original: signature f1(x, y)
f1 = sym.lambdify((x,y), fu)
f1(1, 2) # returns 2.4495997326938213
# nested: signature f2(z) where x,y = z
f2 = sym.lambdify([(x,y)], fu)
f2((1, 2)) # returns 2.4495997326938213
Even if this weren't possible to do within lambdify
, we could define a thin wrapper that unpacks the arguments to the lambdified function (although this would be one function call slower on each call, so for fast functions that get called a lot of times this might lead to measurable impact on the runtime):
f = sym.lambdify((x,y), fu) # signature f(x,y)
def unpacking_f(z): # signature f(z) where x,y = z
return f(*z)
Of course if the function is not for a single, throw-away use in a numerical solver (such as curve fitting or minimization), it's good practice to use functools.wraps
for wrappers. This would preserve the docstring automatically generated by lambdify
.