pythonpython-3.xsympyequation-solvinglambdify

Python - Sympy - Solving equations numerically for multiple parameters in a grid


A given equation depends on an unknown variable (y) and a set of parameters. I would like to numerically solve for y, given each element of a grid with values of the parameters.

A simplified example of my attempted solution is as follows (y is the unknown variable and x is the parameter):

import numpy as np
import sympy as sp
x,y=sp.symbols('x y')
xgrid=np.arange(1,6)
f = sp.lambdify(x,sp.nsolve(x**2+y,y,2),"numpy")
print(f(xgrid))

However, I am getting the following error:

expected a one-dimensional and numerical function.

I was expecting to receive a vector with y=-x**2 for every value x in xgrid.

Please notice that the actual function of interest is not y=-x**2 as in the example, but a non-linear function that is implicit in both x in y.

Am I forced to do a loop over each value in the grid, or can I still use lambdify somehow? Thanks in advance!


Solution

  • The purpose of sympy.lambdify is to transform symbolic expressions into numerical ones. It makes no sense "lambdyfing" sympy.nsolve as the latter is (by default) a numerical function. If you need to define a "wrapper" function for sympy.nsolve you should do so by using the standard python approach.

    def f(x):
        y = sp.symbols('y')
        return float(sp.nsolve(x**2+y,y,2))
    

    Now calling f(xgrid), where xfrid is an ndarray makes no sense as the function accepts scalar arguments. You need to write a loop. If you are feeling lazy, you could instead use the convenient np.vectorize function, which makes a function evaluate for ndarrays even when it is defined only for scalar arguments. However, note that this approach is essentially a shorthand for a loop, i.e., it performs the exact same computations as if you had explicitly written a loop.

    f = np.vectorize(f)
    f(xgrid)
    

    array([ -1., -4., -9., -16., -25.])