Roots of unity

Bob McElrath mcelrath at draal.physics.wisc.edu
Fri Jan 18 06:07:38 CET 2002


ginsh:
    > evalf((-1)^(1/3));
    0.5+0.86602540378443864673*I

While this answer is technically correct:
    exp(I*pi/3) = -1

It's not what I was expecting, and the cause of some headache today.  I was
trying to write a little routine like RootOf to solve a cubic polynomial, and
was getting three complex answers.  (at least one of them must be real if you
start with a real polynomial)

How should I go about enforcing that (-1)^(1/3) = -1?  I'm interested in
polynomials over the reals, so the complex solutions don't interest me.  This
behaviour of evalf is preventing me from extracting the real solution.

Here's my little function if anyone is interested:

// Find the roots of a polynomial.
// The polynomial can be at most 4th order.
lst RootOf(const ex& poly, const ex& x) {
    ex p = poly;
    ex D,Q,R,S,T;
    p.expand();
    ex a0 = poly.coeff(x,0);
    ex a1 = poly.coeff(x,1);
    ex a2 = poly.coeff(x,2);
    ex a3 = poly.coeff(x,3);
    ex a4 = poly.coeff(x,4);
    switch(p.degree(x)) {
        case 0:
            return lst();
        case 1:
            return lst(-a0/a1);
        case 2:
            return lst((-a1 + sqrt(a1*a1-4*a2*a0))/(2*a2), (-a1 - sqrt(a1*a1-4*a2*a0))/(2*a2));
        case 3:
            a0 /= a3;
            a1 /= a3;
            a2 /= a3;
            Q = (3*a1-a2*a2)/9;
            R = (9*a2*a1-27*a0-2*a2*a2*a2)/54;
            D = pow(Q,3) + pow(R,2);
            S = pow(R+sqrt(D),numeric(1,3));
            T = pow(R-sqrt(D),numeric(1,3));
            // These formulas come from: http://mathworld.wolfram.com/CubicEquation.html
            return lst(
                    -numeric(1,3)*a2+S+T,
                    -numeric(1,3)*a2-numeric(1,2)*(S+T)+numeric(1,2)*I*sqrt(ex(3))*(S-T),
                    -numeric(1,3)*a2-numeric(1,2)*(S+T)-numeric(1,2)*I*sqrt(ex(3))*(S-T)
            );
        //case 4:
            // http://mathworld.wolfram.com/QuarticEquation.html
            // It seems this is defined ambiguously. eq. 30 wants "a real root" but there
            // may be as many as 3!  Can there 12 roots!??!
        default:
            throw(std::domain_error("RootOf: Cannot take the root of a polynomial with degree > 4"));
    }
    return lst();
}

Cheers,
-- Bob

Bob McElrath (rsmcelrath at students.wisc.edu) 
Univ. of Wisconsin at Madison, Department of Physics
-------------- next part --------------
A non-text attachment was scrubbed...
Name: not available
Type: application/pgp-signature
Size: 240 bytes
Desc: not available
Url : http://www.cebix.net/pipermail/ginac-list/attachments/20020118/c958c446/attachment.pgp


More information about the GiNaC-list mailing list