係數表示法: a(
x)=∑
n−1j
=0aj
xj點值表示法: (x
0,y0
),(x
1,y1
),..
.,(x
n−1,
yn−1
)
n次單位復根,滿足條件wn
=1,可得w=
e2πi
k/n n次單位複數根滿足一些基本性質:
對於多項式a(x),計算它在n個n次單位複數根處的值,即可求出其離散傅利葉變換(dft)。所以我們求其在n個n次單位複數根處的點值表示式,也相當於對其進行一次離散傅利葉變換。而使用其離散傅利葉變換得到的點值表示式能很方便地在o(n)的時間內計算得到多項式乘法結果。
所以整個演算法的過程即: fft->點值乘法->逆fft
對於多項式a(
x),定義 a[
0](x
)=a0
+a2x
+a4x
2+..
.+an
−2xn
/2−1
a[1](x)
=a1+
a3x+
a5x2
+...
+an−
1xn/
2−1
那麼 a(x
)=a[
0](x
2)+x
a[1]
(x2)
所以,求a(x)在w0
n,w1
n,..
.,wn
−1n 的值的問題被轉化為求次數界為n/2的a[
1](x
) 和a[
0](x
) 在點(w
0n)2
,(w1
n)2,
...(
wn−1
n)2 ,這裡實際上僅有n/2個不同值,此時問題規模被縮小了一半。
而計算逆fft時,只需根據aj
=1/n
∑k=0
n−1y
kw−k
jn即可
這裡使用一段引自別人部落格的**(#
const double eps(1e-8);
typedef long long lint;
const double pi = acos(-1.0);
struct complex
complex(){}
};complex operator + (const complex &c1, const complex &c2)
complex operator - (const complex &c1, const complex &c2)
complex operator * (const complex &c1, const complex &c2)
int rev(int id, int
len)
return ret;
}//當dft= 1時是dft, dft = -1則是逆dft
complex* iterativefft(complex* a, int
len, int dft)//對長度為len(2的冪)的陣列進行dft變換}}
if(dft ==-1) for(int i =0; i < len; i++) a[i].real /= len, a[i].image /= len;
return a;
}
快速傅利葉
參考 ae 97 e6 b3 95 e5 ad a6 e4 b9 a0 e7 ac 94 e8 ae b0 hdu大整數乘法 include include include include include using namespace std const double pi acos 1.0 複數...
FFT 快速傅利葉演算法 for java
package com.test.test2 public class fft bitreverse i reve double theta,dt 2 3.14159265358979323846 fft n for i 0 i fft n 1 i 用於頻譜顯示的快速傅利葉變換 param real...
快速傅利葉(FFT)
快速傅利葉 更加形象的理解傅利葉變換 大概了解之後 從傅利葉級數到傅利葉變換 太大,只能裁剪為兩張 刨根問底的同學 雷德演算法 輸出序列是按自然順序排列的,而輸入序列的順序則是 位元反轉 方式排列的。也就是說,將序號用二進位制表示,然後將二進位制數以相反方向排列,再以這個數作為序號。如011變成11...