FFT 学习笔记

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\) 称作虚部。

虚数没有大小和正负之分。注意:部分实数的运算公式不能拓展到复数。

定义虚部互为相反数的复数为共轭复数。

虚数的基本运算如下:

  1. 加减法:实部、虚部分别相加。如:\((a+bi)\pm(c+di)=a\pm c+(b\pm d)i\)

  2. 乘法:当做一次多项式相乘即可。如:\((a+bi)\times (c+di)=ac-bd+(ad+bc)i\)

  3. 除法:同乘分母的共轭复数。如:\(\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\) 个复数根,可知这就是原方程的所有根。

单位根有如下性质:

  1. \(\omega^{2k}_{2n}=\omega^k_n\)

    感性证明:把单位圆等分成 \(2n\) 份取 \(2k\) 份等价于等分成 \(n\) 份取 \(k\) 份。

  2. \(\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 共两次操作即可完成。

posted @   ChthollyNS  阅读(15)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 分享一个免费、快速、无限量使用的满血 DeepSeek R1 模型,支持深度思考和联网搜索!
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· ollama系列01:轻松3步本地部署deepseek,普通电脑可用
· 25岁的心里话
· 按钮权限的设计及实现
点击右上角即可分享
微信分享提示