Cubic formula gives the wrong result (triple checked)
I'd like to solve $ax^3 + bx^2 + cx + d = 0$ using the cubic formula.
I coded three versions of this formula, described in three sources:
MathWorld, EqWorld,
and in the book, "The Unattainable Attempt to Avoid the Casus Irreducibilis for Cubic Equations".
While I get identical results across all versions, these results are incorrect.
For example, for $a=1$, $b=2$, $c=3$, $d=4$,
I find incorrect roots:
$x_1 = -0.1747 - 0.8521i$,
$x_2 = 0.4270 + 1.1995i$,
$x_3 = -2.2523 - 0.3474i$.
The correct roots are:
$x_1 = -1.6506$,
$x_2 = -0.1747 + 1.5469i$,
$x_3 = -0.1747 - 1.5469i$
In case you're interested, the actual code is below. Thank you for your help!
%% Wolfram version
Q = (3*c - b^2) / 9;
R = (9*b*c - 27*d - 2*b^3) / 54;
D = Q^3 + R^2;
S = (R + sqrt(D))^(1/3);
T = (R - sqrt(D))^(1/3);
x1 = - b/3 + (S + T);
x2 = - b/3 - (S + T) / 2 + sqrt(-3) * (S - T) / 2;
x3 = - b/3 - (S + T) / 2 - sqrt(-3) * (S - T) / 2;
%% Book version
omega1 = - 1/2 + sqrt(-3)/2;
omega2 = - 1/2 - sqrt(-3)/2;
p = (3*a*c - b^2) / (3*a^2);
q = (2*b^3 - 9*a*b*c + 27*(a^3)*d) / (27*a^3);
r = sqrt(q^2/4 + p^3/27);
s = (-q/2 + r)^(1/3);
t = (-q/2 - r)^(1/3);
x1 = s + t - b/(3*a);
x2 = omega1*s + omega2*t - b/(3*a);
x3 = omega2*s + omega1*t - b/(3*a);
%% Eqworld version
p = - 1/3 * (b/a)^2 + (c/a);
q = 2/27 * (b/a)^3 - (b*c)/(3*a^2) + d/a;
D = (p/3)^3 + (q/2)^2;
A = (-q/2 + sqrt(D))^(1/3);
B = (-q/2 - sqrt(D))^(1/3);
y1 = A + B;
y2 = - 1/2 * (A + B) + sqrt(-3)/2 * (A - B);
y3 = - 1/2 * (A + B) - sqrt(-3)/2 * (A - B);
x1 = y1 - b / (3*a);
x2 = y2 - b / (3*a);
x3 = y3 - b / (3*a);
Solution 1:
The problem occurs when you are taking a cube root: in the Wolfram version, when you compute $$T = \sqrt[3]{R - \sqrt{D}} = \sqrt[3]{-\frac{35}{27}-\sqrt{\frac{50}{27}}}$$ and in corresponding places in the other versions of the cubic formula.
The expression inside the cube root is negative (approximately $-2.66$), and the cubic formula works if you take the real cube root (approximately $-1.39$). But writing $(R - \sqrt D)^{1/3}$ in many computer algebra systems instead computes the principal cube root: the complex root with largest real part. This will be the real cube root for a positive number, but here, it gives us approximately $0.69 - 1.2 i$, and that is the source of your error.
I can't identify the language you're using by looking at it, so I don't know what the best way to avoid this problem is. In Mathematica, there's a built-in CubeRoot
command, which will always take the real root of a real number.
You can always make it go with some conditionals: define $T$ to be
- $(R - \sqrt{D})^{1/3}$, if $R - \sqrt D \ge 0$, and
- $-(\sqrt D - R)^{1/3}$, if $R - \sqrt D < 0$.
(And do a similar thing everywhere else you take a cube root.)
The above will work for real coefficients; for complex coefficients (or even when $D$ is negative), we want to be more careful, because then a real root might not exist.
The idea is that we ran into trouble here, not because we weren't taking the real root necessarily, but because we took two cube roots that "didn't match up with each other". We can rewrite the cubic formula in a few different ways so that we only take one cube root, and express the other cube root we'd have to take in terms of the first. Then the issue doesn't occur.
This gives us a better way to solve the problem in code: after computing $S = (R + \sqrt D)^{1/3}$, set $T = -Q/S$. The justification is this: since $S^3 = R + \sqrt D$ and $T^3 = R - \sqrt D$, we have $S^3 T^3 = R^2 - D = -Q^3$. Naively, we can cancel the cube roots and assume $ST = -Q$, and this works out.
See also this question and its answer.