FFT 学习笔记
1.多项式与卷积
1.1 多项式
对于多项式 \(F(x)=a_0+a_1x+a_2x^2+a_3x^3+\dots+a_nx^n\),我们称 \(a_0,a_1,\dots,a_n\) 为它的系数,这种表示法叫做系数表示法。
定义 \(F(x)\) 的 \(n\) 次项系数为 \(f_n\)。
我们有:
\[F(x)=\sum_{i=0}^nf_ix^i \]1.2 卷积
考虑两个多项式进行乘法,即\(P(x)=F(x)G(x)\),有 \(p_k=\sum_{i=0}^kf_ig_{k-i}\),也可写作 \(p_k=\sum_{i+j=k}f_ig_j\)。
事实上,形如 \(P[k]=\sum_{i\oplus j=k}f_ig_j\) 的操作叫做卷积,\(\oplus\) 为任意运算。
多项式乘法为 \(\oplus\) 取 \(+\) 的操作,即加法卷积,暴力进行的时间复杂度为 \(O(n^2)\)。
2.DFT 思想
有定理:平面上的 \(n+1\) 个点唯一确定一个 \(n\) 次多项式(常见应用是待定系数法和拉格朗日插值公式)。于是我们可以用点值的方法表示一个多项式,这被称作点值表示法。
对于两个多项式相乘,我们可以直接将它们对应点的点值相乘。对于两个次数为 \(n\) 的多项式,我们只需要取 \(2n+1\) 个点相乘即可,时间复杂度为 \(O(n)\),优于暴力卷积的 \(O(n^2)\)。
DFT(离散傅里叶变换)所做的就是将一个多项式的系数表达法转换为点值表示法。
但是我们取的点是什么呢?
3.复数和单位圆
3.1 复数
定义 \(i^2=-1\),这里 \(i\) 被称作虚数单位。
复数可以记为 \(a+bi\),\(a\) 称作实部,\(b\) 称作虚部。
虚数没有大小和正负之分。注意:部分实数的运算公式不能拓展到复数。
定义虚部互为相反数的复数为共轭复数。
虚数的基本运算如下:
-
加减法:实部、虚部分别相加。如:\((a+bi)\pm(c+di)=a\pm c+(b\pm d)i\)。
-
乘法:当做一次多项式相乘即可。如:\((a+bi)\times (c+di)=ac-bd+(ad+bc)i\)。
-
除法:同乘分母的共轭复数。如:\(\dfrac{a+bi}{c+di}=\dfrac{(a+bi)(c-di)}{(c+di)(c-di)}=\dfrac{ac+bd+(bc-ad)i}{c^2+d^2}\)
我们同时注意到复数的几何含义:我们可以用数对 \((a,b)\) 来表示复数 \((a+bi)\),事实上,复数 \(a+bi\) 所对应的是平面直角坐标系上横坐标为 \(a\),纵坐标为 \(b\) 的点。
定义一个虚数 \(a+bi\) 的模长为 \(\sqrt{a^2+b^2}\),即其到原点的距离,幅角为与 \(x\) 轴形成的夹角。
有定理:复数相乘,模长相乘,幅角相加。
首先证明模长相乘:
证明:
设两个复数分别为 \(a+bi\) 和 \(c+di\),则它们的模长分别为 \(\sqrt{a^2+b^2}\) 和 \(\sqrt{c^2+d^2}\),相乘后的模长为 \(\sqrt{a^2c^2+a^2d^2+b^2c^2+b^2d^2}\)。
\((a+bi)(c+di)=ac-bd+(ad+bc)i\) ,其对应点的坐标为 \((ac-bd,ad+bc)\)。其模长为 \(\sqrt{(ac-bd)^2+(ad+bc)^2}\),展开即为 \(\sqrt{a^2c^2+a^2d^2+b^2c^2+b^2d^2}\),证毕。
然后证明幅角相加。
如图,\(B=3+2i,C=1+4i,D=BC=-5+14i\)。
有 \(AD:AB=AC,AC:AE=AC\) 我们通过两点之间距离公式可以证明 \(DC:EB=AC\),即可得到 \(\triangle AEB\backsim\triangle ACD\),进而证明幅角相加。
3.2 单位圆
定义单位圆是平面直角坐标系上一个圆心为原点,半径为 \(1\) 的圆。
求方程 \(x^n=1\) 的所有复数解,不难发现,其所有解都在单位圆上。这些解对应着分别是幅角为 \(0,\dfrac{1}{n},\dfrac{2}{n},\dots,\dfrac{n-1}{n}\) 圆周的点,此时正好对应着 \(0,1,2,\dots,n-1\) 倍圆周。我们将这些点称作单位根,表示为 \(\omega_n^1,\dots,\omega_n^{n-1}\)。由代数基本定理:\(n\) 次方程恰有 \(n\) 个复数根,可知这就是原方程的所有根。
单位根有如下性质:
-
\(\omega^{2k}_{2n}=\omega^k_n\)。
感性证明:把单位圆等分成 \(2n\) 份取 \(2k\) 份等价于等分成 \(n\) 份取 \(k\) 份。
-
\(\omega_n^{k+\frac{n}{2}}=-\omega^k_n\)。
感性证明:转动半周即关于原点对称。
4.FFT
设 \(F(x)=f_0+f_1x+f_2x^2+\dots+f_{n-1}x^{n-1}\),为方便计算,这里使 \(n=2^k\)。
我们可以按照奇偶将 \(F(x)\) 分为 \(A(x)\) 和 \(B(x)\),其中,\(A(x)=f_0+f_2x+\dots+f_{n-2}x^{\frac{n}{2}-1}\),\(B(x)=f_1+f_3x+\cdots+f_{n-1}x^{\frac{n}{2}-1}\)。
这样,我们有:
\[F(x)=A(x^2)+xB(x^2) \]设 \(k<\dfrac{n}{2}\),将 \(\omega^k_n\) 分别代入 \(F(x),A(x),B(x)\),则:
\[\begin{aligned} F(\omega^k_n)&=A((\omega^k_n)^2)+\omega^k_nB((\omega^k_n)^2)\\ &=A(\omega^k_{\frac{n}{2}})+\omega^k_nB(\omega^k_{\frac{n}{2}}) \end{aligned} \]代入 \(\omega^{k+\frac{n}{2}}_n\),则:
\[\begin{aligned} F(\omega^{k+\frac{n}{2}}_n)&=A((\omega^{k+\frac{n}{2}}_n)^2)+\omega^{k+\frac{n}{2}}_nB((\omega^{k+\frac{n}{2}}_n)^2) \\&=A(\omega^{2k}_n)+\omega^{k+\frac{n}{2}}_nB(\omega^{2k}_n) \\&=A(\omega^k_{\frac{n}{2}})-\omega^k_nB(\omega^k_{\frac{n}{2}}) \end{aligned} \]我们注意到:两个式子的结果仅存在一个正负号的差异,这就也意味着,我们若知道两个多项式 \(A(x),B(x)\) 在 \(\omega^0_{\frac{n}{2}}\) 至 \(\omega^{\frac{n}{2}-1}_{\frac{n}{2}}\) 处的点值表示,我们就可以以 \(O(n)\) 的时间复杂度求出多项式 \(F(x)\) 在 \(\omega^0_n\) 至 \(\omega^{n-1}_n\) 处的点值表示。这个过程可以不断分治到 \(n=1\) 的情况,再逐层合并即可,这就是 FFT 的思想。
5.IDFT
我们为什么要将单位根代入式子?
设 \(G_{n}\) 表示多项式 \(F(x)\) 在经过 DFT 后的点值,有:
\[G_k=\sum^{n-1}_{i=0}(\omega^k_n)^if_i \]我们能够证明:
\[nf_k=\sum^{n-1}_{i=0}(\omega^{-k}_n)^ig_i \]证明:
\[\begin{aligned} &\sum^{n-1}_{i=0}(\omega^{-k}_n)^ig_i \\&=\sum^{n-1}_{i=0}\sum^{n-1}_{j=0}(\omega^i_n)^j(\omega^{-k}_n)^if_j \\&=\sum^{n-1}_{i=0}\sum^{n-1}_{j=0}(\omega^{i(j-k)}_n)f_j \end{aligned} \]当 \(j=k\) 时的贡献是:
\[\sum_{i=0}^{n-1}f_k=nf_k \]否则,当 \(j\neq k\) 时:
考虑式子 \(\sum^{n-1}_{j=0}(\omega^{i(j-k)}_n)\) 的贡献,由等比数列求和公式,我们有:
\[\sum^{n-1}_{j=0}(\omega^{i(j-k)}_n)=\omega^0_n\dfrac{1-\omega^n_n}{1-\omega^1_n}=0 \]故原式成立。证毕。
由此,我们只需要将多项式进行 DFT 后的点值代入单位根的相反数再进行一次 DFT,即可得到原多项式。
注:
\[\omega_n^1=(\cos\dfrac{2\pi}{n},\sin\dfrac{2\pi}{n}) \omega_n^{-1}=(\cos\dfrac{2\pi}{n},-\sin\dfrac{2\pi}{n}) \]6.FFT优化
6.1 三次变两次
计算 \(F(x)G(x)\),朴素的需要进行两次 DFT,一次 IDFT,共三次操作。
设 复数多项式\(P(x)=F(x)+G(x)i\),计算 \(P(x)^2=F(x)^2-G(x)^2+2F(x)G(x)i\)
注意到此时 \(P(x)\) 的虚部恰巧时答案的两倍,这样我们只需要一次 DFT 和一次 IDFT 共两次操作即可完成。
标签:frac,多项式,sum,FFT,bi,笔记,学习,dfrac,omega From: https://www.cnblogs.com/ChthollyNS/p/-/FFT-Basic