FFT - 快速傅里叶变换 - TEST
作者:互联网
FFT - 快速傅里叶变换
目录写在前面
该博客仅为个人对一些算法的理解与总结,不保证正确性,同时欢迎各位纠正。
目的
FFT (Fast Fourier Transform) 是为了为快速求出两个多项式的卷积,也就是 $ C(x) = A(x) \ast B(x) $ ,或者表达为
\[c(i) = \sum_{j = 0}^{i} a(j) \times b(i - j) \]( $ a(i), b(i), c(i) $ 为多项式系数 $ A(x), B(x), C(x) $ 为多项式 )
前置知识
原根
详细定义可参考 知乎 或 OI-WIKI,简而言之就是,对于模 $ m $ 意义下的原根 $ a $,有 $ a^1, a^2, \cdots, a^{\varphi(m)} \bmod m $ 的值各不相同,$ \varphi(m) $ 表示 欧拉函数 。
单位根
对于 $ \epsilon^n = 1 (\epsilon \neq 1)$,称 \(\epsilon\) 为 $ n $ 次单位根,其可以为模意义下的或复数意义下的。
对于模 $ m $ 意义下的, $ m $ 为质数,令原根为 $ g $ 则有 $ \gcd(g, m) = 1 $,此时若满足 $ n \mid m - 1 $ 则有 $ \epsilon = g^{\frac{m - 1}{n}} $。
证明:
\[&(g^{\frac{m - 1}{n}})^n &\equiv 1 \pmod{m}\\ \iff &g^{m - 1} &\equiv 1 \pmod{m}\\ \]由 费马小定理 可知显然成立
对于复数意义下的,则可将一单位圆 n 等分,并取该 n 个点表示的复数,从 x 轴,也就是从 $ (1, 0) $ 开始取,逆时针从 0 开始对这些复数进行编号,对于第 k 个复数记作 $ \epsilon_n^k $,则对于幅角非零且最小的复数 $ \epsilon_n^1 $,由复数相乘时模长相乘幅角相加可知一定有 $ (\epsilon_n1)k = \epsilon_n^k $,则称 $ \epsilon_n^1 $ 为 $ n $ 次单位根。
很多地方可能用 $ \omega $ 来表示单位根,也就是本文中的 $ \epsilon $,仅为表示方式的区别而已。
单位根性质
对于 $ n $ 次单位根有如下式子
\[(\epsilon^k)^2 = (\epsilon^{k + \dfrac{n}{2}})^2 \]证明
\[\begin{align}(\epsilon^{k + \dfrac{n}{2}})^2 &= (\epsilon^k)^2 \times \epsilon^2\\ &= (\epsilon^k)^2 \end{align} \]等比数列求和公式
\[S_n = a_1 \dfrac{1-q^n}{1-q} \]正文
单位根反演
对于 $ n $ 次单位根 $ \epsilon $,显然有如下的, $ a_1 = \epsilon^0 = 1 $, $ q = \epsilon^v $,的等比数列的求和为
\[\begin{align}\sum_{i = 0}^{n - 1} \epsilon^{vi} &= \dfrac{1 - \epsilon^{nv}}{1-\epsilon^v} (\epsilon^v \neq 1)\\ &= 0 \end{align} \]又有 $ n $ 次单位根性质可知 $ \epsilon^v = 1 $ 时,上式 $ = 1 $。
且又有如下式子
\[\epsilon^v = 1 \iff n \mid v \]综上则有如下式子
\[\dfrac{1}{n}\sum_{i = 0}^{n - 1}\epsilon^{vi} = \left\{ \begin{array}{ll} 0 & \quad n \nmid v\\ 1 & \quad n \mid v \end{array} \right. \]此即为单位根反演
推式子
将单位根反演代入原式,令 $ v = p + q - i $,则 $ n \mid v $,
且令
\[d(x) = \left\{ \begin{array}{ll} 0 & \quad p + q \not\equiv i \bmod{n}\\ 1 & \quad p + q \equiv i \bmod{n} \end{array} \right. \]显然有如下式子
\[&\begin{align} c(i) &= \sum_{j = 0}^i a(j) \times b(i - j)\\ &= \sum_p\sum_q a(p) \times b(q) \times d(x)\\ &= \sum_{p = 0}^{n - 1}\sum_{q = 0}^{n - 1} a(p) \times b(q) \times \dfrac{1}{n}\sum_{k = 0}^{n - 1}\epsilon^{k \times (p + q - i)}\\ &= \sum_{p = 0}^{n - 1} a(p) \sum_{q = 0}^{n - 1} b(q) \times \dfrac{1}{n} \sum_{k = 0}^{n - 1}\epsilon^{kp}\epsilon^{kq}\epsilon^{-ki}\\ &= \sum_{p = 0}^{n - 1} a(p)\epsilon^{kp} \sum_{q = 0}^{n - 1} b(q)\epsilon^{kq} \times \dfrac{1}{n} \sum_{k = 0}^{n - 1}\epsilon^{-ki}\\ \end{align}\\ \iff&n \times c(i) \sum_{k = 0}^{n - 1}\epsilon^{ki} = \sum_{p = 0}^{n - 1} a(p)\epsilon^{kp} \sum_{q = 0}^{n - 1} b(q)\epsilon^{kq} \]观察最后两个式子,可以发现如下两个式子
\[& c(i) = \sum_{p = 0}^{n - 1} a(p)\epsilon^{kp} \sum_{q = 0}^{n - 1} b(q)\epsilon^{kq} \times \dfrac{1}{n} \sum_{k = 0}^{n - 1}\epsilon^{-ki}\\ \iff&n \times c(i) \sum_{k = 0}^{n - 1}\epsilon^{ki} = \sum_{p = 0}^{n - 1} a(p)\epsilon^{kp} \sum_{q = 0}^{n - 1} b(q)\epsilon^{kq} \]考虑令该多项式上一点为 $ (\epsilon^p, f(p)) $,多项式第 $ p $ 项系数为 $ g(p) $,有
\[\begin{align} f(p) &= \sum_{i = 0}^{n - 1}\epsilon^{pi}g(i)\\ g(p) &= \dfrac{1}{n}\sum_{i = 0}^{n - 1}\epsilon^{-pi}f(i) \end{align} \]证明
\[//TODO \]则可知求 $ f(p) $ 的过程即为DFT,求 $ g(p) $ 的过程即为IDFT。
由定义显然有
\[DFT(C, i) = DFT(A, i) \times DFT(B, i) \]( $ A, B, C $ 均代表该多项式 )
又有
\[IDFT(DFT(C)) = C \]证明
\[//TODO \]则此时多项式 C 可求,但时间复杂度仍然是 $ O(n^2) $
继续推式子
对于
\[f(p) = \sum_{i = 0}^{n - 1}\epsilon^{pi}g(i) \]可以考虑 $ f(p) $ 与 $ f(p + 2^k) $ 的关系,则此时我们可以假设 $ n = 2^{k + 1} $
且令
\[d_1(x) = \left\{ \begin{array}{ll} 0 & \quad i \equiv 0 (\bmod{2})\\ 1 & \quad i \equiv 1 (\bmod{2}) \end{array} \right.\\ d_2(x) = \left\{ \begin{array}{ll} 1 & \quad i \equiv 0 (\bmod{2})\\ 0 & \quad i \equiv 1 (\bmod{2}) \end{array} \right. \]由单位根的性质可以得到以下式子
\[\begin{align}f(p + 2^k) &= \sum_{i = 0}^{n - 1}(\epsilon^{p + 2^k})^ig(i)\\ &= \sum_{i = 0}^{n - 1}(\epsilon^p)^ig(i)d_1(i) + \sum_{i = 0}^{n - 1}(\epsilon^p)^iug(i)d_2(i) \end{align} \]其中u为一个二次单位根,因为显然当且仅当 $ i $ 为奇数时,下式不为 $ 0 $。
\[\sum_{i = 0}^{n - 1}(\epsilon^p)^iug(i)d(i) \]$ i $ 为奇数时,可以有如下推导
\[\begin{align}\sum_{i = 0}^{n - 1}(\epsilon^{p + 2^k})^ig(i) &= \sum_{i = 0}^{n - 1}(\epsilon^p)^i\epsilon^{2^k}g(i)\\ \end{align} \]此时显然有
\[\begin{align}(\epsilon^{2^k})^2 &= \epsilon^{2^{k + 1}} \end{align} \]且我们已知 $ \epsilon $ 为 $ 2^{k + 1} $ 次单位根,所以显然有
\[\epsilon^{2^{k + 1}} = 1 \]所以 $ \epsilon{2k} $ 为二次单位根,这里为了方便,我们用 $ u $ 代替。
此时可以考虑令
\[f^{'}(p) &=& \sum_{i = 0}^{n - 1}(\epsilon^p)^ig(i)d_1(i)\\ f^{'}(p + 2^k) &=& \sum_{i = 0}^{n - 1}(\epsilon^p)^{i}g(i)d_2(i) \]所以将幂次除以二后,显然有(此时 $ \epsilon $ 应为 $ \dfrac{n}{2} $ 次单位根)
\[f^{'}(p) &=& \sum_{i = 0}^{\frac{n}{2} - 1}(\epsilon^p)^{i}g(i \times 2)\\ f^{'}(p + 2^k) &=& \sum_{i = 0}^{\frac{n}{2} - 1}(\epsilon^p)^{i}g(i \times 2 + 1) \]再将式子转化为
\[f^{'}(p) &=& \sum_{i = 0}^{n^{'}}(\epsilon^p)^{i}g_1(i)\\ f^{'}(p + 2^k) &=& \sum_{i = 0}^{{n^{'}}}(\epsilon^p)^{i}g_2(i) \]此时式子形式便可按相同方法继续递归,直到 $ n = 2 $ 时进行回溯。
Code
//TODO
优化
//TODO
写在后面
写完之后发现依然没有很清晰的弄明白,然后发现有几个Blog写的更清晰易懂
一小时学会快速傅里叶变换(Fast Fourier Transform)
至于几个TODO等以后再慢慢填坑吧
标签:epsilon,sum,FFT,单位根,times,TEST,傅里叶,align,式子 来源: https://www.cnblogs.com/tsawke/p/16572609.html