2

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?

Diogo Mata
  • 143
  • 1
  • 2
  • 7

1 Answers1

1

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)
asylumax
  • 781
  • 1
  • 8
  • 34
  • Yeah it is a geometry problem! The last equation is a sphere equation as you pointed out. I'll try the different things you suggested. Thanks ! – Diogo Mata May 30 '20 at 14:05
  • Note that the initial conditions for the search in what was posted was (1,1,1); you may get different answers with different initial search parameters (like (100,100,100)). Check the reference: https://docs.scipy.org/doc/scipy/reference/generated/scipy.optimize.fsolve.html#scipy.optimize.fsolve ! – asylumax May 30 '20 at 14:09
  • 1
    Is there any way/method that ables me to get all of the solutions of the system ? – Diogo Mata May 30 '20 at 14:53
  • 1
    Ah, that's another problem. One way to try and solve this is to use different starting points for the initial conditions. Since you are working in the x-y-z coordinate system, you could try 8 extremes (the points of a cube, say, (1000,1000,1000), (1000,1000,-1000), etc. as well as (0,0,0). This won't tell you everything, but it might be a start. For example, the intersection of a 2D circle with a 2D parabola might get you 0,1,2,3, or 4 solutions. Much of this depends on the problem details. – asylumax May 30 '20 at 15:36
  • Note the answer in https://stackoverflow.com/questions/8739227/how-to-solve-a-pair-of-nonlinear-equations-using-python?noredirect=1&lq=1; SymPy can deliver more than one solution. – asylumax May 30 '20 at 16:15
  • Got it ! It helped a lot ! Thank You ! – Diogo Mata Jun 01 '20 at 10:01