模板:快速傅里葉變換(FFT)

參考:http://blog.csdn.net/f_zyj/article/details/76037583
若是公式炸了請去個人csdn博客:http://blog.csdn.net/luyouqi233/article/details/79323568
原文便是一篇很好的FFT入門博客,可是筆者打算爲了往後的學習,則將原篇章的結構刪改增添一下,若有思路上的雷同十分正常。
「是時候打開FFT的大門了!」
html

預備知識:

1.至少知道基礎數論與必定解三角形知識(大概是高中水平)。
2.定義\(i=\sqrt{-1}\)
3.引入複數(即形如\(a+bi\)(a,b均爲實數)的數的集合)
4.\((cos\theta+i\times sin\theta)^k=cos(k\theta)+i\times sin(k\theta)\)
5.顯然咱們對多項式FFT以後獲得的答案不是咱們想要的,那麼這時候就須要反着用FFT把式子再變回去(本文記作IFFT)。算法

這裏證實一下第四條,用概括法。
顯然當\(k=1\)時成立。
\(k\)成立時,咱們有:
\((cos\theta+i\times sin\theta)^{k+1}\)
\(=(cos\theta+i\times sin\theta)^k\times (cos\theta+i\times sin\theta)\)
\(=(cos(k\theta)+i\times sin(k\theta))\times (cos\theta+i\times sin\theta)\)
\(=cos(k\theta)cos\theta+i\times sin(k\theta)cos\theta+i\times cos(k\theta)sin\theta+i^2\times sin(k\theta) sin\theta\)
\(=cos(k\theta)cos\theta-sin(k\theta) sin\theta+i\times (sin(k\theta)cos\theta+cos(k\theta)sin\theta)\)
\(=cos((k+1)\theta)+i\times sin((k+1)\theta)\)
得證。函數

問題引入:

\(A(x)=\sum_{i=0}^{n-1}a_ix^i,B(x)=\sum_{i=0}^{n-1}b_ix^i\),求\(A(x)\times B(x)\)後的多項式係數。學習

初探:

顯然咱們有一個\(O(n^2)\)的解法,可是實在是太慢了。
考慮到一個\(n-1\)次多項式能夠看作是定義在複數域上的函數,則咱們必定能夠找到n個點來惟一肯定這個函數。
固然咱們也能夠經過這些點來表示這個多項式。
假設:
\(A(x)\)被表示爲:\(<(x_0,y_{a_0}),(x_1,y_{a_1}),\ldots,(x_{2n-2},y_{a_{2n-2}})>\)
\(B(x)\)被表示爲:\(<(x_0,y_{b_0}),(x_1,y_{b_1}),\ldots,(x_{2n-2},y_{b_{2n-2}})>\)
顯然\(A(x)\times B(x)\)被表示爲:\(<(x_0,y_{a_0}y_{b_0}),(x_1,y_{a_1}y_{b_1}),\ldots,(x_{2n-2},y_{a_{2n-2}}y_{b_{2n-2}})>\)優化

這裏多取了點的緣由在於\(A(x)\times B(x)\)是一個\(2n-2\)次多項式,則至少要取\(2n-1\)個點才能保證正確。spa

可是顯然仍是\(O(n^2)\)的。.net

再試:

考慮設\(A(x_i)=A_0(x_i^2)+x_iA_1(x_i^2)\),其中:
\(A_0(x)=a_0+a_2x+a_4x^2+\ldots+a_{n-2}x^{\frac{n}{2}+1}\)
\(A_1(x)=a_1+a_3x+a_5x^2+\ldots+a_{n-1}x^{\frac{n}{2}+1}\)htm

其實就是按照係數下標的奇偶性分類了一下。blog

此時咱們再令取點的\(x\)值爲\(<x_0,x_1,\ldots,x_{\frac{n}{2}-1},-x_0,-x_1,\ldots,-x_{\frac{n}{2}-1}>\)
咱們發現把\(x\)平方後咱們的取值瞬間縮小了一半,而原式惟一變化的就是\(A_1(x)\)前的符號。
看起來咱們彷佛找到了\(O(nlogn)\)的可行方案。
可是很惋惜,這樣優秀的\(x\)取值的性質只會保留一次,也就是說咱們只是獲得了一個\(O(\frac{n^2}{2})\)
如何才能每次將問題的規模縮小一半是咱們的目標。遞歸

插曲:

有我的告訴你:不如試試\(X_n=cos\frac{2\pi}{n}+i\times sin\frac{2\pi}{n}\)\(0\ldots n-1\)次方做爲\(x\)的取值。

這塊你們一直有個疑惑:這是怎麼構造出來的啊?
事實上傅里葉變換最先是應用於信號處理上的,傅里葉提出:任何連續週期信號能夠由一組適當的正弦曲線組合而成。
多項式能夠看作非連續週期信號,而後經過各類奇妙的姿式讓它逼近正弦曲線的組合形,詳情能夠看鬆鬆鬆WC2018的課件。
「逼近」顯然用到了微積分,不適合初學者,因此就直接跳過了。(其實我也不會……)
(再多說一點吧,其實上面和下面的數學推理徹底能夠從物理層面理解,仍是能夠參考鬆鬆鬆WC2018的課件)

繼續:

那麼令取點的\(x\)值爲\(<X_n^0,X_n^1,\ldots,X_n^{n-1}>\)
咱們可知:
\((X_n^{k})^2\)

\(=X_n^{2k}\)

\(=cos\frac{2k\times 2\pi}{n}+i\times sin\frac{2k\times 2\pi}{n}\)

\(=cos\frac{2k\pi}{\frac{n}{2}}+i\times sin\frac{2k\pi}{\frac{n}{2}}\)

\(=X_{\frac{n}{2}}^k\)


\(X_n^{k}\)

\(=cos\frac{k\times 2\pi}{n}+i\times sin\frac{k\times 2\pi}{n}\)

根據三角函數的週期性可知,\(k\)\(n\)取模顯然不會對答案形成影響。
因而咱們有\(X_n^{k}=X_n^{k\%n}\)

那麼顯然對於\(<(X_n^0)^2,(X_n^1)^2,\ldots,(X_n^{n-1})^2>\)

它等效於\(<X_{\frac{n}{2}}^0,X_{\frac{n}{2}}^1,\ldots,X_{\frac{n}{2}}^{\frac{n}{2}-1},X_{\frac{n}{2}}^0,X_{\frac{n}{2}}^1,\ldots,X_{\frac{n}{2}}^{\frac{n}{2}-1}>\)

咱們好像看到了\(O(nlogn)\)的曙光了。

尾聲:

顯然咱們能夠對\(x\)的取值折半,而後對於左右區間的\(x\)值遞歸下去便可。
Q1:誒等等,「再試」裏面的內容好像沒有應用上啊……

A1:那就轉化一下,其實咱們只須要求一個區間的\(A_0(x)\)\(A_1(x)\)值遞歸下去求\(A(x)\)便可。
也就是說其實咱們是獲得了:
\(<(A_0)_0,(A_0)_1,\ldots,(A_0)_{\frac{n}{2}-1},(A_1)_0,(A_1)_1,\ldots,(A_1)_{\frac{n}{2}-1}>\)

Q2:這好像是多此一舉……

A2:emmm……我說這個能夠用於常數優化你信嗎……
顯然\(A(X_n^k)=(A_0)_{k\%\frac{n}{2}}+X_n^k(A_1)_{k\%\frac{n}{2}}\)

取模是由於,不要忘了咱們的取值是由兩個同樣的左右區間合併在一塊兒的。

那麼咱們獲得了\(<A_0,A_1,\ldots,A_{n-1}>\)

(其中\(A_k=A(X_n^k)\)

咱們好像把這個序列的長度減小了一半誒!那天然是快了二倍啊。

不要忘了n要知足始終是2的倍數,因此n要取2的整數次冪,同時將沒用的次冪的係數填成0。

Q3:IFFT怎麼作啊?

A3:繼續看下去……?

補遺:

略講一下IFFT。
顯然咱們能夠把FFT的最初算法(也就是DFT)看作兩個矩陣相乘。

兩個矩陣分別一個填\((X_n^k)^m\),一個填係數,能夠上參考處原博客看矩陣。

那麼咱們把第一個矩陣變成逆矩陣豈不是爲IFFT?
其實就是這樣,而且事實上就是填\(((X_n^{-k})^m)/n\),具體證實過程看參考處原博客。
剩下的作法就和FFT同樣啦。

謝幕:

事實上我上述講的內容其實沒有多少用(滑稽。
由於你理解半天也不如不理解知道怎麼用而後默寫下來。
可是理解了更好背啊。

例題:

模板:
HDU1402:A * B Problem Plus:http://www.cnblogs.com/luyouqi233/p/8448969.html

應用:
BZOJ3527:[ZJOI2014]力:http://www.cnblogs.com/luyouqi233/p/8452117.html

+++++++++++++++++++++++++++++++++++++++++++

+本文做者:luyouqi233。               +

+歡迎訪問個人博客:http://www.cnblogs.com/luyouqi233/+

+++++++++++++++++++++++++++++++++++++++++++

相關文章
相關標籤/搜索