Matlab快速傅里叶变换程序(FFT)编写

Matlab快速傅里叶变换程序(FFT)编写

(不利用Matlab内置fft)

最近在学习数字信号处理,正好到快速傅里叶变换,写一个基于基2FFT算法的傅里叶变换。利用原理:DIT-FFT(时域抽取法基2FFT)。
DIT-FFT:
设序列x(n)的长度为N,且满足N=2^M,M为自然数。
①按n的奇偶把x(n)分解为两个N/2的子序列。
②对x(n)做DFT,经过化简可以得到
X(k)=X1(k)+W^k;
X(k+N/2)=X1(k)+W^kX2(k);
k=0,1,…,N/2-1;
由此得到一个蝶形运算符号:
Matlab快速傅里叶变换程序(FFT)编写_第1张图片
③这是DIT-FFT基本原理,按照N值的大小,还可进一步进行分解运算,可分解M次,将N点DFT分解为N个1点DFT和M级蝶形运算,而1点DFT就是时域序列本身。
DFT与FFT运算量比较:
N点DFT:复数乘法CM=NN
复数加法CA=N
(N-1)
N点FFT: 复数乘法CM=MN/2
复数加法CA=M
N
N=2^M
代码:

function H=ditfft2(xn,M)
%DIT-FFT快速傅里叶变换程序
%程序名称:ditfft
%程序作者:grace_fight 2018/10/29

b=length(xn);                %调整补零
if(b<2^M)
    xn=[xn,zeros(1,(2^M)-b)];
end
b=length(xn);                %补零后xn长度
A=zeros(1,b);                %xn转换数组
N=2^M;                       %计算点数
nxd=bin2dec(fliplr(dec2bin([1:N]-1,M)))+1;%倒序排列序号
xn=xn(nxd);                               %倒序xn         
for i=1:N                                 %N个1点DFT,xn本身,赋值到数组A
   A(i)=xn(i);
end
for L = 1:M                               %DIT-FFT变换,M级蝶形变换
    B = 2^(L-1);                          %两个输入数据距离
    for J = 0:B-1;                        %旋转因子处理
        P=2^(M-L)*J;
        for k=(J+1):2^L:N;                %本次蝶形运算跨越时间
            W=exp(-j*2*pi*P/N);           %对应旋转因子
            T=A(k)+A(k+B)*W;              %进行蝶形运算
            A(k+B)=A(k)-A(k+B)*W;
            A(k)=T;
        end
    end
end
H=A;                                      %输出H为A

测试代码:

%测试程序
clear;                      %清屏
clc;
xn=[1 1 1 1];               %要转换的序列
M=5;                        %转换级数
B=fft(xn,32);               %matlab内置fft变换,用于对比
subplot(2,1,1);             %内置fft变换图像
[a1,b1]=size(B);
o1=1:b1;                    %内置fft变换坐标
stem(o1,abs(B),'.');        %绘图
H=ditfft2(xn,M);            %手工编写ditfft2函数
subplot(2,1,2);             %绘制手工编写的fft图像
[a1,b2]=size(H);
o2=1:b2;                    %ditfft2变换坐标
stem(o2,abs(H),'.')         %绘图

运行结果:
Matlab快速傅里叶变换程序(FFT)编写_第2张图片

参考:《数字信号处理第四版》高西全 丁玉美

你可能感兴趣的:(数字信号处理)