Reputation: 414
I have an equation 1x+2y=40 . I'd like to solve it for y (ie. get it to form y=...) And then substitute numbers for x to get numbers for y. My current semi-manual solution is as follows:
import matplotlib.pyplot as plt
import numpy as np
from sympy import symbols, solve
m=40
pa=1
pb=2
x, y = symbols('x, y')
eq = pa*x+pb*y-m
y= solve(eq, y)
print(y)
print(type(y))
print(type(y[0]))
# then watch on screen what y is and substitute by hand
x=np.linspace(1,4,41)
y=2-x/2
plt.plot(x,y)
Is there a better way to substitute numbers for x into solution and get numbers for y? (after 'solve' y seems to be of type list with one item of mystical type of 'sympy.core.add.Add')
Terveisin, Markus
Upvotes: 1
Views: 727
Reputation: 414
Thanks, I could not find this piece of very basic information in the tutorials or in the documentation.
Here is a full working example based on the previous answer:
from sympy import symbols, solve, lambdify
import numpy as np
m=40
pa=1
pb=2
x, y = symbols('x, y')
eq = pa*x+pb*y-m
[soly]= solve(eq, y)
print(f"y= {soly}")
print(f"y(2)= {soly.subs(x, 2)}")
yfx = lambdify([x], soly, 'numpy')
print(f"y(np.arange(10))= {yfx(np.arange(10))}")
Upvotes: 1
Reputation: 14500
The solve
function returns a list of expressions. It returns a list because in general there can be more than one solution to an equation:
In [17]: solve(x**2 - 2, x)
Out[17]: [-√2, √2]
If you know that there should only be one solution then you can extract it from the list any way you like e.g.:
In [12]: m=40
...: pa=1
...: pb=2
...:
...: x, y = symbols('x, y')
...: eq = pa*x+pb*y-m
...:
...: [soly] = solve(eq, y)
In [13]: soly
Out[13]:
x
20 - ─
2
The solution is given here as a symbolic expression involving the symbol x. You can substitute values for x with subs:
In [14]: soly.subs(x, 2)
Out[14]: 19
The subs
method performs a symbolic substitution that can handle substituting other symbolic expressions for x
:
In [19]: soly.subs(x, sqrt(2))
Out[19]:
√2
20 - ──
2
To evaluate the expression efficiently in ordinary floating point for many possible values of x using you can use lambdify
:
In [15]: yfx = lambdify([x], soly, 'numpy')
In [16]: yfx(np.arange(10))
Out[16]: array([20. , 19.5, 19. , 18.5, 18. , 17.5, 17. , 16.5, 16. , 15.5])
Note that it is a bad idea to overwrite a variable that you are using for a symbol like this:
y = solve(eq, y) # use a different name like ysol
It is a bad idea to do this because any subsequent use of the Python variable y
no longer refers to the original symbol y
which is a common cause of confusion for inexperienced users of SymPy.
Most of the points I mentioned above are covered in the official tutorial which I recommend reading:
https://docs.sympy.org/latest/tutorial/index.html
The lambdify
function is documented with a lengthy explanation here:
https://docs.sympy.org/latest/modules/utilities/lambdify.html#sympy.utilities.lambdify.lambdify
Upvotes: 1