作为我正在编写的程序的一部分,我需要精确地求解三次方程(而不是使用数值求根器):
a*x**3 + b*x**2 + c*x + d = 0.
我正在尝试使用 此处。但是,请考虑以下代码(这是 Python,但它是非常通用的代码):
a = 1.0
b = 0.0
c = 0.2 - 1.0
d = -0.7 * 0.2
q = (3*a*c - b**2) / (9 * a**2)
r = (9*a*b*c - 27*a**2*d - 2*b**3) / (54*a**3)
print "q = ",q
print "r = ",r
delta = q**3 + r**2
print "delta = ",delta
# here delta is less than zero so we use the second set of equations from the article:
rho = (-q**3)**0.5
# For x1 the imaginary part is unimportant since it cancels out
s_real = rho**(1./3.)
t_real = rho**(1./3.)
print "s [real] = ",s_real
print "t [real] = ",t_real
x1 = s_real + t_real - b / (3. * a)
print "x1 = ", x1
print "should be zero: ",a*x1**3+b*x1**2+c*x1+d
但输出是:
q = -0.266666666667
r = 0.07
delta = -0.014062962963
s [real] = 0.516397779494
t [real] = 0.516397779494
x1 = 1.03279555899
should be zero: 0.135412149064
因此输出不为零,因此 x1 实际上不是解决方案。维基百科的文章有错误吗?
ps:我知道 numpy.roots 会解这种方程,但我需要对数百万个方程执行此操作,因此我需要实现它来处理系数数组。
As part of a program I'm writing, I need to solve a cubic equation exactly (rather than using a numerical root finder):
a*x**3 + b*x**2 + c*x + d = 0.
I'm trying to use the equations from here. However, consider the following code (this is Python but it's pretty generic code):
a = 1.0
b = 0.0
c = 0.2 - 1.0
d = -0.7 * 0.2
q = (3*a*c - b**2) / (9 * a**2)
r = (9*a*b*c - 27*a**2*d - 2*b**3) / (54*a**3)
print "q = ",q
print "r = ",r
delta = q**3 + r**2
print "delta = ",delta
# here delta is less than zero so we use the second set of equations from the article:
rho = (-q**3)**0.5
# For x1 the imaginary part is unimportant since it cancels out
s_real = rho**(1./3.)
t_real = rho**(1./3.)
print "s [real] = ",s_real
print "t [real] = ",t_real
x1 = s_real + t_real - b / (3. * a)
print "x1 = ", x1
print "should be zero: ",a*x1**3+b*x1**2+c*x1+d
But the output is:
q = -0.266666666667
r = 0.07
delta = -0.014062962963
s [real] = 0.516397779494
t [real] = 0.516397779494
x1 = 1.03279555899
should be zero: 0.135412149064
so the output is not zero, and so x1 isn't actually a solution. Is there a mistake in the Wikipedia article?
ps: I know that numpy.roots will solve this kind of equation but I need to do this for millions of equations and so I need to implement this to work on arrays of coefficients.
发布评论
评论(5)
维基百科的符号
(rho^(1/3), theta/3)
并不意味着rho^(1/3)
是实部而theta/ 3
是虚部。相反,这是在极坐标中。因此,如果您想要实部,您可以采用rho^(1/3) * cos(theta/3)
。我对您的代码进行了这些更改,它对我有用:(
当然,这里
s_real = t_real
因为cos
是偶数。)Wikipedia's notation
(rho^(1/3), theta/3)
does not mean thatrho^(1/3)
is the real part andtheta/3
is the imaginary part. Rather, this is in polar coordinates. Thus, if you want the real part, you would takerho^(1/3) * cos(theta/3)
.I made these changes to your code and it worked for me:
(Of course,
s_real = t_real
here becausecos
is even.)这是 A. Rex 在 JavaScript 中的解决方案:
Here's A. Rex's solution in JavaScript:
在这里,我放置了一个三次方程(具有复系数)求解器。
Here, I put a cubic equation (with complex coefficients) solver.
如果有人需要 C++ 代码,您可以使用这段 OpenCV:
https://github.com/opencv/opencv/blob/master/modules/calib3d/src/polynom_solver.cpp
In case someone needs C++ code, you can use this piece of OpenCV:
https://github.com/opencv/opencv/blob/master/modules/calib3d/src/polynom_solver.cpp