I wrote in my previous post that Cantor and Zassenhaus' algorithm of polynomial factorisation over finite fields can be divided into three stages:
According to Modern Computer Algebra, "the second stage consumes the bulk of the computing time". In 1998 Erich Kaltofen and Victor Shoup designed a new approach to distinct-degree factorisation which allows to decrease it's cost. This strategy is called "baby/giant step" and exploits the fact from number theory:
- squarefree factorisation
- distinct-degree factorisation
- equal-degree factorisation
(in the standard Cantor-Zassenhaus algorithm the squarefree factorisation step is merged with the algorithm itself)
Lemma. For nonnegative integers i and j, the polynomial xqi−xqj∈Fq[x] is divisible by precisely those irreducible polynomials in Fq[x] whose degree divides i−j.
The proof is easy: if i≥j then xqi−xqj=(xqi−j−x)qj. From the Theorem from the previous post we know that the factorisation of xqk−x consists of all irreducible factors whose degree is a divisor of k.
Now it's possible to formulate the algorithm:
Fast distinct-degree factorisation (DDF)
Input and output
This algorithm takes as input a square-free polynomial f∈Fq[x] of degree n.
The output is f[1],...,f[n]∈Fq[x] such that for 1≤d≤n, f[d] is the product of the monic irreducible factors of f of degree d. The algorithm is parameterized by a constant β, with 0≤β≤1.
Step 1 (compute baby steps)
Let l=⌈nβ⌉ . For 0≤i≤l, compute hi=xqimodf.
Step 2 (compute giant steps)
Step 2 (compute giant steps)
Let m=⌈n2l⌉ . For 1≤j≤m, compute Hj=xqljmodf.
Step 3 (compute interval polynomials)
For 1≤j≤m, compute Ij=∏0≤i≤l(Hj−hi)modf .
(by Lemma the polynomial Ij is divisible by those irreducible factors of f whose degree divides an integer k with (j−1)l<k≤jl)
Step 4 (compute coarse DDF)
In this step, we compute polynomials F1,...,Fm where Fj=f[(j−1)l+1]f[(j−1)l+2]...f[jl]. This is done as follows.
s←f;
for j←1 to m do
{Fj←gcd(s,Ij);s←sFj}
Step 5 (compute fine DDF)
s←f;
for j←1 to m do
{Fj←gcd(s,Ij);s←sFj}
Step 5 (compute fine DDF)
In this step, we compute the output polynomials f[1],...,f[n].
First, initialize f[1],...,f[n] to 1. Then do the following.
for j←1 to m do
{
g←Fj;
for i←l−1 down to 0 do
{f[lj−i]←gcd(g,Hj−hi);g←gf[lj−i]}
{f[lj−i]←gcd(g,Hj−hi);g←gf[lj−i]}
}
if s≠1 then f[deg(s)]←s
Some technical remarks
1. Lemma. For any positive integer r if we are given h=xqrmodf∈Fq[x], then for any g∈Fq[x], we can compute gqrmodf as g(h)modf.
Now to perform Step 2 we set H1=hl and then compute each Hj as Hj−1(H1)modf.
2. Computing f(g)modh is a so-called "modular composition" problem. For solving this problem one can use e.g. Horner scheme or Brent and Kung's algorithm (this also requires fast matrix multiplication).
By now I implemented the simplest version of the fast CZ algorithm: it uses Horner scheme in Step 2.
The next step might be to implement matrix multiplication and Brent and Kung's algorithm.
No comments:
Post a Comment