python 不使用 sympy 求解三次方程
python solve Cubic equation without using sympy
是否可以不使用 sympy 求解三次方程?
示例:
import sympy as sp
xp = 30
num = xp + 4.44
sp.var('x, a, b, c, d')
Sol3 = sp.solve(0.0509 * x ** 3 + 0.0192 * x ** 2 + 3.68 * x - num, x)
结果是:
[6.07118098358257, -3.2241955998463 - 10.0524891203436*I, -3.2241955998463 + 10.0524891203436*I]
但我想找到一种方法来使用 numpy 或完全不使用 3 部分库
我用 numpy 试过:
import numpy as np
coeff = [0.0509, 0.0192, 3.68, --4.44]
print(np.roots(coeff))
但结果是:
[ 0.40668245+8.54994773j 0.40668245-8.54994773j -1.19057511+0.j]
您可以实施 cubic formula
这个来自 mathologer 的 Youtube 视频可以帮助理解它。
基于此,ax^3 + bx^2 + cx + d = 0 的三次函数可以这样写:
def cubic(a,b,c,d):
n = -b**3/27/a**3 + b*c/6/a**2 - d/2/a
s = (n**2 + (c/3/a - b**2/9/a**2)**3)**0.5
r0 = (n-s)**(1/3)+(n+s)**(1/3) - b/3/a
r1 = (n+s)**(1/3)+(n+s)**(1/3) - b/3/a
r2 = (n-s)**(1/3)+(n-s)**(1/3) - b/3/a
return (r0,r1,r2)
公式的简化版只需要获取c和d作为参数(又名p和q),可以这样实现:
def cubic(p,q):
n = -q/2
s = (q*q/4+p**3/27)**0.5
r0 = (n-s)**(1/3)+(n+s)**(1/3)
r1 = (n+s)**(1/3)+(n+s)**(1/3)
r2 = (n-s)**(1/3)+(n-s)**(1/3)
return (r0,r1,r2)
print(cubic(-15,-126))
(5.999999999999999, 9.999999999999998, 2.0)
我会让你混合复数运算以正确获得所有 3 个根
在您的 numpy 方法中,您在最终系数上犯了两个小错误。
在 SymPy
示例中,您的最后一个系数是 - num
,根据您的代码,这是:-num = - (xp + 4.44) = -(30 + 4.44) = -34.44
在您的 NumPy
示例中,您最后一个系数是 --4.44
,它是 4.44
,不等于 -34.33
。
如果您编辑 NumPy
代码,您将得到:
import numpy as np
coeff = [0.0509, 0.0192, 3.68, -34.44]
print(np.roots(coeff))
[-3.2241956 +10.05248912j -3.2241956 -10.05248912j
6.07118098 +0.j ]
答案是一样的(注意NumPy
用j
表示复数。SymPy
用I
)
是否可以不使用 sympy 求解三次方程?
示例:
import sympy as sp
xp = 30
num = xp + 4.44
sp.var('x, a, b, c, d')
Sol3 = sp.solve(0.0509 * x ** 3 + 0.0192 * x ** 2 + 3.68 * x - num, x)
结果是:
[6.07118098358257, -3.2241955998463 - 10.0524891203436*I, -3.2241955998463 + 10.0524891203436*I]
但我想找到一种方法来使用 numpy 或完全不使用 3 部分库
我用 numpy 试过:
import numpy as np
coeff = [0.0509, 0.0192, 3.68, --4.44]
print(np.roots(coeff))
但结果是:
[ 0.40668245+8.54994773j 0.40668245-8.54994773j -1.19057511+0.j]
您可以实施 cubic formula
这个来自 mathologer 的 Youtube 视频可以帮助理解它。
基于此,ax^3 + bx^2 + cx + d = 0 的三次函数可以这样写:
def cubic(a,b,c,d):
n = -b**3/27/a**3 + b*c/6/a**2 - d/2/a
s = (n**2 + (c/3/a - b**2/9/a**2)**3)**0.5
r0 = (n-s)**(1/3)+(n+s)**(1/3) - b/3/a
r1 = (n+s)**(1/3)+(n+s)**(1/3) - b/3/a
r2 = (n-s)**(1/3)+(n-s)**(1/3) - b/3/a
return (r0,r1,r2)
公式的简化版只需要获取c和d作为参数(又名p和q),可以这样实现:
def cubic(p,q):
n = -q/2
s = (q*q/4+p**3/27)**0.5
r0 = (n-s)**(1/3)+(n+s)**(1/3)
r1 = (n+s)**(1/3)+(n+s)**(1/3)
r2 = (n-s)**(1/3)+(n-s)**(1/3)
return (r0,r1,r2)
print(cubic(-15,-126))
(5.999999999999999, 9.999999999999998, 2.0)
我会让你混合复数运算以正确获得所有 3 个根
在您的 numpy 方法中,您在最终系数上犯了两个小错误。
在 SymPy
示例中,您的最后一个系数是 - num
,根据您的代码,这是:-num = - (xp + 4.44) = -(30 + 4.44) = -34.44
在您的 NumPy
示例中,您最后一个系数是 --4.44
,它是 4.44
,不等于 -34.33
。
如果您编辑 NumPy
代码,您将得到:
import numpy as np
coeff = [0.0509, 0.0192, 3.68, -34.44]
print(np.roots(coeff))
[-3.2241956 +10.05248912j -3.2241956 -10.05248912j
6.07118098 +0.j ]
答案是一样的(注意NumPy
用j
表示复数。SymPy
用I
)