加载中...

快速傅里叶变换学习笔记

快速傅里叶变换

学习这个很久了,由于网上没有为初学者写的详细的教程,走了很多弯路。特此写一篇文章。特此写一篇文章。

考虑两个多项式\(\displaystyle f(x)=\sum_{i=0}^{n}a_ix^i,g(x)=\sum_{i=0}^{n}b_ix^i\),如果我们得到他们的卷积\(h=f*g\),直接用系数表示进行计算的话,时间复杂度为\(\mathcal O(n^2)\)的。因此,我们考虑用点值表示法。也就是说,如果我们知道

\[\mathcal f(x)=\{(x_1,y_1),(x_2,y_2)\cdots(x_n,y_n)\} \]

\[g(x)=\{(x_1,y'_1),(x_2,y'_2)\cdots(x_n,y'_n)\} \]

就可以得到

\[\mathcal h(x)=\{(x_1,y_1y'_1),(x_2,y_2y'_2)\cdots(x_n,y_ny'_n)\} \]

这样做就变成\(\mathcal O(n)\)了。

那么现在问题变成了如何求得\(f\)的点值表示?这里我们就需要用到快速傅里叶变换。我们考虑对\(f(x)\)进行变形 ,为了叙述方便,我们假设多项式的项数\(n\)满足\(n=2^k-1,k\in\mathbb{Z}\),不足的项系数为\(0\)

\[f(x) =\sum_{i=0}^{n}a_ix^i\\ f(x)= \sum_{i=0}^{\frac{n-1}{2}}a_{2i+1}x^{2i+1}+\sum_{i=0}^{\frac{n-1}{2}}a_{2i}x^{2i}\\ f(x)=x\sum_{i=0}^{\frac{n-1}{2}}a_{2i+1}x^{2i}+\sum_{i=0}^{\frac{n-1}{2}}a_{2i}x^{2i} \]

我们假设

\[\mathcal G(x)= \sum_{i=0}^{\frac{n-1}{2}}a_{2i+1}x^{2i}\\ \mathcal H(x)=\sum_{i=0}^{\frac{n-1}{2}}a_{2i}x^{2i} \]

那么有

\[f(x)=x\mathcal G(x^2)+\mathcal H(x^2) \]

假设\(\mathcal \omega_n\)为单位复根,即\(\mathcal \omega_n\)满足

\[\mathcal \omega_n^n=1 \]

那么有

\[{\rm DFT}(f(\mathcal \omega_n^k))= \omega_n^k{\rm DFT}(\mathcal G(\mathcal \omega_n^{2k}))+{\rm DFT}(\mathcal H(\mathcal \omega_n^{2k}))\\ {\rm DFT}(f(\mathcal \omega_n^k))=\mathcal \omega_n^k{\rm DFT}(\mathcal G(\mathcal \omega_{\frac n2}^{k}))+{\rm DFT}(\mathcal H(\mathcal \omega_{\frac n2}^{k})) \]

同理

\[{\rm DFT}(f(\mathcal \omega_n^{{\frac n2}+ k}))=\mathcal \omega_n^k{\rm DFT}(\mathcal G(\mathcal \omega_{n}^{2k+n}))+{\rm DFT}(\mathcal H(\mathcal \omega_n^{2k+n}))\\ {\rm DFT}(f(\mathcal \omega_n^{{\frac n2}+ k}))=-\mathcal \omega_n^k{\rm DFT}(\mathcal G(\mathcal \omega_{\frac n2}^{k}))+{\rm DFT}(\mathcal H(\mathcal \omega_{\frac n2}^{k})) \]

至此,我们完成了计算。一共\(\mathcal O(\log n)\)层,每层处理\(\mathcal O(n)\),时间复杂度\(\mathcal O(n\log n)\)

posted @ 2022-03-28 15:23  ZQYang  阅读(72)  评论(0)    收藏  举报