根据课本上分析的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.')切记!