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!
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.])
When this line f = sp.lambdify(x, sp.nsolve(x**2+y,y,2),"numpy") is executing, first python executes sp.nsolve(x**2+y, y, 2). It is the issue on your code, SymPy has one equation to resolve with 2 unknowns.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With