Solving Cyclotomic Polynomials by Radical Expressions
Andreas Weber, Michael Keckeisen, Essam Abdel-Rahman
E-mail: weber@cs.uni-bonn.de
Introduction
Niels Henrik Abel and Evariste Galois showed that polynomial equations of degree higher than four cannot be solved by radical expressions in general. As Galois stated in his work, radical solutions exist if and only if the Galois group of the polynomial is solvable.
Since the the Galois group of a cyclotomic polynomial is Abelian, its Galois group is solvable, and so its solutions can be expressed by radical expressions.
Example: the 5th cyclotomic polynomial and it's solutions:
| > | cycl:=numtheory[cyclotomic](5,x); |
| > | s:=solve(cycl): |
| > | for i from 1 to 4 do t[i]:=[Re(s[i]),Im(s[i])]; u[i]:=[Re(s[i]),Im(s[i]), ZETA^i] od: |
| > | p1:=plot([[1,0],t[1],t[2],t[3],t[4],[1,0]],style=line,title=`The 4 Solutions of the 5th cyclotomic polynomial:`): |
| > | p2:=plots[implicitplot](x^2+y^2=1,x=-1..1,y=-1..1,scaling=constrained): |
| > | p3:=plots[textplot]([[1,0,``],u[1],u[2],u[3],u[4],[1,0,``]]): |
| > | plots[display]([p1,p2,p3]); |
![]() |
In the last years algorithmic methods to compute solutions by radicals for the cases in which the Galois group of the polynomial is solvable have obtained renewed attention [HM01]. However, for the special case of cyclotomic polynomials a very good algorithm was already published in the year 1801, when the masterwork Disquisitiones Arithmeticae ([Gau86]) of Carl Friedrich Gauss appeared. In this book Gauss described an algorithm to compute radical expressions for primitive roots of unity. This work in some sense is a generalization of the famous result of Gauss already obtained in 1797 showing that the regular 17gon can be constructed by compass and ruler.
We implemented this algorithm of Gauss for computing radical expressions for roots of unity in MAPLE with an improved time complexity compared to Gauss' original proposition [Web96]. The command radsolve serves as an extension to the solve command, that returns radical solutions for all cyclotomic factors of a polynomial with integer coefficients and calls solve for the others.
The hard part of the proof and of the algorithm is to compute a radical expression for a primitive
-th root of unity, where
is a prime number. The improvement in our algorithm reduces the asymptotic time complexity in this case from
Ο((
to
Ο(
,
where is the largest prime factor of -1. An analysis of the algorithm and the statement and proof of the proposition on which the improvement is based can be found in [Web96]. We also refer to this paper for a description of the underlying ideas of Gauss' algorithm and the statement of the theorems that yield its correctness.
For an overview see The Algorithm.
Compared to the MAPLE-code given in [Web96], we managed to improve the practical speed of the algorithm to a great extend, reducing the needed amount of memory at the same time. For instance, the computations of radical expressions for the 47th, 59th, or 83rd root of unity failed with the previous implementation, but can now be accomplished within a few hours.
The Algorithm
Radical solutions for cyclotomic polynomials
The n-th cyclotomic Polynomial over the rational numbers is of the form
(x) =
and its degree is
φ(n) =
where n =
and φ is the Eulerian φ -Function, as can be seen in [Nar90, p. 13 and 169]. From the difining formula of φ it can be seen that the inverse image
of φ is finite. Thus, to determine whether or not an irreducible factor of a polynomial is cyclotomic, it suffices to compare the j-th cyclotomic polynomial with q for all j in
. MAPLE provides the function numtheory[invphi] to calculate
; the computational costs of this functions is neglegible for the range of arguments which are feasible for computing radical expressions.
Given the n-th cyclotomic polynomial
(x) , the task of computing φ(n) radical solutions can be reduced to finding a radical expression for one root of unity, because this root will be primitive, e.g. a multiplicative generator for the others. Further, it suffices to find a primitive n-th root of unity to compute primitive roots of unity for all prime factors of n by applying some relatively simple recursion formulas, see e.g. [Gaa88].
Radical expressions for primitive r-th roots of unity
The hard part of the algorithm is to find a radical expression for a primitive
-th root of unity, where
is a prime number. This part involves the computation of Gaussian periods, cf. [Gau86, Sec.343]. If
denotes a primitive -th root of unity the period (f , k) for two integers f and k is defined by
(f , k) =
where e =
and ℊ is a primitive -th root. In Maple a primitive -th root can be computed by the function primroot in the package numtheory. The Gaussian periods are generators of intermediate fields of the number field Q(
), which is a number field of degree -1 over the rationals. Using the modern terminlogy of intermediate fields the algorithm of Gauss works roughly as follows. Starting with the rationals, compute a radical expression for a generator of an intermediate field of prime degree, i.e. an appropriate Gaussian period. After this task has been accomplished compute a radical expressions for a generator of another intermediate field (i.e. another Gaussian period) whose relative degree over the other intermediate field is of prime order. Continue this task until a radical expression for a generator of Q(
), i.e.
has been computed.
The difficult part of Gauss algorithm is the lifting of radical expressions from one intermediate field to another one. We will not give the details of this lifting here but we refer to [Web96].
How to use radsolve
The library is included in the file radsolvelib.mpl.
All functionality is available via the function radsolve.
The command radsolve serves as an extension to the Maple solve command. It returns radical solutions for all cyclotomic factors of a polynomial with integer coefficients and calls solve for the others.
radsolve(poly) is based on an algorithm given by Carl Friedrich Gauss in his Disquisitiones Arithmeticae, 1797, with an improved time complexity, as described in Weber, A.: Computing radical expressions for roots of unity, SIGSAM Bulletin 30, 117 (Sept. 1996), p.11-20.
The Maple solve command does not express the solutions of a cyclotomic factor of a polynomial of degree higher than 4 in radicals, but uses sin and cos functions instead.
| > | solve(x^17-1); |
| (3.2.1) |
In the following, we set AllSolutions to false. Thus we get only one solution for any irreducible factor of the polynomial.
| > | restart: |
| > | libdir:=currentdir():; |
| > | fname1 := cat(libdir, "\\radsolvelib.mpl"):; |
| > | read(fname1):; |
| > | _AllSolutions:=false: |
| > | r17:=radsolve(x^17-1); |
| (3.2.2) |
| > |
| (3.2.3) |
| > | solve(16*x^3-16*x^6-14*x^2+2*x^9-12*x^8+13*x^7-3+4*x+16*x^5-16*x^4); |
| (3.2.4) |
| > |
![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() |
(3.2.5) |
| > |
| (3.2.6) |
| > | _AllSolutions:=false: |
| > | _UseRootsymbols:=true: |
| > | infolevel[radsolve]:=3: |
| > | radsolve(16*x^3-16*x^6-14*x^2+2*x^9-12*x^8+13*x^7-3+4*x+16*x^5-16*x^4); |
| radsolve: The global variables are set to:
radsolve: _AllSolutions= false radsolve: _SwapPrimeOrder= false radsolve: _UseRootsymbols= true radsolve: _EnvExplicit= false radsolve: Degree less than 5 -> use solve radsolve: invphi(degree)= [7 9 14 18] radsolve: No, not equal. radsolve: No, not equal. radsolve: Yes, it's equal. radsolve: Itīs the 14 -th cyclotomic polynomial! radsolve: Calculating the solution(s)... radical_prime_primroot: Entering. Calculating a radical expression for a primitive 7 -th root of unity... expressions_for_periods: Entering with prime factors of 6 : 3 2 expressions_for_periods: Entering with prime factors of 6 : 1 3 expressions_for_periods: Leaving. Generator for intermediate field of degree 3 computed. expressions_for_periods: used time 0.15e-1 expressions_for_periods: Leaving. Generator for intermediate field of degree 6 computed. expressions_for_periods: used time 0.31e-1 radical_prime_primroot: Entering. Calculating a radical expression for a primitive 3 -th root of unity... expressions_for_periods: Entering with prime factors of 2 : 1 2 expressions_for_periods: Leaving. Generator for intermediate field of degree 2 computed. expressions_for_periods: used time 0. radical_prime_primroot: Calculated a radical expression for a primitive 3 -th root of unity. Leaving. radical_prime_primroot: Calculated a radical expression for a primitive 7 -th root of unity. Leaving. radical_primroot: Leaving. radsolve: Used Time= 0.47e-1 |
|
| (3.2.7) |
To verify the results, use radnormal . You might have to use numeric evaluation for large results:
| > | _UseRootsymbols:=true: |
| > | z:=radsolve(numtheory[cyclotomic](41,x)): |
| > | Digits:=32: |
| > | numeval:=codegen[makeproc](map(evalf,[codegen[optimize](z)])): |
| > | fnormal(numeval()^41-1,30); |