fft.md
1 # Discrete Fast Fourier Transform 2 3 Available code files: 4 5 * [fft2.sage](https://codeberg.org/darkrenaissance/darkfi/src/branch/master/script/research/zk/fft/fft2.sage): 6 implementation using vandermonde matrices illustrating the theory section below. 7 * [fft3.sage](https://codeberg.org/darkrenaissance/darkfi/src/branch/master/script/research/zk/fft/fft3.sage): 8 simple example with $n = 4$ showing 3 steps of the algorithm. 9 * [fft4.sage](https://codeberg.org/darkrenaissance/darkfi/src/branch/master/script/research/zk/fft/fft4.sage): 10 illustrates the full working algorithm. 11 12 ## Theory 13 14 $$ f(x)g(x) ā š½_{<2n}[x] $$ 15 $$ fg = \sum_{i + j < 2n - 2} a_i b_j x^{i + j} $$ 16 Complexity: $O(n^2)$ 17 18 Suppose $Ļ ā š½$ is an nth root of unity. 19 20 Recall: if $š½ = š½_{p^k}$ then $āN : š½_{p^N}$ 21 contains all nth roots of unity. 22 23 $$ \DFT_Ļ : š½^n ā š½^n $$ 24 $$ \DFT_Ļ(f) = (f(Ļ^0), f(Ļ^1), ā¦, f(Ļ^{n - 1})) $$ 25 26 $$ V_Ļ = 27 \begin{pmatrix} 28 1 & 1 & 1 & \cdots & 1 \\ 29 1 & Ļ^1 & Ļ^2 & \cdots & Ļ^{n - 1} \\ 30 1 & Ļ^2 & Ļ^4 & \cdots & Ļ^{2(n - 1)} \\ 31 \vdots \\ 32 1 & Ļ^{n - 1} & Ļ^{2(n - 1)} & \cdots & Ļ^{(n - 1)^2} \\ 33 \end{pmatrix} 34 $$ 35 36 $$ \DFT_Ļ(f) = V_Ļ Ā· f^T $$ 37 since vandermonde multiplication is simply evaluation of a polynomial. 38 39 ### Lemma: $V_Ļ^{-1} = \frac{1}{n} V_{Ļ^{-1}}$ 40 41 Use $1 + Ļ + ⯠+ Ļ^{n - 1}$ and compute $V_Ļ V_{Ļ^{-1}}$ 42 43 Corollary: $\DFT_Ļ$ is invertible. 44 45 ### Definitions 46 47 1. Convolution $f * g = fg \mod (x^n - 1)$ 48 2. Pointwise product 49 $$(a_0, ā¦, a_{n - 1})Ā·(b_0, ā¦, b_{n - 1}) = 50 (a_0 b_0, ā¦, a_{n - 1} b_{n - 1}) ā š½^n ā š½_{<n}[x]$$ 51 52 ### Theorem: $\DFT_Ļ(f*g) = \DFT_Ļ(f)Ā·\DFT_Ļ(g)$ 53 54 $$ fg = q'(x^n - 1) + f*g $$ 55 $$ ā f*g = fg + q(x^n - 1) $$ 56 $$ \deg fg ⤠2n - 2 $$ 57 58 $$ 59 \begin{align} 60 (f*g)(Ļ^i) &= f(Ļ^i)g(Ļ^i) + q(Ļ^i)(Ļ^{in} - 1) \\ 61 &= f(Ļ^i)g(Ļ^i) 62 \end{align} 63 $$ 64 65 ### Result 66 67 $$ f, g ā š½_{<n/2}[x] $$ 68 $$ fg = f*g $$ 69 $$ \DFT_Ļ(f*g) = \DFT_Ļ(f)Ā·\DFT_Ļ(g) $$ 70 $$ fg = \frac{1}{n} \DFT_{Ļ^{-1}} (\DFT_Ļ(f) Ā· \DFT_Ļ(g)) $$ 71 72 ## Finite Field Extension Containing Nth Roots of Unity 73 74 $$ μ_N = āØĻā©, |š½_{p^N}^Ć| = p^N - 1 $$ 75 $$ \textrm{ord}(Ļ) = n | p^N - 1 $$ 76 but $š½_{p^N}^Ć$ is cyclic. 77 78 For all $d | p^N - 1$, there exists $x ā š½_{p^N}^Ć$ 79 with ord$(x) = d$. 80 81 Finding $n | p^N - 1$ is sufficient for $Ļ ā š½_{p^N}$ 82 $$ n | p^N - 1 ā \textrm{ord}(p) = (⤠/ nā¤)^Ć $$ 83 84 ## FFT Algorithm Recursive Compute 85 86 We recurse to a depth of $\log n$. Since each recursion uses $Ļ^i$, then 87 in the final step $Ļ^i = 1$, and we simply return $f^T$. 88 89 We only need to prove a single step of the algorithm produces the desired 90 result, and then the correctness is inductively proven. 91 92 $$ 93 \begin{align} 94 f(X) &= a_0 + a_1 X + a_2 X^2 + ⯠+ a_{n - 1} X^{n - 1} \\ 95 &= g(X) + X^{n/2} h(X) 96 \end{align} 97 $$ 98 99 ### Algorithm 100 101 Implementation of this algorithm is available in [fft4.sage](https://codeberg.org/darkrenaissance/darkfi/src/branch/master/script/research/zk/fft/fft4.sage). 102 Particularly the function called `calc_dft()`. 103 104 **function** DFT($n = 2^d, f(X)$)<br> 105 <span style="padding-left: 30px;">**if** $n = 1$ **then**</span><br> 106 <span style="padding-left: 60px;"> **return** $f(X)$</span><br> 107 <span style="padding-left: 30px;">**end**</span><br> 108 <span style="padding-left: 30px;">Write $f(X)$ as the sum of two polynomials with equal degree</span><br> 109 <span style="padding-left: 30px;">$f(X) = g(X) + X^{n/2} h(X)$</span><br> 110 <span style="padding-left: 30px;">Let $\mathbf{g}, \mathbf{h}$ be the vector representations of $g(X), h(X)$</span><br> 111 <span style="padding-left: 30px;"></span><br> 112 <span style="padding-left: 30px;">$\mathbf{r} = \mathbf{g} + \mathbf{h}$</span><br> 113 <span style="padding-left: 30px;">$\mathbf{s} = (\mathbf{g} - \mathbf{h})Ā·(Ļ^0, ā¦, Ļ^{n/2 - 1})$</span><br> 114 <span style="padding-left: 30px;">Let $r(X), s(X)$ be the polynomials represented by the vectors $\mathbf{r}, \mathbf{s}$</span><br> 115 <span style="padding-left: 30px;"></span><br> 116 <span style="padding-left: 30px;">Compute $(r(Ļ^0), ā¦, r(Ļ^{n/2})) = \textrm{DFT}_{Ļ^2}(n/2, r(X))$</span><br> 117 <span style="padding-left: 30px;">Compute $(s(Ļ^0), ā¦, s(Ļ^{n/2})) = \textrm{DFT}_{Ļ^2}(n/2, s(X))$</span><br> 118 <span style="padding-left: 30px;"></span><br> 119 <span style="padding-left: 30px;">**return** $(r(Ļ^0), s(Ļ^0), r(Ļ^2), s(Ļ^2), ā¦, r(Ļ^{n/2}), s(Ļ^{n/2}))$</span><br> 120 end 121 122 Sage code: 123 124 ```python 125 def calc_dft(Ļ_powers, f): 126 m = len(f) 127 if m == 1: 128 return f 129 g, h = vector(f[:m/2]), vector(f[m/2:]) 130 131 r = g + h 132 s = dot(g - h, Ļ_powers) 133 134 Ļ_powers = vector(Ļ_i for Ļ_i in Ļ_powers[::2]) 135 rT = calc_dft(Ļ_powers, r) 136 sT = calc_dft(Ļ_powers, s) 137 138 return list(alternate(rT, sT)) 139 ``` 140 141 ### Even Values 142 143 $$ 144 \begin{align} 145 r(X) &= g(X) + h(X) \\ 146 \\ 147 f(Ļ^{2i}) &= g(Ļ^{2i}) + (Ļ^{2i})^{n/2} h(Ļ^{2i}) \\ 148 &= g(Ļ^{2i}) + h(Ļ^{2i}) \\ 149 &= (g + h)(Ļ^{2i}) \\ 150 \end{align} 151 $$ 152 153 So then we can now compute $DFT_Ļ(f)_{k=2i} = DFT_{Ļ^2}(r)$ 154 for the even powers of $f(Ļ^{2i})$. 155 156 ### Odd Values 157 158 For odd values $k = 2i + 1$ 159 160 $$ 161 \begin{align} 162 s(X) &= (g(X) - h(X))Ā·(Ļ^0, ā¦, Ļ^{n/2 - 1}) \\ 163 \\ 164 f(X) &= a_0 + a_1 X + a_2 X^2 + ⯠+ a_{n - 1} X^{n - 1} \\ 165 &= g(X) + X^{n/2} h(X) \\ 166 f(Ļ^{2i + 1}) &= g(Ļ^{2i + 1}) + (Ļ^{2i + 1})^{n/2} h(Ļ^{2i + 1}) \\ 167 \end{align} 168 $$ 169 But observe that for any $n$th root of unity $Ļ^n = 1$ and $Ļ^{n/2} = -1$ 170 $$ (Ļ^{2i + 1})^{n/2} = Ļ^{in} Ļ^{n/2} = Ļ^{n/2} = -1 $$ 171 $$ 172 \begin{align} 173 ā f(Ļ^{2i + 1}) &= g(Ļ^{2i + 1}) - h(Ļ^{2i + 1}) \\ 174 &= (g - h)(Ļ^{2i + 1}) 175 \end{align} 176 $$ 177 178 Let $\mathbf{s} = (\mathbf{g} - \mathbf{h})Ā·(Ļ^0, ā¦, Ļ^{n/2 - 1})$ be the 179 representation for $s(X)$. Then we can see that $s(Ļ^{2i}) = (g - h)(Ļ^{2i + 1})$ 180 as desired. 181 182 So then we can now compute $DFT_Ļ(f)_{k=2i + 1} = DFT_{Ļ^2}(s)$ 183 for the odd powers of $f(Ļ^{2i + 1})$. 184 185 ## Example 186 187 Let $n = 8$ 188 $$ 189 \begin{align} 190 f(X) &= (a_0 + a_1 X + a_2 X^2 + a_3 X^3) + (a_4 X^4 + a_5 X^5 + a_6 X^6 + a_7 X^7) \\ 191 &= (a_0 + a_1 X + a_2 X^2 + a_3 X^3) + X^4 (a_4 + a_5 X + a_6 X^2 + a_7 X^3) \\ 192 &= g(X) + X^{n/2} h(X) \\ 193 g(X) &= a_0 + a_1 X + a_2 X^2 + a_3 X^3 \\ 194 h(X) &= a_4 + a_5 X + a_6 X^2 + a_7 X^3 \\ 195 \end{align} 196 $$ 197 Now vectorize $g(X), h(X)$ 198 $$ 199 \begin{align} 200 \mathbf{g} &= (a_0, a_1, a_2, a_3) \\ 201 \mathbf{h} &= (a_4, a_5, a_6, a_7) \\ 202 \end{align} 203 $$ 204 Compute reduced polynomials in vector form 205 $$ 206 \begin{align} 207 \mathbf{r} &= \mathbf{g} + \mathbf{h} \\ 208 &= (a_0 + a_4, a_1 + a_5, a_2 + a_6, a_3 + a_7) \\ 209 \mathbf{s} &= (\mathbf{g} - \mathbf{h})Ā·(1, Ļ, Ļ^2, Ļ^3) \\ 210 &= (a_0 - a_4, a_1 - a_5, a_2 - a_6, a_3 - a_7)Ā·(1, Ļ, Ļ^2, Ļ^3) \\ 211 &= (a_0 - a_4, Ļ (a_1 - a_5), Ļ^2 (a_2 - a_6), Ļ^3 (a_3 - a_7)) \\ 212 \end{align} 213 $$ 214 Convert them to polynomials from the vectors. We also expand them out below 215 for completeness. 216 $$ 217 \begin{align} 218 r(X) &= r_0 + r_1 X + r_2 X^2 + r_3 X^3 \\ 219 &= (a_0 + a_4) + (a_1 + a_5) X + (a_2 + a_6) X^2 + (a_3 + a_7) X^3 \\ 220 s(X) &= s_0 + s_1 X + s_2 X^2 + s_3 X^3 \\ 221 &= (a_0 - a_4) + Ļ (a_1 - a_5) X + Ļ^2 (a_2 - a_6) X^2 + Ļ^3 (a_3 - a_7) X^3 \\ 222 \end{align} 223 $$ 224 Compute 225 $$ \textrm{DFT}_{Ļ^2}(4, r(X)), \textrm{DFT}_{Ļ^2}(4, s(X)) $$ 226 The values returned will be 227 $$ 228 (r(1), s(1), r(Ļ^2), s(Ļ^2), r(Ļ^4), s(Ļ^4), r(Ļ^6), s(Ļ^6)) 229 = 230 (f(1), f(Ļ), f(Ļ^2), f(Ļ^3), f(Ļ^4), f(Ļ^5), f(Ļ^6), f(Ļ^7)) 231 $$ 232 Which is the output we return. 233 234 ### Comparing Evaluations for $f(X)$ and $r(X), s(X)$ 235 236 We can see the evaluations are correct by substituting in $Ļ^i$. 237 238 We expect that $s(X)$ on the domain $(1, Ļ^2, Ļ^4, Ļ^6)$ produces the values 239 $(f(1), f(Ļ^2), f(Ļ^4), f(Ļ^6))$, while $r(X)$ on the same domain produces 240 $(f(Ļ), f(Ļ^3), f(Ļ^5), f(Ļ^7))$. 241 242 #### Even Values 243 244 Let $k = 2i$, be an even number. Then note that $k$ is a multiple of 2, so 245 $4k$ is a multiple of $n ā Ļ^{4k} = 1$, 246 $$ 247 \begin{align} 248 r(X) &= (a_0 + a_4) + (a_1 + a_5) X + (a_2 + a_6) X^2 + (a_3 + a_7) X^3 \\ 249 r(Ļ^{2i}) &= (a_0 + a_4) + (a_1 + a_5) Ļ^{2i} + (a_2 + a_6) Ļ^{4i} + (a_3 + a_7) Ļ^{6i} \\ 250 f(Ļ^k) &= (a_0 + a_1 Ļ^k + a_2 Ļ^{2k} + a_3 Ļ^{3k}) + Ļ^{4k} (a_4 + a_5 Ļ^k + a_6 Ļ^{2k} + a_7 Ļ^{3k}) \\ 251 &= (a_0 + a_1 Ļ^k + a_2 Ļ^{2k} + a_3 Ļ^{3k}) + (a_4 + a_5 Ļ^k + a_6 Ļ^{2k} + a_7 Ļ^{3k}) \\ 252 &= (a_0 + a_4) + (a_1 + a_5) Ļ^k + (a_2 + a_6) Ļ^{2k} + (a_3 + a_7) Ļ^{3k} \\ 253 &= f(Ļ^{2i}) \\ 254 &= (a_0 + a_4) + (a_1 + a_5) Ļ^{2i} + (a_2 + a_6) Ļ^{4i} + (a_3 + a_7) Ļ^{6i} \\ 255 &= r(Ļ^{2i}) 256 \end{align} 257 $$ 258 259 #### Odd Values 260 261 For $k = 2i + 1$ odd, we have a similar relation where $4k = 8i + 4$, so 262 $Ļ^{4k} = Ļ^4$. But observe that $Ļ^4 = -1$. 263 $$ 264 \begin{align} 265 s(X) &= (a_0 - a_4) + Ļ (a_1 - a_5) X + Ļ^2 (a_2 - a_6) X^2 + Ļ^3 (a_3 - a_7) X^3 \\ 266 s(Ļ^{2i}) &= (a_0 - a_4) + (a_1 - a_5) Ļ^{2i + 1} + (a_2 - a_6) Ļ^{4i + 2} + (a_3 - a_7) Ļ^{6i + 3} \\ 267 f(Ļ^k) &= (a_0 + a_1 Ļ^k + a_2 Ļ^{2k} + a_3 Ļ^{3k}) + Ļ^{4k} (a_4 + a_5 Ļ^k + a_6 Ļ^{2k} + a_7 Ļ^{3k}) \\ 268 &= (a_0 + a_1 Ļ^k + a_2 Ļ^{2k} + a_3 Ļ^{3k}) - (a_4 + a_5 Ļ^k + a_6 Ļ^{2k} + a_7 Ļ^{3k}) \\ 269 &= f(Ļ^{2i + 1}) \\ 270 &= (a_0 + a_1 Ļ^{2i + 1} + a_2 Ļ^{4i + 2} + a_3 Ļ^{6i + 3}) - (a_4 + a_5 Ļ^{2i + 1} + a_6 Ļ^{4i + 2} + a_7 Ļ^{6i + 3}) \\ 271 &= 272 (a_0 - a_4) 273 + (a_1 - a_5) Ļ^{2i + 1} 274 + (a_2 - a_6) Ļ^{4i + 2} 275 + (a_3 - a_7) Ļ^{6i + 3} \\ 276 &= s(Ļ^{2i}) 277 \end{align} 278 $$ 279