1。直接計算離散傅立葉變換具有n^2的複雜度,而cooley 和tukey在1965年發現了一種計算離散傅立葉變換的快速算法(即通
常所說的FFT算法),這個算法在計算變換長度n=2^k的離散傅立葉變換時,具有 n*k 的複雜度,即O(n)=n*log2(n), 下面以此
爲例,講講快FFT的特點。
1)複數運算:傅立葉變換是基於複數的,因此首先知道複數的運算規則,在FFT算法中,只涉及複數的加、減和乘法三種運
算。一個複數可表示爲 c=( x,yi), x 爲複數的實部,y爲複數的虛部,i爲虛數單位,等於-1的平方根。複數的運算規則是:
若c1 表示爲 (x1,y1),c2 表示爲(x2,y2), 則 (x1+x2,y1+y2)和(x1-x2,y1-y2)分別等於c1+c2的和,c1-c2的差,複數的乘法
相對複雜一些,c1*c2 的積爲 (x1*x2-y1*y2,x1*y2+x2*y1).
2)蝶形變換:普通的FFT算法稱爲基2的FFT算法,這種算法的核心是蝶形變換 長度爲n=2^k1的變換共需要做 k1 * n/2 次
蝶形變換,若需變換數據表示爲一個複數數組c[],則每次蝶形變換有2個輸入 c[i],c[i+s],兩個輸出:c[i],c[i+s],s成爲翅
間距。 每個變換的基本算法是:
t=wr * c[i+s];
c[i+s]=c[i]-t;
c[i]=c[i]+t;
前面說過,長度爲n=2^k1的變換共需要做 k1 *
n/2次變換,實際的程序是一個3層循環,共需要k1*k2*(k3/2)次變換(k2*k3/2=n/2)。前面的wr是w的整數次方,w=e^(-2*PI/k3
) (k3=2,4,8,16...n,PI是圓周率),也成爲旋轉因子,例如n=32的變換需要log2(32)=5趟變換:
第1趟變換需要16*1次變換,翅間距是1, 若w=e^(-2*PI/2), 則wr=w^1
第2趟變換需要8*2次變換, 翅間距是2, 若w=e^(-2*PI/4), 則wr=w^1,w^2
第3趟變換需要4*2次變換, 翅間距是4, 若w=e^(-2*PI/8), 則wr=w^1,w^2,w^3,w^4
第4趟變換需要2*8次變換, 翅間距是8, 若w=e^(-2*PI/16),則wr=w^1,w^2,w^3,w^4,w^5,w^6,w^7,w^8
第5趟變換需要16*1次變換,翅間距是16, 若w=e^(-2*PI/32),則wr=w^1,w^2,w^3,w^4,w^5...w^15,w^16
3)w數組,w 的實部=cos(2*PI/k3),w的虛部= -sin(2*PI/k3),計算出w,則wr數組就好求了,不斷即相乘即可,當然也可以通
過三角函數直接求。w^p 的實部=cos(2*PI/K3*p),虛部=-sin(2*PI/k3*p)
4)複數數組排序,在基2的蝶形變換中,複數數組需要重新排序,c[i] 要放置到數組c的第 reverse(c[i])
的位置,m=reverse(n) 函數的算法是這樣的,若 n的 k位2進制的爲b[], b[k-1],B[k-2],...b[2],b[1],b[0],( b[i] 等於1
或者0,b[0]爲最低bit). 則m=reverse(n)的2進制的爲 b[0],b[1],b[2],b[3],...b[k-1] (b[k-1]爲最低bit).
更復雜的變換算法:基2的蝶形變換算法不止一種,它可分爲2類,一類爲基2時分傅立葉變換,另一類爲基2頻分傅立葉變
換。上例的變爲基2時分算法,在每一趟變換中,翅間距依次變大,第一趟爲2,最後一趟爲n/2,數組重排在變換之前進行,基
2頻分算法正好相反,翅間距依次縮小,起於n/2,止於2,數組重排在蝶形變換之後進行。 在<傅立葉變換>一書中,提到3
種基2時分變換,3種基2頻分變換。上述算法稱爲基2時分FFT第二種算法。我在看你的這個程序的同時,還看到朱志剛寫的一
個FFT程序,這個程序的算法是基2時分FFT第一種算法,它比經典的算法更復雜,需要對wr數組進行逆序排列。
///這個程序不太直觀的地方。
在計算wp是,虛部使用sin函數直接計算,但是實部沒有直接計算,按照數學公式cos(x)=1-2*sin(x/2)^2,這裏,wpr只取-2*s
in(x/2),比實際值小1,故在計算w時,採用以下算式:
wr = wr * wpr - wi * wpi + wr;
wi = wi * wpr + wtemp * wpi + wi;
wr*wpr-wi*wpi+wr --> wr*(1+wpr)-wi*wpi,可以看到這裏將1重新補上了。
//更復雜的FFT算法,除了基2 的FFT算法外,還有更加複雜的基4算法,基8算法,甚至基3,基5算法,純粹的基4算法只能計算
長度爲4^k的變換,但它比基2的算法速度更高。爲了提高速度,很多FFT算法使用混合基算法。如我看到的2個效率很高程序均
使用了混合基算法。第一個程序是來自:http://momonga.t.u-tokyo.ac.jp/~ooura/fft.html,它使用了基2,基4,甚至基8混
合算法,共提供了6同樣功能的算法。可對長度爲2^k的序列做FFT,這個程序的寫的很複雜,我現在尚不能完全看懂。另一個
程序來自:http://hjem.get2net.dk/jjn/fft.htm。相對於前者,這個程序相對簡單一點。它使用了基2,基3,基4,基5,基8,
基10 混合算法,幾乎可以計算任意長度的FFT。具體的,當序列長度n爲2,3,5,7,11,13,17,19,23,29,31,37等小素數時,或
者n的最大素因數小於等於37時,可計算這個序列的FFT。
關於FFT算法的其它文檔:http://www.jjj.de/fxt/fxtbook.pdf, websuite: http://www.jjj.de/fxt/, 這是我見過的關於變換算法的最全面的文檔。