根據課本上分析的DIT和DIF的步驟以及特點,寫了兩個DIF和DIT的基2fft演算法。
DIT和DIF,為了方便編程,對於前者將輸入按倒位序重新排列,輸出幾位自然順序排列;後者的話,輸入為自然順序,輸出為倒位序。
痛點就是倒位序的演算法,以及FFT的迴圈演算法。
下面是最簡單的序列長度為2的整數冪
1.倒位序演算法,兩者都是通用的。
(1)折斷一半再拼上,再折斷一半再拼上,知道列向量變成行向量
這就反應了倒位序的實質。
我只能想到用迴圈:
x=[1:8]';
L=length(x);
for i=1:1:log2(L) L=L/2; y=mat2cell(x,[L,L]); y=reshape(y,1,2); x=cell2mat(y);end
詢問了大牛,不用迴圈,直接用matlab的函數有:
第一種方法:
N = 3;
a = (1:8)';
y = permute(reshape(a,2*ones(1,N)),N:-1:1);
y(:).' |
第二種方法:
N=4;
p(1:2^N,N:-1:1)=dec2bin(0:(2^N-1));
re=bin2dec(char(p))+1;
re |
第二種方法就是說,每一次折斷一半再拼上,就想等於下標數迴圈右移
即000=>000,001=>100,010=>010,011=>101....類似這樣。
(2)至於迴圈,就是利用相互之間的關係。
p與第幾級與k之間的關係,書上說,考慮到硬體的裝置成本問題,發現每一級每兩個相互乘積求和的下標與其他兩者無關,故不需要在引進其他的硬體裝置。
x(k)=x(k)+x(k+b)e^(-j*2*π/N*p);
x(k+b)=x(k)-x(k+b)e^(-j*2*π/N*p);
在編程的時候注意x(k)需要重新賦給其他字母,不然會引起混淆錯誤,即
mid=x(k)
x(k)=mid+x(k+b)e^(-j*2*π/N*p);
x(k+b)=mid-x(k+b)e^(-j*2*π/N*p)
上述三句語句就是核心,其他的迴圈無非就是找各種k,p,n等等參數的關係!
(3)最後強調下,一直調了好久的問題,複數和實數的轉置(複數轉置不可用x‘,一定要用x.')切記!