How to substitute variable in multiple equations in Sympy - python

for example, if I want to use solve a set of linear equations
eq1: x + y + 8z = 2
eq2: 2x + 6y + z = 5
suppose I already know the value of z, is there any way I can subsitute the z in eq1 and eq2 in one operation such as
linear_equations([eq1, eq2]).subs({z: 100})

You can use the Sympy library to achieve what exactly you are looking to solve.
Below is the code which will perform the substitution of the Z value and then solve the linear equation to find the values of x & Y values
from sympy import symbols
from sympy.solvers import solve
x,y,z = symbols('x y z')
expression1 = x + y + 8*z - 2
expression2 = 2*x + 6*y + z - 5
expression1 = expression1.subs(z,100)
expression2 = expression2.subs(z,100)
solution = solve([expression1, expression2], [x, y])
print(solution)

Related

Speeding up Sympy solve() on a particular equation

I am trying to solve an equation but the solve() function is taking over 10 minutes even on a high RAM colab notebook. Are there any simplifications to the problem that I can take to speed this along? Here is the code:
x, y, x_0, y_0, x_new, y_new, t, f = symbols('x y x_0 y_0 x_new y_new t f')
D = (2 * (1 - t) * sqrt(x * y) + t * (x + y)) / (2 * (x + y) * sqrt(x * y))
D_old = D.subs([(x, x_0), (y, y_0)])
D_new = D.subs([(x, x_new), (y, y_new)])
delta_D = D_new - D_old
target = Eq(delta_D, f)
answer = solve(target, x_new)
If it is taking a long time you must be trying to solve for one of the x or y values. This will require solving a messy cubic equation in many variables. It would be better if you just substituted in the values of interest and then used nsolve to find the roots of interest. Otherwise, you can get a symbolic solution to the generic cubic g3 = solve(a*x**3 + b*x**2 + c*x + d, x) and then substitute in the corresponding expressions for the coefficients of collect(sympy.solvers.solvers.unrad(target.rewrite(Add))[0], v) where v is the variable of interest. But I won't bog this down with more details until it is clear what you really want to do.

How to solve system of nonlinear equations with parameters in Python

I am trying to solve a system of nonlinear equations in Python. The equations have the form:
(1) x^2 + y^2 = a
(2)(x-b)^2 + y^2 = c
where x and y are the variables and a,b,c are parameters. I would like to have a function which i can pass the parameters a,b,c to and it returns me the values for x and y. How can I do that ?
What i currently have is
from scipy.optimize import fsolve
def equation(var, *data):
a,b,c = data
x,y = var
eq1 = x**2 + y**2 - a**2
eq2 = (x - b)**2 + y**2 - c**2
return [eq1, eq2]
x,y = fsolve(equation, args=data)
But this does not quite work. Can someone help?
I think it is just missing the initialized values
from scipy.optimize import fsolve
def equation(var, *data):
a,b,c = data
x,y = var
eq1 = x**2 + y**2 - a**2
eq2 = (x - b)**2 + y**2 - c**2
return [eq1, eq2]
x,y = fsolve(equation,[1,1], args=(1,1,1))
print(x,y)
Taking inspiration from geometrical interpretation of Thierry Lathuille, there is maybe no real need to use a nonlinear solver.
First, Eq. (1) requires y^2=a^2-x^2 and thus (x-b)^2+a^2-x^2=c^2 according to Eq. (2). The latter equality simplifies to b^2-2bx+a^2=c^2 with xSol=(a^2+b^2-c^2)/(2b) as the possible solution for x (the symmetry suggest that there'll be only one solution for x). With this solution for x, we can check the sign of a^2-xSol^2. If negative, then there is no solution. If non-negative, then the solutions are (xSol,+ySol) and (xSol,-ySol) with ySol=np.sqrt(a^2-xSol^2).
Based on some testing with the code below, the solution above seems to work (but correct me if I'm wrong).
from scipy.optimize import fsolve
import numpy as np
abc = (1,1,4)
# Nonlinear optimizer
def equation(var, *data):
a,b,c = data
x,y = var
eq1 = x**2 + y**2 - a**2
eq2 = (x - b)**2 + y**2 - c**2
return [eq1, eq2]
x,y = fsolve(equation,[1,1], args=abc)
print(x,y)
# Geometric solution
a = abc[0]; b = abc[1]; c = abc[2]
xSol = (a**2+b**2-c**2)/(2*b)
if a**2-xSol**2<0:
print("No solution")
else:
ySol = np.sqrt(a**2-xSol**2)
print(xSol,ySol)
print(xSol,-ySol)

Simplify in sympy with custom symbols

Suppose that I have sympy variables x, y and z
I have the expression (x + y) (x + y) + x
Is it possible that I am able to define z as x + y so that I can "simplify" the expression above to z^2 + x?
That is, I want to use z wherever I can in the simplified expression.
Yes, use subs as in
>>> var('x:z')
(x, y, z)
>>> ((x + y)*(x + y) + x).subs(x+y,z)
x + z**2
The subs routine will sometimes try to be smart about substitutions, but works best when the substitution target is a symbol (and hence unambiguous). So if you want to try the replacement x+y->z in a more ambiguous expression, try replacing x->z-y, simplify, and then resubstitute z-y->x to restore anything that didn't change:
>>> ((x*x + 2 * x * y + y * y) + x).subs(x,z-y).expand().subs(z-y,x)
x + z**2

I got an empty list when solving two equation

I tried to solve two simple equations but I got nothing.
from sympy import *
x, y = symbols('x y')
eq1=Function('eq1')
eq2=Function('eq2')
eq1 = Eq(x + y , 1) # x + y = 1
eq2 = Eq(x + y ,3) # x + y = 3
ans = solve([eq1, eq2] , [x, y])
print(ans)
I got
[]
You set everything up ok. The empty list is the way that solve tells you that it could not find a solution for x and y that satisfied the equations. And, indeed, there are no values which, when added, will give two different results (as others have noted).

How to make user-input for Symbols case insensitive

I want to avoid caps lock errors in a scypy base script that I made.
The script calculate partial derivatives
from sympy import *
from sympy.parsing.sympy_parser import parse_expr
from sympy.parsing.sympy_parser import standard_transformations, \
x, y, z = symbols('x y z ', real=True)
transformations = (standard_transformations + (implicit_multiplication_application,)
self.eq1 = parse_expr(self.entry_5.get(), locals(), transformations=transformations)
self.dfx = diff(self.eq1, x)
self.dfy = diff(self.eq1, y)
self.dfz = diff(self.eq1, z)
It work fine for this example entry_5 is x ** 2 + y ** 2 + z ** 2
'Partial derivatives calculation:
Partial der by X: 2*x
Partial der by Y: 2*y
Partial der by Z: 2*z
but now, I'm trying to add capital X,Y,Z with the same code:
.
.
.
x, y, z, X, Y, Z = symbols('x y z X Y Z', real=True)
.
.
.
now, entry_5 is- X ** 2 + y ** 2 + z ** 2 (capital x)
and the output is:
'Partial derivatives calculation:
Partial der by X: 0
Partial der by Y: 2*y
Partial der by Z: 2*z
If you are wanting your input to be recast to lowercase so the derivatives that you hard coded always work you could either convert the input to lower case or, more safely, provide locals that remap the uppercase symbols of interest to lower case symbols. For clarity in the following I use S to sympify rather than the parser:
>>> S('x', {'x':'upper'}) # example showing you can replace 'x' with 'upper'
upper
>>> S('X', dict([(str(i), str(i).lower()) for i in symbols('X:Z')]))
x
In your code you will have to update your locals with the dict() that is being used in my example: loc = locals(); loc.update(dict([(str(i), str(i).lower()) for i in symbols('X:Z')])) and use loc instead of locals() in your code.

Categories