快速傅里叶变换(FFT)学习笔记

有关多项式的一个基础算法,理解起来比较困难。

快速傅里叶变换(\(\text{Fast Fourier Transform,FFT}\))和傅里叶变换(\(\text{Fourier Transform,FT}\))没什么关系,也不是傅里叶发明的。这种算法用于在 \(O(n\log n)\) 时间复杂度内求出两个多项式的卷积(相当于多项式之间相乘)。

前置知识

多项式的表示

\(n\) 项式等价于 \(n-1\) 次项式。(每个次项的系数都不为零)

系数表示法

形如 \(F(x)=\sum\limits^{n-1}_{i=0} a_ix^i\),把一个 \(n-1\) 次项式的每一次项都表示出来。

两个多项式直接相乘时间复杂度为 \(O(n^2)\)

点值表示法

对于一个 \(n-1\) 次多项式,可以用 \(n\) 个点 \((x_i,y_i=F(x_i)\) 来表示,相当于由 \(n\)\(n\) 次方程组成的方程组 。

当两个表示不同多项式的点 \(x\) 坐标相等,\(y\) 坐标直接相乘。这种情况下相乘时间复杂度为 \(O(n)\)

两种表示法间的转换

系数表示法 \(\rightarrow\) 点值表示法

对于 \(n-1\) 次项式选取 \(n\) 个点计算对应值来表示。

点值表示法 \(\rightarrow\) 系数表示法

根据每个点列出 \(n-1\) 元方程,通过高斯消元解出方程。

注意在上述及下文的关于多个多项式的计算中,要统一次数,次数低的多项式要在高次上补零。

复数

复数及三角函数学习笔记

单位根是在FFT的思想中一项非常重要的部分。

思想

正常多项式的的乘法并没有什么捷径,时间复杂度 \(O(n^2)\)。于是数学家们想到了可以变为使用点值表示法来运算,能将相乘的时间复杂度优化到 \(O(n)\)

接下来的难点便是如何进行系数表示法与点值表示法之间的转换。这需要用到离散傅里叶变换\(\text{Discrete Fourier Transform,DFT}\))和离散傅里叶逆变换\(\text{Inverse Discrete Fourier Transform,IDFT}\))。

请注意接下来的内容中 \(n=2^m\),其中 \(m\in\N\)\(m\) 是正整数),许多性质需要依靠这个条件才能推出来。

DFT

DFT 是一种将多项式从系数表示法转换为点值表示法的算法。

我们设多项式 \(A(x)=a_0+a_1x+a_2x^2+a_3x^3+\cdots+a_{n-1}x^{n-1}\)

将其系数及其所对应项按照下标奇偶性分类,则有

\[A(x)=(a+a_2x^2+a_4x^4+\cdots+a_{n-2}x^{n-2})+(a_1x^1+a_3x^3+\cdots+a_{n-1}x^{n-1}) \]

\[A_1(x)=a_0+a_2x+a_4x^2+\cdots+a_{n-2}x^{\frac{n}{2}-1}\\ A_2(x)=a_1x+a_3x^2+a_5x^3+\cdots+a_{n-1}x^{\frac{n}{2}-1} \]

(注意此处 \(x\) 指数的区别以及此处的 \(n\) 与上个公式是同一个)

可以得到:

\[A(x)=A_1(x^2)+xA_2(x^2) \]

此时将 \(x=\omega_n^k(0<k<\frac{n}{2})\) 带入 \(A(x)\),得

\[A(\omega_n^k)=A_1(\omega_n^{2k})+\omega_n^k A_2(\omega_n^{2k})\\ \]

同理,将 \(x=\omega_n^{k+\frac{n}{2}}(0<k<\frac{n}{2})\) 带入 \(A(x)\),得

\[A(\omega_n^{k+\frac{n}{2}})=A_1(\omega_n^{2k+n})+\omega_n^{k+\frac{n}{2}}A_2(\omega_n^{2k+n})\\ =A_1(\omega_n^{2k}\cdot\omega_n^n)+\omega_n^{k+\frac{n}{2}}A_2(\omega_n^{2k}\cdot\omega_n^n)\\ =A_1(\omega_n^{2k}\cdot1)+\omega_n^k\cdot\omega_n^{\frac{n}{2}}\cdot A_2(\omega_n^{2k}\cdot1)\\ =A_1(\omega_n^{2k})-\omega_n^kA_2(\omega_n^{2k}) \]

我们发现这个公式与上面那个公式很像,只有一个系数不一样。也就是说,如果我们知道上面那个

公式,那么下面那个公式就能在 \(O(1)\) 的时间内求出来。

发现当 \(k\) 的的取值遍历 \([0,\frac{n}{2}-1]\) 时,\(k+\frac{n}{2}\) 的取值正好遍历了 \([\frac{n}{2},n-1]\)

也就是说,只需要算出多项式的一半,另一半就能立马算出来,变成了类似于分治的一种思想。

这种思想的时间复杂度为 \(O(n\log n)\)

IDFT

IDFT 是一种将多项式从点值表示法转换为系数表示法的算法。是 DFT 的逆算法。

posted @ 2023-07-04 21:48  Lyz09  阅读(36)  评论(0编辑  收藏  举报