Python – Sympy – Solving equations numerically for multiple parameters in a grid
Question:
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!
Answers:
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.
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.])
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!
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.
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.])