Yun's algorithm returns the square-free factorization, at the cost of a constant number of gcds full
This proof shows: correctness.
Let F be a field of characteristic 0 or of characteristic p>n, and let f∈F[x] be monic of degree n≥1 (the implementation first divides by the leading coefficient). Let f=∏j=1kajj be the square-free factorization, with the aj monic, square-free, pairwise coprime and ak=1; it exists and is unique, as shown on the square-free factorization page.
Step 0. Each aj is coprime to jaj′. If aj=1 there is nothing to show. Otherwise let q be an irreducible factor of aj. Over a field of characteristic 0, q′=0 because degq≥1. In characteristic p>n, q′=0 would force q to be a polynomial in xp and so degq≥p>n, which is impossible. So q′=0, degq′<degq, and q∤q′. Write aj=qr with q∤r, because aj is square-free. Then aj′=q′r+qr′, and q∤q′r, so q∤aj′. Also j≤n, so j=0 in F, and q∤jaj′. This holds for every irreducible factor q of aj, so gcd(aj,jaj′)=1.
Notation. For 1≤i≤k+1 let
bi=j≥i∏aj,ei=j≥i∑(j−i+1)aj′ajbi,di=ei−bi′=j>i∑(j−i)aj′ajbi, with bk+1=1. The last form of di uses bi′=∑j≥iaj′bi/aj, the product rule, and the term j=i of ei has the factor j−i+1=1.
Lines L2 and L3. By the product rule, f′=∑jjajj−1aj′∏l=jall. Let g=∏jajj−1. Then f=gb1 and f′=ge1, since jajj−1aj′∏l=jall=g⋅jaj′b1/aj. Also gcd(b1,e1)=1: for each j, every term of e1 except the term j is divisible by aj, and the term j, jaj′b1/aj, is coprime to aj by Step 0 and because the al are pairwise coprime. So gcd(f,f′)=ggcd(b1,e1)=g, as g is monic. Line L2 computes b=g and line L3 computes c=f/g=b1 and d=f′/g−c′=e1−b1′=d1.
Loop invariant. At the ith test of line L4, c=bi and d=di, and the list holds a1,…,ai−1. It holds for i=1 by the previous paragraph.
Line L5. We show gcd(bi,di)=ai. Each term of di has j>i, so its factor bi/aj contains ai; so ai∣di. For j>i, every term of di other than the term j is divisible by aj, and the term j, (j−i)aj′bi/aj, is coprime to aj: j−i is between 1 and n, so it is nonzero in F, aj is coprime to aj′ by Step 0, and aj is coprime to the other al. So gcd(aj,di)=1 for j>i. Since bi=ai∏j>iaj with pairwise coprime factors, gcd(bi,di)=ai⋅∏j>igcd(aj,di/ai)=ai; the gcd of aj with di/ai is 1 because it divides gcd(aj,di)=1. This also covers ai=1.
Lines L6 to L8. Line L6 appends ai. Line L7 sets c=bi/ai=bi+1. Line L8 sets d=di/ai−bi+1′. Now di/ai=∑j>i(j−i)aj′bi+1/aj=∑j≥i+1(j−(i+1)+1)aj′bi+1/aj=ei+1, so d=ei+1−bi+1′=di+1. The invariant holds for i+1.
Termination and result. bi=1 exactly when aj=1 for all j≥i, that is when i>k, because ak=1. So the loop runs for i=1,…,k and stops with the list a1,…,ak, which line L9 returns with the leading coefficient of the input. A constant input is handled before line L1.
Cost. Let ni=degbi=∑j≥idegaj. Then ∑i=1kni=∑jjdegaj=n, and degdi<ni. Iteration i makes one gcd of two polynomials of degree at most ni, two exact divisions of polynomials of degree at most ni, and one derivative. With the Euclidean algorithm and schoolbook division these cost O(ni2), and ∑ini2≤(∑ini)2=n2. Lines L2 and L3 cost O(n2). So the total is O(n2) field operations. If a gcd of degree d costs G(d) with G(d)/d nondecreasing, then ∑iG(ni)≤∑i(ni/n)G(n)=G(n), and with fast division the total is O(G(n)+M(n)logn)=O(M(n)logn) with the fast Euclidean algorithm. ■