成绩
数字信号处理
实验报告
实验名称: FFT算法的应用
实验班级:
姓 名:
学号(后两位):
指导教师:
实验日期: 2010.11.23
实验3 FFT算法的应用
一、实验目的
1、加深对离散信号的DFT的理解;
2、在MATLAB中实现FFT算法。
二、实验原理
N点序列的DFT和IDFT变换定义式如下:
,
,
利用旋转因子具有周期性,可以得到快速算法(FFT)。
在MATLAB中,可以用函数x=fft(x,N)和x=ifft(x,N)计算N点序列的DFT正、反变换。
三、预习要求
1、在MATLAB中,熟悉函数fft、ifft的使用;
2、阅读扩展练习中的实例,学习在MATLAB中的实现FFT算法的实现;
3、利用MATLAB编程完成计算,绘出相应图形。并与理论计算相比较,说明实验结果的原因。
例:对连续的单一频率周期信号 按采样频率采样,截取长度N分别选N =20和N =16,观察其DFT结果的幅度谱。
解:此时离散序列,即k=8。用MATLAB计算并作图,函数fft用于计算离散傅里叶变换DFT,程序如下:
k=8;
n1=[0:1:19];
xa1=sin(2*pi*n1/k);
subplot(2,2,1)
plot(n1,xa1)
xlabel('t/T');ylabel('x(n)');
xk1=fft(xa1);xk1=abs(xk1);
subplot(2,2,2)
stem(n1,xk1)
xlabel('k');ylabel('X(k)');
n2=[0:1:15];
xa2=sin(2*pi*n2/k);
subplot(2,2,3)
plot(n2,xa2)
xlabel('t/T');ylabel('x(n)');
xk2=fft(xa2);xk2=abs(xk2);
subplot(2,2,4)
stem(n2,xk2)
xlabel('k');ylabel('X(k)');
图1 不同的截取长度的正弦信号及其DFT结果
计算结果示于图1,(a)和(b)分别是N=20时的截取信号和DFT结果,由于截取了两个半周期,频谱出现泄漏;(c) 和(d) 分别是N=16时的截取信号和DFT结果,由于截取了两个整周期,得到单一谱线的频谱。上述频谱的误差主要是由于时域中对信号的非整周期截断产生的频谱泄漏。
四、实验内容
1、2N点实数序列
N=64。用一个64点的复数FFT程序,一次算出,并绘出 的图形。(按照基于2的蝶型结构的递推公式编程)
编程如下:
N=64;n=[0:1:N-1];
n1=2*n;n2=2*n+1;k=[0:1:N-1];
xn1=cos(2*pi/N*7*n1)+1/2*cos(2*pi/N*19*n1);
xn2=cos(2*pi/N*7*n2)+1/2*cos(2*pi/N*19*n2);
XK1=fft(xn1);XK2=fft(xn2);
X1=XK1+exp(-j*pi*k/N).*XK2;
X2=XK1-exp(-j*pi*k/N).*XK2;
X1=[X1 zeros(1,N)];X2=[zeros(1,N) X2];
XK=X1+X2;
k=[0:1:2*N-1];
XK=abs(XK); stem(k,XK);
xlabel('k');ylabel('|X(k)|');
title('X(k)=DFT[x(n)]2N')
2、已知某序列在单位圆上的N=64等分样点的Z变换为:
。
用N点IFFT程序计算出和。
MATLAB编程如下:
N=64;
k=[0:1:63];
xk=1./(1-0.8*exp(-j*2*pi*k/N));
xn=ifft(xk,64);
stem(k,xn)
xlabel('k');ylabel('x(n)');
disp('xn序列');disp(xn);
xn的图像为:
xn序列:
1.0000 - 0.0000i 0.8000 + 0.0000i 0.6400 + 0.0000i 0.5120 + 0.0000i
0.4096 + 0.0000i 0.3277 + 0.0000i 0.2621 + 0.0000i 0.2097 + 0.0000i
0.1678 + 0.0000i 0.1342 + 0.0000i 0.1074 + 0.0000i 0.0859 + 0.0000i
0.0687 - 0.0000i 0.0550 - 0.0000i 0.0440 - 0.0000i 0.0352 - 0.0000i
0.0281 - 0.0000i 0.0225 - 0.0000i 0.0180 - 0.0000i 0.0144 - 0.0000i
0.0115 - 0.0000i 0.0092 - 0.0000i 0.0074 - 0.0000i 0.0059 - 0.0000i
0.0047 - 0.0000i 0.0038 - 0.0000i 0.0030 - 0.0000i 0.0024 - 0.0000i
0.0019 - 0.0000i 0.0015 - 0.0000i 0.0012 - 0.0000i 0.0010 + 0.0000i
0.0008 + 0.0000i 0.0006 + 0.0000i 0.0005 + 0.0000i 0.0004 + 0.0000i
0.0003 + 0.0000i 0.0003 + 0.0000i 0.0002 + 0.0000i 0.0002 + 0.0000i
0.0001 + 0.0000i 0.0001 + 0.0000i 0.0001 + 0.0000i 0.0001 + 0.0000i
0.0001 + 0.0000i 0.0000 + 0.0000i 0.0000 + 0.0000i 0.0000 - 0.0000i
0.0000 + 0.0000i 0.0000 + 0.0000i 0.0000 + 0.0000i 0.0000 - 0.0000i
0.0000 + 0.0000i 0.0000 - 0.0000i 0.0000 - 0.0000i 0.0000 - 0.0000i
0.0000 - 0.0000i 0.0000 - 0.0000i 0.0000 - 0.0000i 0.0000 - 0.0000i
0.0000 - 0.0000i 0.0000 - 0.0000i 0.0000 - 0.0000i 0.0000 - 0.0000i
五、结果分析
理论值计算:
因,k=0,1,……,63。所以,其中|z|>0.8,所以,n=0,1,2,……63。当n=0时,x(n)=1.0,当n=1时,x(n)=0.8,等等,
六、心得体会
这次试验加深了离散信号的DFT的理解,了解和掌握了利用MATLAB进行FFT算法,经过前几次的试验,感觉比前几次试验做的稍微好了点,但是还是依然出现些问题,还是需要在课下多加练习。
辛旸 PB10210006
实验目的
1、加深对快速傅里叶变换的理解。
2、掌握FFT 算法及其程序的编写。
3、掌握算法性能评测的方法。
实验内容
1.编写自己的FFT算法:
代码如下:
function [ X ] = Sampling( x,N )
%myFFT 实现FFT时域取样算法
% 输出:生成FFT序列X(k),输入:欲变换序列x(n),FFT变换长度N(可缺省)
(1) if ~exist('N','var'); %检查是否有变换长度N输入
(2) N=length(x); %若无,则令N等于序列长度
(3) end
(4) if N<length(x); %如果N小于序列长度,则对序列进行截短
(5) x=x(:,1:N);
(6) else
(7) x=[x,zeros(1,N-length(x))]; %如果N大于序列长度,对序列补零进行延长
(8) end;
(9) for i=1:1:length(x)/2+1; %判断N是2的多少次方
(10) if 2^i>=length(x); %若N不是2的整数幂
(11) N=2^i; %增大N为2的整数幂
(12) break;
(13) end
(14) end
(15) x=[x,zeros(1,N-length(x))]; %确保要变换的序列长度为2^i
(16) k1=zeros(1,N);
(17) X=zeros(1,N);
(18) w=zeros(1,N);
(19) for m=0:1:N-1; %确定反序序列k1和正序序列k的关系
(20) k=m;
(21) for n=i-1:-1:0; %从高位开始依次将各位移至反序位
(22) k1(m+1)=k1(m+1)+fix(k/(2^n))*(2^(i-1-n));
(23) k=rem(k,2^n);
(24) end;
(25) end
(26) for l=1:1:N;
(27) X(k1(l)+1)=x(l); %生成反序序列
(28) w(l)=exp(-1i*2*pi/N*(l-1)); %生成旋转因子
(29) end
(30) for l=0:1:i-1; %控制FFT运算级数
(31) for m=1:1:N; %每一级中有N/2个蝶形运算
(32) if rem((m-1),2^(l+1))<2^l; %找到蝶形运算的上半部分
(33) b=X(m)+X(m+2^l)*w(2^(i-1-l)*rem((m-1),2^l)+1); %将结果暂存至b
(34) X(m+2^l)=a(m)-X(m+2^l)*w(2^(i-1-l)*rem((m-1),2^l)+1);
(35) X(m)=b; %实现原位运算
(36) end
(37) end
(38) end
2.选择实验1中的典型信号序列验证算法的有效性:
为方便比较两个算法,编写了myCompare函数计算两种算法的运行时间,并绘制频谱曲线
代码如下:
function [ t1,t2,e ] = myCompare( x,N )
%myCompare函数:比较自己编写的算法与系统自带算法的差异
% 输入:与变换信号序列x(n)和欲变换长度N
% 输出:自己编写的函数的执行时间t1,系统自带函数的执行时间t2,两者计算序列的差异平方和e tic;
X1=myFFT(x,N);
t1=toc;
tic;
X2=fft(x,N);
t2=toc;
subplot(1,2,1);plot(abs(X1));xlabel('k');ylabel('X(k');title('ÓÃ×Ô¼º±àдµÄº¯ÊýµÃµ½µÄ±ä»»ÐòÁÐƵÆ×');
subplot(1,2,2);plot(abs(X2));xlabel('k');ylabel('X(k');title('ϵͳ×Ô´øFFTº¯ÊýµÃµ½µÄ±ä»»ÐòÁÐƵÆ×');
e=sum((X1-X2).^2);
end
对理想采样信号A=444.128,α=50*2^(1/2)*π,Ω=50*2^(1/2)*π,T=1/1000,序列长度50,用自己编写的FFT算法和系统自带算法做64点FFT变换后绘制频域序列,如下:
对高斯序列,p=8,q=8,序列长度16,用自己编写的FFT算法和系统自带算法做16点FFT变换后绘制频域序列,如下:
对衰减正弦序列α=0.01,f=0.05,序列长度100,用自己编写的FFT算法和系统自带算法做128点FFT变换后绘制频域序列,如下:
由以上结果可知,自己编写的算法运行结果与系统自带算法一致,且可以对信号进行截断或补零后再做变换。
3.对所编制FFT算法进行性能评估:
与自己编写的DFT算法进行性能比较:
对N点序列进行DFT变换需要N²/2次复乘,而对N点序列做基2-FFT只需N/2*log2(N)次复乘,因此运算量减少了很多,且随着序列长度增加,运算量差异变大。
与系统自带FFT算法进行性能比较:
由于系统自带FFT函数用C语言实现,无法查看源代码,只知道效率更高,而且在计算任意点的DFT(不指定变换长度N)时,系统自带函数无需采取补零操作,而自己编写的函数会先补零再变换,改变了频域取样密度,会得到与系统自带函数不同的结果。
比较自己编写的DFT算法、自己编写的FFT算法和系统自带算法三者运算时间,得到下表:
由此绘制曲线如图:
由比较结果可知,虽然运算时间曲线和理想曲线不完全相同,但三种算法的相对运算时间与理论预期一致。
实验总结及个人结论:
从对实验的比较结果中可知,自己编写的FFT算法有效且比自己编写的DFT算法快很多,但却始终比系统自带的算法慢,一方面是因为系统自带算法实现效率高,另一方面,在观察了自己编写的算法中各步执行时间后,发现函数用在生成反序序列的时间和实际进行FFT运算的时间相当,相当于多用了一倍的时间。另外,对任意长序列,自己编写的FFT算法只能补零后计算,而不能像系统自带函数一样算出实际的N点DFT。
算法设计与分析实验报告班级姓名学号年月日目录实验一二分查找程序实现03页实验二棋盘覆盖问题分治法08页实验三01背包问题的动态规划…
算法设计课程报告课题名称算法设计与实现课题负责人名学号张樱紫0743111317同组成员名单角色无指导教师左劼评阅成绩评阅意见提交…
遗传算法实验报告姓名:**学号:**一、实验目的:熟悉和掌握遗传算法的运行机制和求解的基本方法。遗传算法是一种基于空间搜索的算法,…
1hanoi塔packagesyyimportjavautilpublicclassHanoipublicstaticvoidmo…
20xx年上半年商务工作个人总结今年在商务工作上,我尽到了应尽的职责,过去的半年里在不断改善工作方式方法的同时,顺利完成如下工作:…
十月工作总结十月所做工作:1、产业集聚升级项目申报资料编写;2、两个新产品技术总结以及检测、查新技术资料编写;3、协助两化项目资料…
鸡西市传染病医院廉政风险防控机制建设总结根据市卫生局《关于印发鸡西市卫生系统廉政风险防控机制建设工作实施方案的通知》精神,我院以开…
牛马榔20xx年小学远程教育工作总结一年来,我校在国家实施的农村中小学现代远程教育工程中,为了加强对现代远程教育工作的管理和现代远…
喀什地区第一人民医院20xx年度《万名医师支援农村卫生工程》工作总结夏木西丁.阿布都热西提喀什地区第一人民医院20xx年度《万名医…