Search code examples
pythonscipyequation-solving

scipy.optimize.root returning incorrect solution


I am trying to solve a system of simultaneous equations as follows:

"145.0x/21025 = -0.334" 
"(-48.402x-96.650y+96.650z)/21025 = -0.334" 
"(-48.402x+132.070y+35.214z)/21025 = -0.334" 
"sqrt(x^2+y^2+z^2) = 145.0"

I am using the following Python script:

from scipy.optimize import root
from numpy import sqrt
from sys import argv, stdout

initGuesses = eval(argv[1])
equations = argv[2:]

def f(variables):
    x,y,z = variables
    results = []
    for eqn in equations:
        results.append(eval(eqn))
    return results

solution = root(f, initGuesses, method="lm")
stdout.write(str(solution["x"][0]) + "," + str(solution["x"][1]) + "," + str(solution["x"][2]))
stdout.flush()

The program is called as follows:

python3 SolvePosition3D.py "(1,1,1)" "(145.0*x+0.0*y+0.0*z)/21025.0+0.334" "(-48.402*x-96.650*y+96.650*z)/21025+0.334" "(-48.402*x+132.070*y+35.214*z)/21025+0.334" "sqrt(x**2+y**2+z**2)-145.0"

And I am receiving the following output:

48.2699997956,35.4758788666,132.042180583

This solution is wrong; the correct solution is roughly

-48,-35,-132

which is the same numbers but * -1.

The answer returned by the program satisfies the final equation, but violates all others.

Does anyone know why this is happening? Getting the correct solutions to these equations (and many others like them) is vitally important to my current project.


Solution

  • I was able to run the code via adding

    from numpy import sqrt
    from scipy.optimize import root
    

    and switching to regular old prints for the solution.

    Your starting guess seems to be wrong. Starting from (1, 1, 1), the root finder converges to 48.2699997956,35.4758788666,132.042180583, as you said. If you plug in (-1,-1,-1), you get -48.2649482763,-35.4698607274,-132.050694891 as expected.

    As for why it does that, well, nonlinear systems are just hard to solve like that. Most algorithms tend to find solutions deterministically based on the starting point. If you need to try multiple starting points, try a grid-based search.