I'm trying to find the roots with the root function in Scipy for functions/variables created in Sympy.
sympy:
AllEquations = [x1 - 5, y1 - 5, z1 - 5, ((x1 - x2)**2 + (y1 - y2)**2 + (z1 - z2)**2)**0.5 - 150, y2 - 100, z2, ((x1 - x2)**2 + (y1 - y2)**2 + (z1 - z2)**2)**0.5 - 150]
AllVariables = [x1, y1, z1, x2, y2, z2]
Below works in Scipy, but is done manually:
def equation(p):
x1, y1, z1, x2, y2, z2 = p
return x1 - 5, y1 - 5, z1 - 5, ((x1 - x2)**2 + (y1 - y2)**2 + (z1 - z2)**2)**0.5 - 150, y2 - 100, z2, ((x1 - x2)**2 + (y1 - y2)**2 + (z1 - z2)**2)**0.5 - 150
initial_guess = [5,5,5,100,100,0]
from scipy.optimize import root
sol = root(equation, initial_guess, method = 'lm")
>>>sol.x
array([ 5.00000000e+00, 5.00000000e+00, 5.00000000e+00, 1.20974135e+02,
1.00000000e+02, -2.00332805e-25])
Question is now, how can I automate this? The equation function above is static and should be made dynamically as the number of parameters and functions will change continuously.
This can be done using sympy's lambdify
function to turn the equation into a Python function that can be evaluated numerically.
import sympy as smp
from scipy.optimize import root
x1, x2, y1, y2, z1, z2 = smp.symbols("x1 x2 y1 y2 z1 z2")
variables = [x1, x2, y1, y2, z1, z2]
equations = [x1 - 5,
y1 - 5,
z1 - 5,
((x1 - x2)**2 + (y1 - y2)**2 + (z1 - z2)**2)**0.5 - 150,
y2 - 100,
z2,
]
# this list will contain all the functions you want to find the roots of
equations_lamb = [smp.lambdify(variables, eq) for eq in equations]
def combined_function(x, function_list):
# evaluates the provided list of functions
res = []
for function in function_list:
res.append(function(*x))
return res
initial_guess = [0]*len(variables)
sol = root(combined_function, initial_guess, args=(equations_lamb,))
print(sol)