Python 的 sympy 求解器在 4 次方程上返回坏根

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

我需要用 python 求解四次方程。为此,我使用 sympy 模块。

当我 运行 脚本时,sympy return 将方程的 4 个解作为复数(见输出),而实际上,都是真实的。

为什么 sympy return 的答案是错误的?

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()

输出:

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

剧情(有4个zero-crossings):

请注意,结果实际上是真实的,达到数值精度。 e-30真是个小数目。解说也和剧情一致,不用担心

也可以直接从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]