These are the human proofs of Winograd Fourier transform algorithm, at full length.
WFTA computes the DFT of length q_1 ⋯ q_d with ∏ m_i − ∏ u_i multiplications and Σ (a_i + c_i) ∏_{j<i} m_j ∏_{j>i} q_j additions full
This proof shows: correctness, complexity.
Setting.R is C or Z/pZ, n=q1⋯qd with pairwise coprime qi∈{2,3,4,5,7,8}, and ω∈R has order exactly n. Put ωq=ωn/q, of order exactly q, and Fq=(ωqjk)0≤k,j<q. In Z/pZ an element of order q exists only if q∣p−1; so 2 is invertible when some qi∈{3,5,7,8} (then p≥7), and 3 is invertible when 7∣n (then p≥29). These are the only divisions in the constants. For a root w of order q write C(e)=(we+w−e)/2 and S(e)=(we−w−e)/2.
Statement. WFTA returns Xk=∑j<nxjωjk for all 0≤k<n. It does ∏imqi−∏iuqi multiplications and ∑i=1d(aqi+cqi)∏j<imqj∏j>iqj additions and subtractions, with (m,a,c,u) equal to (2,2,0,2), (3,3,3,1), (4,6,2,3), (6,8,9,1), (9,17,19,1) and (8,16,10,4) for q=2,3,4,5,7,8.
Lemma 1 (index maps). The map (j1,…,jd)↦j=∑ijin/qimodn is a bijection from ∏i[0,qi) to [0,n), and k↦(kmodq1,…,kmodqd) is a bijection from [0,n) to ∏i[0,qi). With a[j1,…,jd]=xj and ki=kmodqi,
Xk=j1,…,jd∑a[j1,…,jd]i=1∏dωqijiki.
Proof. For l=i, qi divides n/ql, so j≡jin/qi(modqi); since n/qi is coprime to qi, j determines each ji. The map is injective between sets of size n, hence bijective. The second map is bijective by the Chinese remainder theorem. Finally ωjk=∏iω(n/qi)jik=∏iωqijik, because ωn=1, and ωqijik=ωqijiki because ωqiqi=1. Summing over j, that is over all tuples, gives the formula. □
Lemma 2 (pairing). Let q be an odd prime, w of order q, tj±=xj±xq−j for 1≤j≤(q−1)/2. Then for 1≤k<q, Xk=x0+∑j(C(jk)tj++S(jk)tj−), and X0=x0+∑jtj+. Moreover C is even and S odd in e, and both depend on e modulo q.
Proof.xjwjk+xq−jw−jk=C(jk)(xj+xq−j)+S(jk)(xj−xq−j), since C+S=wjk and C−S=w−jk. Summing over the pairs {j,q−j}, which partition [1,q), gives the claim. □
Lemma 3 (cyclic convolution of length 3). For h,v∈R3, let yb=∑a<3h(b−a)mod3va, H=h0+h1+h2, ge=he−H/3, s=v0+v1+v2, d0=v0−v1, d1=v1−v2, e=v0−v2, P1=g0d0, P2=g1d1, P3=(g0+g1)e. Then y=3Hs(1,1,1)+(P1−P2,P3−P1,P2−P3).
Proof. Convolution is linear in the kernel, and the constant kernel 3H(1,1,1) gives 3Hs in every position. For g, g2=−g0−g1. Then g0v0+g2v1+g1v2=g0(v0−v1)−g1(v1−v2)=P1−P2; g1v0+g0v1+g2v2=g1(v0−v2)+g0(v1−v2)=(g0+g1)e−g0d0=P3−P1, using e=d0+d1; and the third entry is minus the sum of the first two, because ∑b∑agb−ava=(∑g)s=0, which is P2−P3. □
Lemma 4 (modules). For each q in the list and each w of order q, the module of the page (the code of _pre, _post and _mu) computes Fqx with root w.
Proof.q=2: w=−1, and the module returns (x0+x1,x0−x1).
q=4: w2=−1 (an element of order 2 in a field), w3=−w. Then X0=(x0+x2)+(x1+x3), X2=(x0+x2)−(x1+x3), X1=(x0−x2)+w(x1−x3) and X3=(x0−x2)−w(x1−x3), which are the four outputs.
q=3: by Lemma 2 with t±=x1±x2, X1=x0+C(1)t++S(1)t− and X2=x0+C(1)t+−S(1)t−, using C(2)=C(−1)=C(1) and S(2)=−S(1). The module has m0=x0+t+=X0, m1=(C(1)−1)t+, m2=S(1)t−, and m0+m1=x0+C(1)t+, so its outputs m0, m0+m1±m2 are right.
q=5: with t0,t1=x1+x4,x2+x3, u0,u1=x1−x4,x2−x3, and Ce=C(e), Se=S(e), Lemma 2 and C4=C1, S4=−S1 give X1=x0+C1t0+C2t1+S1u0+S2u1 and X2=x0+C2t0+C1t1+S2u0−S1u1, and X4, X3 are the same with the signs of the S terms reversed. The module computes s=t0+t1, m0=x0+s=X0, m1=(2C1+C2−1)s, m2=2C1−C2(t0−t1), m3=S2(u0+u1), m4=(S1−S2)u0, m5=−(S1+S2)u1. Then m0+m1±m2 is x0+C1t0+C2t1 or x0+C2t0+C1t1; m3+m4=S1u0+S2u1 and m3+m5=S2u0−S1u1. The outputs m0, r0+i0, r1+i1, r1−i1, r0−i0 are X0,…,X4.
q=7: let pj,uj=xj±x7−j for j=1,2,3. By Lemma 2, with Ce and Se taken modulo 7, the real parts Rk=x0+Ckp1+C2kp2+C3kp3 are
and the imaginary parts Ik=Sku1+S2ku2+S3ku3 are I1=S1u1+S2u2+S3u3, I3=S3u1−S1u2+S2u3 and I2=S2u1−S3u2−S1u3, with Xk=Rk+Ik and X7−k=Rk−Ik. The convolution y of Lemma 3 with kernel (C1,C3,C2) and input (p1,p2,p3) is (R1,R3,R2)−x0, by expanding yb=∑ahb−ava. The convolution with kernel (S1,−S3,S2) and input (u1,u2,−u3) is (I1,−I3,I2), by the same expansion. The module's inputs are those of Lemma 3 for both: s,d0,d1,e from (p1,p2,p3), and u1+u2−u3, u1−u2, u2+u3, u1+u3 from (u1,u2,−u3). Its constants are 1 for m0=x0+s=X0, H/3−1 for s, so that m0+m1=x0+3Hs, then g0,g1,g0+g1, then T/3 and the three values of the second kernel. So rb=m0+m1+wb=x0+yb gives R1,R3,R2, and ub gives I1,−I3,I2. The outputs m0, r0+u0, r2+u2, r1−u1, r1+u1, r2−u2, r0−u0 are X0,X1,X2,X3,X4,X5,X6.
q=8: let J=w2, of order 4, so J2=−1 and 1+J=0; put c=w/(1+J). Write sj=xj+xj+4 and dj=xj−xj+4 for j<4. Since w4=−1, X2k′=∑j<4sjJjk′, the DFT of length 4 of s with root J, which the first four products and the q=4 formulas compute. And X2k′+1=∑j<4zjJjk′ with zj=wjdj. Now w=c(1+J) and w3=wJ=c(J−1), so
using J2=−1. With a,b=d0±Jd2, P=m6+m7 and Q=m7−m6, where m6=c(d1−d3) and m7=cJ(d1+d3), the DFT of length 4 of z is (a+P,b+Q,a−P,b−Q), which are X1,X3,X5,X7. □
Lemma 5 (axes and Kronecker products). Store an array of shape (s1,…,sd) in row-major order. Applying a linear map L:Rsi→Rr to every line along axis i is multiplication by Is1⋯si−1⊗L⊗Isi+1⋯sd, and multiplying entry (t1,…,td) by ∏iμi[ti] is multiplication by diag(μ1)⊗⋯⊗diag(μd).
Proof. In row-major order the entry (t1,…,td) has position ∑iti∏l>isl, which is the indexing of the Kronecker product: the entry of P⊗Q in row (r,r′) and column (c,c′) is PrcQr′c′. Applying L along axis i changes ti by L and keeps the other coordinates, which is the stated product, and the diagonal case is the same statement for the entries. □
Correctness. By Lemma 5, line L3 multiplies vec(a) by ∏i=d1(Im1⋯mi−1⊗Ai⊗Iqi+1⋯qd), which by the mixed-product rule (P⊗Q)(P′⊗Q′)=PP′⊗QQ′ equals A1⊗⋯⊗Ad. Line L4 multiplies by ⨂idiag(μi); skipping the products whose factors are all 1 does not change any value. Line L5 multiplies by C1⊗⋯⊗Cd in the same way, in the reverse order. By the mixed-product rule again, the whole is ⨂iCidiag(μi)Ai=⨂iFqi by Lemma 4 with w=ωqi. The entry of (⨂iFqi)vec(a) at (k1,…,kd) is ∑a[j1,…,jd]∏iωqijiki, which is Xk by Lemma 1, and line L6 reads it at ki=kmodqi. The inverse transform is the same computation with ω−1, which has order n, followed by division by n.
Operation count. A module application costs aq additions in Aq and cq in Cq, read off from the straight-line code; the table of the page lists them. Applying Aqi along axis i costs aqi times the number of lines, the product of the other axis lengths. When line L3 treats axis i, the axes j<i already have length mqj and the axes j>i still have length qj. When line L5 treats axis i (in decreasing order), the axes j>i have been shrunk back to qj and the axes j<i still have length mqj. So both passes over axis i cost (aqi+cqi)∏j<imqj∏j>iqj, which sums to the stated count. Line L4 does one multiplication for each of the ∏imqi tuples except the ∏iuqi whose constants are all 1. Lines L1, L2 and L6 do no arithmetic on the data; the constants and their products depend only on n. The index maps and the passes over the array cost O(d∏imqi) steps, and the array has at most ∏imqi entries.
Real and imaginary constants. Over C with w=e−2πi/q, w−e=we, so every C(e) is real and every S(e) purely imaginary; so are H (a sum of C values), T (a sum of S values), the g and h values, and the constants 1. For q=8, J=−i, 1+J=1−i and w=(1−i)/2, so c=1/2 is real and cJ imaginary. Hence every product ∏iμi[ti] is real or purely imaginary, and multiplying a complex number by it costs 2 real multiplications. ■