FFT 快速傅里葉變換學習筆記
前言
由於老呂以及 dsr 巨巨的講解,將FFT學習了一下可能以后很大幾率都用不到,為了防止自己忘了,趁自己還有點記憶總結一下,可能理解的不深,或有錯誤,請不吝賜教。
定義
快速傅里葉變換 (fast Fourier transform), 即利用計算機計算離散傅里葉變換(DFT)的高效、快速計算方法的統稱,簡稱FFT。快速傅里葉變換是1965年由J.W.庫利和T.W.圖基提出的。采用這種算法能使計算機計算離散傅里葉變換所需要的乘法次數大為減少,特別是被變換的抽樣點數N越多,FFT算法計算量的節省就越顯著。 ——源自百度百科
多項式
FFT主要是用於加速求兩個多項式相乘的過程。
多項式:通俗來講就是有很多項的式子。
一個 \(n\) 項式,形如:
\(f(x)=a_0+a_1x+a_2x^2+a_3x^3+\dots + a_nx^n\)
也可以寫成
\(f(x)=\sum\limits^n_{i=0}a_i\times x^i\)
多項式的表示法
我們去表示一個多項式,或者說去求解一個多項式,主要有兩種方法。
-
系數表示法
這是我們平時最常見的表示多項式的方法。就比如說我們上面的栗子。
如果我們要用系數表示的多項式計算乘積,如 \(f(x)\times g(x)\) ,想象一下,第一個多項式的每一項都要乘上第二個多項式的每一項,這樣的復雜度是 \(O(n)\) 的。
-
點值表示法
一個 \(n\) 次的多項式,可以由 \(n\) 個點確定。比如說 \(y(x)=a_0+a_1x+a_2x^2+a_3x^3+\dots + a_nx^n\),就可以由 \(n\) 個點來表示,分別為 \((x_1,y_1),(x_2,y_2),(x_3,y_3),\dots,(x_n,y_n)\) 。
這樣我們計算 \(f(x)\times g(x)\) 也是 \(O(n)\) 的。
從 \(f(x),g(x)\) 中選出我們要求的 \(n\) 個點(也就是我們每次帶入一個 \(x_i\),用給出的函數求出 \(y_i\)),然后求出對應的乘積,也就是在相乘函數中對應的值,這樣做的復雜度是 \(O(n)\) 的。但是一般題目可能會讓我們輸出系數表示法,所以我們需要將點值表示法轉成系數表示法,但是點值表示法轉換成系數
是 \(O(n^2)\) 的,所以說復雜度還是 \(O(n^2)\) 的。
系數表示法的復雜度不好優化,而點值表示法是 \(O(n)\) 的,所以我們考慮去優化轉化的過程。
復數
一些定義
以下為數學范圍內的知識,學過的可跳過。
我們定義 \(i\) 為虛數單位, \(i^2=-1\)。
初中的時候,解方程我我們總是說在實數范圍內有解或無解。
例如:\(x^2+2x+3=0\)
對於這種方程,我們總是說在實數范圍內無解,而在復數范圍內,這個方程式有解的。
我們把形如 \(a+bi\) 的數叫復數,其中 \(a,b\in R\)(實數)。
在復平面中,\(x\) 軸代表實數,\(y\) 軸代表虛數,從原點到 \((a,b)\) 向量表示復數 \(a+bi\)。
我們在復平面內,將復數對應到向量上,向量與 x 軸正半軸的夾角為 \(\alpha\) ,此時復數可以表示為
\(r(\cos\alpha+i\sin\alpha)\)

模長:從原點到 \((a,b)\) 的距離,\(\sqrt{(a-0)^2+(b-0)^2}\)。
幅角:以逆時針為正方向,從 \(x\) 軸正半軸到已知向量的轉角的有向角叫做幅角。
運算法則
大致了解一下運算規律就行。
加
\((a+bi) \ \ + \ \ (c+di) = (a+c)+(b+d)i\)
減
\((a+bi)\ \ - \ \ (c+di)=(a-c)+(b-d)i\) (加法的逆運算)
乘
代數式:
三角形式:
也就是模長相乘,幅角相加。這里比較重要。
除
代數式:
三角形式:
雖然FFT中不用復數除法。
單位根
定義
在單位圓中,以圓點為起點,圓的 \(n\) 等分點為終點,做 \(n\) 個向量,設幅角為正且最小的向量對應的復數為\(\omega_n\),稱為 \(n\) 次 單位根。
\(\omega_n^k\) 表示 \(k\) 份 \(\omega_n\) 。易得,\(\omega_n^n=\omega_n^0=1\) ,\(\omega_n^{\frac{1}{2}}=-1\)(\(n\) 為偶數)。
性質
-
歐拉公式:
\(e^{ix} = \cos(x)+i \times \sin(x)\)
帶入
\(\omega_n^k = \cos(k\times\frac{2\pi}{n})+i\times \sin(k\times\frac{2\pi}{n})\)
-
\(\omega _{2n}^{2k}=\omega _{n}^{k}\)
-
\(\omega _{n}^{k+\frac{n}{2}}=-\omega _{n}^{k}\)
-
\((\omega_n^k)^2=\omega_n^{2k}\)
-
\(\omega_n^{k+n}=\omega_n^k\)
FFT
考慮一個多項式 \(A(x)\) 求它的 DFT
當 \(k\leq \frac{n}{2}\)
當 \(k> \frac{n}{2}\)
我們發現,當 \(k>\frac{n}{2}\) 的時候,與 \(k\leq \frac{n}{2}\) 的時候就相差了一個符號,當我們求出 \(k\leq \frac{n}{2}\) 中的數值時,就可以推出 \(k>\frac{n}{2}\) 的值,因此我們只用計算 \(k\leq\frac{n}{2}\) 的時候就可以了。
看圖可以看出我們每次都是一個遞歸的過程,然后進行大眼觀察法,觀察我們遞歸后的東西。
變化前 | 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 |
---|---|---|---|---|---|---|---|---|
000 | 001 | 010 | 011 | 100 | 101 | 110 | 111 | |
變化后 | 0 | 4 | 2 | 6 | 1 | 5 | 3 | 7 |
000 | 100 | 010 | 110 | 001 | 101 | 011 | 111 |
剩下的先咕了,以后再補,圖好像也掛了