ButterDog
ButterDog

Reputation: 5225

Python's sympy solver returning bad roots on 4th degree equation

I need to solve a 4th degree equation with python. For this I'm using the sympy module.

When I run the script, sympy returns the 4 solutions of the equation as complex numbers (see output), while, in fact, all of them are real.

What is making sympy return the wrong answer?

import numpy as np
import math
from numpy import linalg as la
import sympy as sy

from matplotlib.pyplot import *

L = np.array([0,1,-20.0])
S = np.array([0,0,-10.0])

a = np.dot(S,S)
b = np.dot(S,L)
c = np.dot(L,L)

k0 = a - 1
k1 = 2*(a-b)
k2 = a + 2*b + c - 4*a*c
k3 = -4*(a*c - b**2)
k4 = 4*c*(a*c - b**2)

y = sy.Symbol('y')
r = sy.solvers.solve(k4*y**4 + k3*y**3 + k2*y**2 + k1*y + k0, y)

print r

y = np.linspace(-1.1, 1.1, 1000)
x = k4*y**4 + k3*y**3 + k2*y**2 + k1*y + k0
figure()
plot(y, x)
grid(True)
show()

Output:

[-0.994999960838935 + 1.66799419488535e-31*I,
 -0.0255580200028216 - 6.34301512012529e-30*I, 
  0.0243009597954184 + 6.32628752256216e-30*I,
  0.998750786632373 - 1.50071821925406e-31*I]

Plot (there are 4 zero-crossings):

enter image description here

Upvotes: 2

Views: 2832

Answers (2)

smichr
smichr

Reputation: 19029

Real values can also be obtained directly from nroots:

>>> eq=k4*y**4 + k3*y**3 + k2*y**2 + k1*y + k0
>>> eq
160400.0*y**4 - 400.0*y**3 - 159499.0*y**2 - 200.0*y + 99.0
>>> nroots(eq)
[-0.994999960838935, -0.0255580200028216, 0.0243009597954184, 0.998750786632373]

Upvotes: 0

gg349
gg349

Reputation: 22671

Notice that the result is actually real, up to numerical precision. e-30 is really a small number. The solutions reported are also consistent with the plot, so nothing to worry about.

Upvotes: 3

Related Questions