文文殿下 快速傅利葉變換 FFT 學習筆記

2022-05-19 05:42:27 字數 4452 閱讀 6885

形如\(a(x)=\sum_^ a_i x^i\)的式子稱為多項式。

我們把\(n\)稱為該多項式的次數界。

顯然,乙個\(n-1\)次多項式的次數界為\(n\)。

設\(a(x)\)和\(b(x)\)為多項式,且次數界分別為\(n\),\(m\)。則有:

\(a(x)=\sum_^a_i x^i\)

\(b(x)=\sum_^b_i x^i\)

他們遵循下面的常用運算法則:

\(a(x)+b(x)=\sum_^ (a_i+b_i)x^i\)

\(a(x)-b(x)=\sum_^ (a_i-b_i)x^i\)

\(a(x)b(x)=\sum_^\sum_^a_i b_ x^k\)

兩個多項式的乘積稱為他們的卷積。卷積也是乙個多項式。

易證次數界分別為\(n\),\(m\)的多項式的卷積是乙個次數界為\(n+m-1\)的多項式。

用定義計算卷積的複雜度為\(o(n^2)\)

使用快速傅利葉變換,可以使複雜度降為\(o(nlogn)\)

形如\(a+bi\)形式的數稱為複數。其中\(i\)是\(\sqrt\)

我們可以使用平面上的點\((a,b)\)來描述乙個複數。

複數的運算法則和向量相似。

除了上文提到的代數形式,也有一種三角形式來表示複數。

如圖所示。

我們知道複數\(a+bi\)對應著平面上的點\((a,b)\),也對應著復平面上的乙個向量。

這個向量的長度叫做複數\(a+bi\)的模,記作\(|a+bi|\),通常用小寫字母\(r\)表示。

這個向量與\(x\)正半軸有乙個夾角,稱為輻角,我們用希臘字母\(\theta\)表示。

顯然有\(a=r\cos\theta\),\(b=r\sin\theta\)

把上式帶入到代數表示式,可以得到\(a+bi=r\cos\theta+ir\sin\theta=r(\cos\theta+i\sin\theta)\)

定理:兩複數相乘,模長相乘,輻角相加。

證明:設\(z_1=r_1(\cos x+i\sin x)\),\(z_2=r_2(\cos y+i\sin y)\).

則\(z_1 z_2=r_1 r_2 [\cos x\cos y-\sin x\sin y+i(\cos x\sin y+\cos y\sin x)]=r_1 r_2[\cos(x+y)+i\sin(x+y)]\)

尤拉公式:\(e^=\cos\theta+i\sin\theta\)

證明:將\(e^x\),\(\sin x\),\(\cos x\)按照泰勒展開得到他們的泰勒級數:

\(e^x=1+\frac+\frac+\frac+…\)

\(\cos x=1-\frac+\frac-\frac+…\)

\(\sin x=x-\frac+\frac-\frac\)

將\(x=i\theta\)帶入得:

\(e^=1+\theta i-\frac-\fraci+\frac+\fraci-\frac-\fraci+…\)

\(e^=(1-\frac+\frac-\frac+…)+i(\theta-\frac+\frac-\frac+…)\)

即\(e^=\cos\theta+i\sin\theta\)

將尤拉公式帶入到三角形式的表示式中就能得到複數的指數形式表示式:\(z=r(\cos\theta+i\sin\theta)=re^\)

在複數域內,有且僅有\(n\)個數,使得這個數的\(n\)次方等於1,我們把這樣的數稱為單位複數根,記作\(\omega_^ (i\epsilon [0,n-1])\)

把\(\theta=2\pi\)帶入尤拉公式,得\(e^=1\)

所以\(\omega_^=(e^})^k\)

消去引理:\(\omega_^=\omega_^\)

證明:\(\omega_^=(e^})^=(e^})^k=\omega_^\)

折半引理:\((\omega_^)^2=\omega_^\)

證明:將\(d=\frac \)帶入消去引理

求和引理:\(\sum_^ (\omega_^)^i=0\) (\(k\)不是\(n\)的倍數)

證明:利用等比數列求和公式,原式等於\(\frac^)^n-1}^-1}=\frac^-1}\)

因為分母不能為0,所以\(\omega_^\)不等於\(1\),所以\(k\)不是\(n\)的倍數.

迴圈性質:\((\omega_^)^p=\omega_^=\omega_^)}\)

證明:\(\omega_^=\omega_^ \right \rfloor n)}=\omega_^\)

對稱性質:\(w_^}=-w_^\)

證明:\(w_^}=e^+\pi i}=w_^ e^=-w_^\)

開頭提到的多項式,都是用係數表達法來表示的。

也就是將次數界為\(n\)的多項式的係數\(a_0,a_1,…,a_\)看成\(n\)維向量\(\vec=(a_0,a_1,…,a_)\),\(\vec\)稱作多項式\(a(x)\)的係數表示。

事實上,除了係數表示\(a(x)=\sum_^a_i x^i\)還有一種表示方法:點值表示法。

乙個次數界為\(n\)的多項式,就是\(n\)的點值對組成的集合。\((x_0,y_0),(x_1,y_1),…,(x_,y_)\) .對於\(0<=k<=n-1\),所有的\(x_k\)各不相同,記作\(y_k=a(x_k)\)

而離散傅利葉變換就是要快速求出多項式在這\(n\)的點的值

cooley-tukey演算法是一種基於分治的演算法

們取\(n\)個\(n\)次單位根 \(w_^,w_^,…,w_^\) 進行求值:\(a(w_^)=\sum_^a_i w_^\)

向量\(\vec=(a(w_^),…,a(w_^))\)稱作\(\vec=(a_0,…,a_n-1)\)的離散傅利葉變換

接下來我們按照奇偶分開來算:

\(a(w_^)=\sum_^a_i w_^\)

\(=\sum_^-1}a_w_^+w_^\sum_^-1}a_w_^\)

\(=\sum_^-1}a_w_}^+w_^\sum_^-1}a_w_}^\) (折半引理)

而\(a(w_^})=\sum_^-1}a_w_}^-w_^\sum_^-1}a_w_}^\)(對稱性質)

這樣問題就變成了求\(\frac\)個單位根的點值,問題的規模縮小了一半,所以是\(o(nlogn)\)的。

對於乙個多項式,如果知道它的係數表示式,我們很容易求出它的點值表示式,這一過程成為求值

如果知道它的點值表示式,讓你求它的係數表示式,這一過程稱為插值

定理:當插值多項式的次數界等於已知點值對的數目時,插值才是明確的

證明:\(y_k=a(x_k)\)等價於

其中,左邊的矩陣稱為範德蒙矩陣,其行列式\(det=\prod_=w_^\)

它們相乘的結果\(e=dv\)滿足\(e_=\sum_^w_^\)

當\(i=j\)時,\(e_=n\)

當\(i\neq j\)時,\(e_=\sum_^(w_^)^k=0\)(求和引理)

所以\(\fracd\)就是我們要求的逆矩陣,如下圖:

這就相當於我們把單位複數根\(w^_\)換成\(w^_\)再做一遍離散傅利葉變換結果除以\(n\)就行了

#include#include#include#includeconst int maxn = 1200000;

const double pi = acos(-1.0);

struct complex

complex(){};

};complex operator + (complex a,complex b)

complex operator - (complex a,complex b)

complex operator * (complex a,complex b)

int n,m,l[maxn],r[maxn];

complex a[maxn<<1],b[maxn<<1];

inline void read(int &x)

}inline void read(double &x)

}void fft(complex *a,int n,int inv)

j+=k;

}for(register int j=2;j<=n;j<<=1) }}

if(inv==-1) for(register int i=0;i

}int ans[maxn<<1];

int main()

fft(a,limit,-1);

for(register int i=0;i<=m+n;i++) printf("%llu ",(unsigned long long int)(a[i].r));

return 0;

}

快速傅利葉變換FFT

fft的作用就不多說了,搞訊號處理的人都會用上。fft的由來 傅利葉變換ft 離散傅利葉變換dft 快速傅利葉變換fft。學習資料 1 陳後金的 數字訊號處理 裡面深入淺出,該有的公式都有,程式設計思想也有。2 一篇系統講述傅利葉變換的帖子 3 學生對fft的理解 4 工程人員對fft的簡單明瞭的總...

快速傅利葉變換 FFT

bzoj 2179 fft快速傅利葉 果題 bzoj2194 請計算c k sigma a i b i k 其中 k i n 並且有 n 10 5。a,b中的元素均為小於等於100的非負整數。注意到i 和 i k有奇妙的聯絡 不妨嘗試把b翻轉 然後就變成卷積了。貼個模板 include define...

快速傅利葉變換 FFT

首先說一下我用fft做什麼,我要做的是多項式乘法,或者說,加速多項式乘法。考慮多項式a x j 0n 1aj xj,它一共有 n 項,我們稱它的次數界為 n。假設我們有兩個次數界為 n 的多項式a x 和b x 要求它們的和是非常簡單的,只需要將對應的係數相加,複雜度為o n 如果要求他們的積,則需...