Reputation: 143
I have three different 3D equations and i want to get the intersection between them (the solution of the system). My variables are x,y,z
Equations:
-0.006683 x**2 - 0.06893 x + 56.73- z = 0
0.002538 y**2 - 1.115 y + 56.73 - z = 0
(x-24.680)**2+(y-238.341)**2+(z+13.971)**2 = 12.580**2
How can i solve this nonlinear system in python?
Upvotes: 2
Views: 552
Reputation: 821
If you re-write the functions:
-0.006683 x**2 - 0.06893 x + 56.73- z = 0
0.002538 y**2 - 1.115 y + 56.73 - z = 0
(x-24.680)**2+(y-238.341)**2+(z+13.971)**2 - 12.580**2 = 0
this helps a bit.
You've got three equations, and three unknowns.
The brute force method is to loop through x, y, and z values (over some domain of x, y, and z), and see how close all equations get to zero.
fa = -0.006683 x**2 - 0.06893 x + 56.73- z
fb = 0.002538 y**2 - 1.115 y + 56.73 - z
fc = (x-24.680)**2+(y-238.341)**2+(z+13.971)**2 - 12.580**2
Use a 'cost function', like cost=fa * fa + fb * fb + fc * fc , and look for the minimum.
There are other methods, like the Nelder-Mead method, which can be used, and are more efficient. https://en.wikipedia.org/wiki/Nelder%E2%80%93Mead_method
Once you find a minimum, you can take your original search range, and make it finer, depending on what sort of accuracy you need.
@warped gives a nicer, more Pythonic solution, however, there is always the possibility there is no solution, or multiple solutions. BTW, is this a geometry problem? The last equation looks like the equation of a sphere.
from scipy.optimize import fsolve
import math
def equations(p):
x, y, z = p
return (-0.006683 * x*x - 0.06893 * x + 56.73- z, \
0.002538 * y*y - 1.115 * y + 56.73 - z, \
(x-24.680)**2+(y-238.341)**2+(z+13.971)**2-12.580**2)
x, y, z = fsolve(equations, (1,1,1))
print (equations((x,y,z)))
print(x,y,z)
Using the method noted in this question using SymPy (answered in nice detail by @Oscar Benjamin), How to solve a pair of nonlinear equations using Python?
you can find other solutions in another way. However, this method didn't find any solutions, at least with my first stab at it.
from sympy import *
x, y, z = symbols('x, y, z')
eq1 = Eq(-0.006683 * x * x - 0.06893 * x + 56.73- z, 0)
eq2 = Eq(0.002538 * y * y - 1.115 * y + 56.73 - z, 0)
eq3 = Eq((x-24.680)**2+(y-238.341)**2+(z+13.971)**2-12.580**2, 0)
sol = solve([eq1, eq2, eq3], [x, y,z])
print(sol)
print("")
if(len(sol)>1):
soln = [tuple(v.evalf() for v in s) for s in sol]
for idx, each in enumerate(soln):
print(idx,each)
Upvotes: 1