Roots of unity
Hans Peter Würmli
wurmli at freesurf.ch
Sun Jan 20 08:40:12 CET 2002
Dear Bob
I have written a
lst RootOf(const lst & l) returning a list of the three zeros plus the lead coefficient
program for degree 3 polynomials, where the input list contains the polynomial and the indeterminate. In the sample output of the main program you will see the effect of precision with Digits=yyy that "zero" is represented by some long digit sequence times E-xxx that you felt some time ago was a bug of GiNaC, but isn't.
I don't know how one can force GiNaC to simplify expressions. Say, I used the programm to find symbolically the three roots x1, x2, x3 and reassembled the polynomonial by expanding leadcoefficient*(x-x1)*(x-x2)*(x-x3). To take an example:
p(x) = 1 + x + x^3
Reassembling p from the roots and expanding produces:
p(x) = 1/2+x+x^3+(-27/2+3/2*sqrt(93))^(-1)-1/18*sqrt(93)
which is correct, if one simplifies 1/2+(-27/2+3/2*sqrt(93))^(-1)-1/18*sqrt(93) to 1
Best regards
Hans Peter
//
// Roots of third degree polynomial
// (from Kochendörfer "Einführung in die Algebra"
//
#include <iostream>
#include <ginac/ginac.h>
using namespace GiNaC;
//
// lst contains the polynomial and the indeterminate
//
lst RootOf(const lst& l){
//
// some checks - throwing an error would be appropriate
//
if (l.nops()!=2) return lst();
ex poly=l.op(0);
//
// Cint cannot resolve the next line
//
if (!is_a<symbol>(l.op(1))) return lst();
//
// my Cint complains if I use the name "x" again, therefore "z"
//
ex z=l.op(1);
if (poly.degree(z)!=3) return lst();
ex a0=poly.coeff(z,0), a1=poly.coeff(z,1),
a2=poly.coeff(z,2),a3=poly.coeff(z,3);
symbol t("t");
//
// normalisation to get the form x^3+a1*x+a0
//
ex save=a2/(a3*3), lead=a3;
ex pol= (poly/a3).subs(z==t-a2/(a3*3)).expand();
//
// polynomial is now p(t)=t^3+p*t+q
//
ex q=pol.coeff(t,0), p=pol.coeff(t,1);
//
// rho^3=1, crho^3=1, the two non-trivial roots of x^3-1
//
ex rho=(-1+pow(3,numeric(1,2))*I) /2,
crho=(-1-pow(3,numeric(1,2))*I)/2;
if (p.is_zero())
return lst((-pow(q,1/numeric(3))-save).expand(),
(-rho*pow(q,1/numeric(3))-save).expand(),
(-crho*pow(q,1/numeric(3))-save).expand(),
lead);
//
// the discriminant
//
ex D= -numeric(4)*pow(p,3)-numeric(27)*pow(q,2);
// Lagrange resolvents
ex lrho=pow(-numeric(27,2)*q+numeric(3,2)*pow(-3*D,numeric(1,2)),1/numeric(3));
ex lcrho=-3*p/lrho;
ex th=numeric(1,3);
return lst(th*(lrho+lcrho)-save, th*(crho*lrho+rho*lcrho)-save, th*(rho*lrho+crho*lcrho)-save, lead);
}
//
//Some examples
//
symbol y("y"), x("x"), a0("a0"),a1("a1"),a2("a2"),a3("a3");
ex poly=1+x+pow(x,3);
ex poly1=a0+a1*x+a2*pow(x,2)+a3*pow(x,3);
ex poly2=27+pow(x,3);
lst l(poly,x), l2(poly2,x),l1(poly1,x);
void main(void){
cout << RootOf(l) << "\n\n\n";
cout << RootOf(l1) << "\n\n\n";
cout << RootOf(l2) << "\n\n\n";
ex test=RootOf(l2).op(3)*(x-RootOf(l2).op(0))*(x-RootOf(l2).op(1))*(x-RootOf(l2).op(2));
cout << l2.op(0) << " = " << test.expand() << "\n\n\n";
ex test1=RootOf(l).op(3)*(x-RootOf(l).op(0))*(x-RootOf(l).op(1))*(x-RootOf(l).op(2));
cout << l.op(0) << " = " << test1.expand() << "\n\n\n";
Digits=50;
cout << evalf(poly.subs(x==RootOf(l).op(0))) << "\n\n\n";
cout << evalf(poly.subs(x==RootOf(l).op(1))) << "\n\n\n";
cout << evalf(poly.subs(x==RootOf(l).op(2))) << "\n\n\n";
cout << evalf(poly2.subs(x==RootOf(l2).op(0))) << "\n\n\n";
cout << evalf(poly2.subs(x==RootOf(l2).op(1))) << "\n\n\n";
cout << evalf(poly2.subs(x==RootOf(l2).op(2))) << "\n\n\n";
cout << "This list should be empty = " << RootOf(lst(pow(x,3),x+y)) << "\n\n\n";
}
-------------- next part --------------
An embedded and charset-unspecified text was scrubbed...
Name: thirdroots.cpp
Url: http://www.cebix.net/pipermail/ginac-list/attachments/20020120/539e838d/thirdroots.cpp
More information about the GiNaC-list
mailing list