快速傅里叶变换
前言:本文避免了大量学术化符号,尽可能面向大众,部分内容存在不严谨。
快速傅里叶变换:
\(\mathcal{O}(n\log n)\) 的时间复杂度内计算两个 \(n\) 次多项式的积,优于 \(\mathcal{O}(n^2)\)。也可以用来加速大整数乘法(看作是多项式乘法)
前置知识:
复数,基本的三角函数。
设复数 \(z=a+bi\),模 \(r=|z|=\sqrt{a^2+b^2}\),辐角 \(\theta\),满足 \(a=r\cos\theta,b=r\sin\theta\)
复数三角形式: \(\boldsymbol{z=r(\cos\theta+i\sin\theta)}\) ,\(r\ge0\) 为复数的模; \(\theta\) 为辐角,主辐角通常取 \(\theta\in[0,2\pi)\)。
运算: \(z_1=r_1(\cos\theta_1+i\sin\theta_1),\quad z_2=r_2(\cos\theta_2+i\sin\theta_2)\)
\(\boldsymbol{z_1z_2=r_1r_2\big[\cos(\theta_1+\theta_2)+i\sin(\theta_1+\theta_2)\big]}\) 模相乘,辐角相加。\(n\) 次方根:\(\boldsymbol{w_k=\sqrt[n]{r}\left(\cos\frac{\theta+2k\pi}{n}+i\sin\frac{\theta+2k\pi}{n}\right),\ k=0,1,\dots,n-1}\)
引入:
对于多项式 \(A=x^4+2x^3+4x^2+5x+4\),\(B=2x^4+3x^3+x^2+4x+3\),我们如果要计算 \(C=A\times B\),需要每一项每一项计算,时间复杂度 \(\mathcal{O}(n^2)\),而使用快速傅里叶变换可以降到 \(\mathcal{O}(n\log n)\)。
离散傅里叶变换:
将一个 \(n\) 次多项式转换成一个点值表示。
设多项式 \(A(x)=\sum_{k=0}^{n-1}a_k x^k\),任取 \(n\) 个两两互异的采样点 \(x_0,x_1,\dots,x_{n-1}\),记 \(y_i=A(x_i)\),
则集合 $${(x_0,y_0),(x_1,y_1),\dots,(x_{n-1},y_{n-1})}$$ 称为多项式 \(A(x)\) 的一种点值表示。
性质:
唯一性:给定 \(n\) 组互异点 \((x_i,y_i)\),存在唯一次数小于 \(n\) 的多项式满足 \(A(x_i)=y_i\)
不唯一性:同一多项式可选取不同采样点,得到互不相同的点值表示
运算特性:若 \(A(x),B(x)\) 在同一组采样点上有点值 \(\{A(x_i)\},\{B(x_i)\}\),则乘积多项式 \(C(x)=A(x)B(x)\) 在该组点上满足 \(C(x_i)=A(x_i)\cdot B(x_i).\)
傅里叶发现,可以将 \(n\) 个 \(x_i\) 表示成 \(n\) 个模长为 \(1\) 的复数。
设 \(n\) 为正整数,考虑复平面上的单位圆。从点 \((1,0)\) 出发,沿逆时针方向将单位圆 \(n\) 等分,得到的第 \(k\) 个分点(从 \(0\) 开始编号)对应的复数为
这些复数称为 \(n\) 次单位根,它们满足 \((\omega_n^k)^n=1\),且 \(\omega_n^k=(\omega_n^1)^k\)。单位根在乘法下构成一个循环群,其几何意义是均匀分布在单位圆上的向量。
给定一个 \(n-1\) 次多项式 \(A(x)=a_0+a_1x+a_2x^2+\cdots+a_{n-1}x^{n-1},\)
将全部 \(n\) 个单位根 \(\omega_n^0,\omega_n^1,\dots,\omega_n^{n-1}\) 依次代入 \(A(x)\),得到一组值 \(y_k = A(\omega_n^k),\qquad k=0,1,\dots,n-1.\)
这组值 \((y_0,y_1,\dots,y_{n-1})\) 称为多项式 \(A(x)\) 的 离散傅里叶变换(DFT)。
为什么要使用单位根作为 \(x\) 代入,是因为离散傅里叶变换有着特殊的性质。
设 \((y_0, y_1, y_2, ..., y_{n - 1})\) 为多项式 \(A(x) = a_0 + a_1x + a_2x^2 +...+a_{n-1}x^{n-1}\) 的离散傅里叶变换。
现在我们再设一个多项式 \(B(x) = y_0 + y_1x + y_2x^2 +...+y_{n-1}x^{n-1}\),现在我们把上面的 \(n\) 个单位根的倒数,即 \(\omega_{n}^{0}, \omega_{n}^{-1}, \omega_{n}^{-2}, ..., \omega_{n}^{-(n - 1)}\) 作为 \(x\) 代入 \(B(x)\),得到一个新的离散傅里叶变换 \((z_0, z_1, z_2, ..., z_{n - 1})\)。
内层和式 \(\displaystyle\sum_{i=0}^{n-1}(\omega_n^{j-k})^i\) 可求:
-
若 \(j=k\),则每一项均为 \(1\),故 \(S=n\);
-
若 \(j\ne k\),由等比数列求和公式得
\[S=\frac{(\omega_n^{j-k})^n-1}{\omega_n^{j-k}-1} =\frac{(\omega_n^n)^{j-k}-1}{\omega_n^{j-k}-1} =\frac{1^{j-k}-1}{\omega_n^{j-k}-1}=0. \]
那么,\(z_k\) 就等于 \(na_k\),即:\(a_i = \frac{z_i}{n}\)
一个结论: 把多项式 \(A(x)\) 的离散傅里叶变换结果作为另一个多项式 \(B(x)\) 的系数,取单位根的倒数即 \(\omega_{n}^{0}, \omega_{n}^{-1}, \omega_{n}^{-2}, ..., \omega_{n}^{-(n - 1)}\) 作为 \(x\) 代入 \(B(x)\),得到的每个数再除以 \(n\),得到的是 \(A(x)\) 的各项系数。这实现了傅里叶变换的逆变换——把点值表示转换成多项式系数表示,这就是离散傅里叶变换神奇的特殊性质。
快速傅里叶变换(FFT)
我们设 \(A(x) = a_0 + a_1x + a_2x^2 +...+a_{n-1}x^{n-1}\),现在为了求离散傅里叶变换,要把一个 \(x = \omega_n^k\) 代入。
考虑将 \(A(x)\) 的每一项按照下标的奇偶分成两部分:
设两个多项式:
-
\[A_1(x) = a_0 + a_2x + ... + a_{n - 2}x^{\frac{n}{2} - 1} \]
-
\[A_2(x) = a_1 + a_3x + ... + a_{n - 1}x^{\frac{n}{2} - 1} \]
则:
假设 \(k < \frac{n}{2}\),现在要把 \(x = \omega_n^k\) 代入:
那么对于 \(A(\omega_n^{k + \frac{n}{2}})\):
上述两式表明,只要我们已经计算出两个子多项式 \(A_1\) 和 \(A_2\) 在 \(\frac{n}{2}\) 个单位根 \(\omega_{n/2}^{0},\omega_{n/2}^{1},\dots,\omega_{n/2}^{n/2-1}\) 处的所有取值,就能用 \(O(n)\) 次运算合并得到 \(A(x)\) 在全部 \(n\) 个单位根处的 DFT 结果。这种分治策略不断将问题规模减半,边界条件为 \(n=1\) 时直接返回常数项。递归深度为 \(\log_2 n\),每层总合并代价为 \(O(n)\),故总时间复杂度为 \(O(n\log n)\),这就是快速傅里叶变换的基本原理。

浙公网安备 33010602011771号