Search code examples
pythonsympynonlinear-functions

Can't get real solution with sympy.solve


I tried sympy.solve to solve an nonlinear equation system. It gave me a complex solution set. Then I tried this equation system in matlab, and got a real solution set which I think is correct, because this is actually a geometry problem and I tested this solution in CAD software.

So...why sympy.solve gave me a complex solution set? where on earth did I make a mistake... or mistakes?

here is the code i wrote:

import sympy
x1=0
y1=-620
r1=920
zqua=126
yqua=276
x3=51
rm=205
r3=104

x0 = sympy.Symbol('x0')
y0 = sympy.Symbol('y0')
r0 = sympy.Symbol('r0')

f1=r0+((x0-x1)**2+(y0-y1)**2)**0.5-r1
f2=(zqua-x0)**2+(yqua-y0)**2-r0**2
f3=r0+((x0-x3)**2+(y0-rm)**2)**0.5-r3

A=sympy.solve((f1,f2,f3), (x0, y0, r0))
print A

and here is the solution it gave:

[(132.229058631742 - 3.4301208813066*I, 282.298802365236 + 1.7767794177989*I, -8.07109966646592 + 1.26065122532955*I), (132.229058631742 + 3.4301208813066*I, 282.298802365236 - 1.7767794177989*I, -8.07109966646592 - 1.26065122532955*I)]

Solution

  • Although you had the right sign of the difference of r in f1 and f3, if you write in terms of squares (where the sign no longer matters) as is already done in f2 you obtain 2 real answers:

    >>> f1=(x0-x1)**2+(y0-y1)**2-(r0 - r1)**2
    >>> f2=(zqua-x0)**2+(yqua-y0)**2-r0**2
    >>> f3=(x0-x3)**2+(y0-rm)**2-(r3 - r0)**2
    >>>
    >>> A=sympy.solve((f1,f2,f3), (x0, y0, r0))
    >>> [[i.n(2) for i in w] for w in A]
    [[73., 2.2e+2, 79.], [88., 2.5e+2, 48.]]
    >>>
    

    SymPy should have found the roots with the other representation, it seems, but it selected -79 and -48 instead, and those results did not satisfy the original equations and were thus excluded from the reported solution.