实验二用matlab实现傅立叶变换.docx
《实验二用matlab实现傅立叶变换.docx》由会员分享,可在线阅读,更多相关《实验二用matlab实现傅立叶变换.docx(12页珍藏版)》请在冰豆网上搜索。
![实验二用matlab实现傅立叶变换.docx](https://file1.bdocx.com/fileroot1/2022-12/7/0c4892e2-bcf9-4a08-8006-267fa027acb9/0c4892e2-bcf9-4a08-8006-267fa027acb91.gif)
实验二用matlab实现傅立叶变换
实验报告
2010年4月15日
实验二用matlab实现傅立叶变换
实验目的:
1.掌握傅立叶数值实现方法(矩阵算法)
2.生成连续周期信号,掌握程序优化技巧
3.对于自定义函数参数有效性的检查
4.复习并巩固“信号与系统”相关知识内容,学习用matlab实现问题
实验环境:
运行于Matlab7.6环境
实验内容:
本次实验参照《信号与系统》——“Matlab综合实验”55页课后练习
习题:
1.如图4.4所示锯齿波信号,分别去一个周期的抽样数据X1(t),0<=t<=1和五个周期的数据X(t),0<=t<5,计算其傅立叶变换X1(w)和X(w),比较有和不同并解释原因。
图4.4练习题2图
编程如下:
方法1:
%计算单位锯齿波和五个周期波形的傅立叶变换
%解法1:
基本用循环实现数值的计算;对于5个周期锯齿波用内外循环来生成实现
T1=1;%一个周期锯齿波
N1=10000;
t1=linspace(0,T1-T1/N1,N1)';
f1=0*t1;
f1=1-2*t1;
OMG=32*pi;%频率抽样区间
K1=100;%频率抽样点数
omg=linspace(-OMG/2,OMG/2-OMG/K1,K1)';
X1=0*omg;
fork=1:
K1%求解五个周期函数的傅里叶变换系数
forn=1:
N1
X1(k)=X1(k)+T1/N1*f1(n)*exp(-j*omg(k)*t1(n));
end
end
fs1=0*t1;
forn=1:
N1%通过傅里叶逆变换还原原函数
fork=1:
K1
fs1(n)=fs1(n)+OMG/2/pi/K1*X1(k)*exp(j*omg(k)*t1(n));
end
end
T2=5;%五个周期锯齿波
N2=10000;
t2=linspace(0,T2-T2/N2,N2)';
f2=0*t2;
t3=linspace(0,T2/5-T2/N2,N2/5)';%先定义一个周期内的锯齿波变量抽样值
f3=0*t3;%初始化一个周期的函数抽样值
f3=1-2*t3;%表示出一个周期内函数抽样值
fors=0:
4%将一个周期锯齿波平移到五个周期,通过循环控制
fora=1:
N2/5
f2(2000*s+a)=f3(a);
end
end%将函数拓展表示为五个周期
X2=0*omg;
fork=1:
K1%求解五个周期函数的傅里叶变换系数
forn=1:
N2
X2(k)=X2(k)+T2/N2*f2(n)*exp(-j*omg(k)*t2(n));
end
end
fs2=0*t2;
forn=1:
N1%通过傅里叶逆变换还原原函数
fork=1:
K1
fs2(n)=fs2(n)+OMG/2/pi/K1*X2(k)*exp(j*omg(k)*t2(n));
end
end
figure;
subplot(2,2,1);
plot(omg,abs(X1),'r');%以幅度频谱画图
xlabel('Frequency'),ylabel('Amplitude');
title('单个锯齿波的幅频曲线');
subplot(2,2,2);
plot(t1,fs1,'r');
xlabel('Second(s)'),ylabel('Amplitude');
title('由频域还原时域函数');
subplot(2,2,3);
plot(omg,abs(X2),'r');
xlabel('Frequency'),ylabel('Amplitude');
title('五个周期锯齿波的幅频曲线');
subplot(2,2,4);
plot(t2,fs2,'r');
xlabel('Second(s)'),ylabel('Amplitude');
title('由频域还原时域函数');
相关曲线:
方法2:
%计算单位锯齿波和五个周期波形的傅立叶变换
%解法2:
数值算法用矩阵实现,大大加快了运行速度;并且直接调用“sawtooth”生成5个周期的锯齿波
T1=1;%单个周期时域范围
N1=10000;%时域抽样点数
t1=linspace(0,T1-T1/N1,N1)';%生成抽样时间点
f1=1-2*t1;%生成抽样函数值
OMG=32*pi;%频域范围
K1=100;%频域抽样点数
omg=linspace(-OMG/2,OMG/2-OMG/K1,K1)';%生成抽样频率点
X1=T1/N1*exp(-j*kron(omg,t1.'))*f1;%傅里叶正变换求解傅里叶系数
fs1=OMG/2/pi/K1*exp(j*kron(t1,omg.'))*X1;%傅里叶逆变换还原时域函数
T2=5;%五个周期时域范围
N2=10000;%时域抽样点数
t2=linspace(0,T2-T2/N2,N2)';%生成抽样时间点
fs2=0*t2;
f2=sawtooth(t2*2*pi,0);%生成五个周期的锯齿波
X2=T2/N2*exp(-j*kron(omg,t2.'))*f2;%傅里叶正变换求解傅里叶系数
fs2=fs2+OMG/2/pi/K1*exp(j*kron(t2,omg.'))*X2;%傅里叶逆变换还原时域函数
figure;%生成一个2*2矩阵子图
subplot(2,2,1);
plot(omg,abs(X1),'r');%一个周期时的频谱图
xlabel('Frequency'),ylabel('Amplitude')
title('单个锯齿周期幅频特性曲线');
subplot(2,2,2);
plot(t1,fs1,'r');%还原的时域函数
xlabel('Time'),ylabel('Amplitude')
title('Functionafterrecovered');
subplot(2,2,3);
plot(omg,abs(X2),'r');%五个周期时的频谱图
xlabel('Frequency'),ylabel('Amplitude')
title('五个锯齿周期幅频特性曲线');
subplot(2,2,4);
plot(t2,fs2,'r');%还原的时域函数
xlabel('Time'),ylabel('Functionafterrecovered')
title('Functionafterrecovered');
相关曲线:
2.请编写函数F=fsana(t,f,,N),计算周期信号f的前N个指数形式的傅立叶级数系数,t表示f对应的抽样时间(均为一个周期);再编写函数f=fssyn(F,t),由傅立叶级数系数F合成抽样时间t对应的函数。
设计信号验证这两个是否正确。
3.利用fsana和fssyn计算练习题1中X1(t)的前10个傅立叶级数系数F,请用这些系数合成周期为0.5的锯齿波,0<=t<2并绘图。
解:
这两题验证函数直接用练习1所给函数.
编程如下:
编写fsana函数:
%函数功能:
定义一个功能函数来实现周期函数的傅里叶正变换t表示f表示的抽样时间f为一个周期内抽样函数值N为前几个指数形式的傅立叶级数系数
functionF=fsana(t,f,N)
omg1=2*pi/(max(t)-min(t));
k=[-N:
N]';
F=1/length(t)*exp(-j*kron(k*omg1,t.'))*f;
编写fssyn函数:
%函数功能:
定义功能函数fssyn由傅立叶级数系数F合成时间t对应的函数
functionf=fssyn(F,t)
omg1=2*pi/(max(t)-min(t));
N=floor(length(F)/2);
k=[-N:
N];
f=exp(j*kron(t,k*omg1))*F;
验证所写函数:
clc
clear
closeall
T1=1;%一个周期时域范围
N1=256;%时域抽样点数
t=linspace(0,T1-T1/N1,N1)';%生成抽样时间点
f=1-2*t;%生成抽样函数值
plot(f)
N=25
F1=fsana(t,f,N)%调用fsana函数求解前N项傅立叶级数系数
figure
(1)
stem(abs(F1),'s')
title('前N项傅立叶级数系数幅度曲线')
f2=fssyn(F1,t)%调用fssyn函数求原时域函数
f3=fssyn1(F1,t)%用所求傅立叶系数合成原基频2倍的函数调用修改后的fssyn函数(修改基频)
figure
(2)
plot(t,f,'b',t,f2,'k')
xlabel('time[s]'),ylabel('Amplitude')
legend('origin','recover')
title('傅立叶逆变换后时域函数与原时域函数对比')
figure(3)
plot(t,f3)
xlabel('time[s]'),ylabel('Amplitude')
title('时域压缩基频变为2倍后的时域函数')
注:
练习3要生成0.5周期的锯齿波,和原锯齿波相比是基频变为2倍,同样改写fssyn函数,修改基频,调用fssyn1函数:
functionf=fssyn1(F,t)
omg1=2*2*pi/(max(t)-min(t));
N=floor(length(F)/2);
k=[-N:
N];
f=exp(j*kron(t,k*omg1))*F;
相关曲线:
实验小结:
这个多礼拜的学习,我进一步对于matlab的数值算法有了自己的了解。
很多数学运算,可以类似地通过高级语言的方法实现,比如循环,可是这样花费的时间比较久,相应的代码也比较长。
Matlab软件库函数中有很多基于矩阵算法,因此,将问题通过矩阵来实现,将大大缩短程序和运行时间,通常也比较读懂(当然是在练习后)。
这次的学习,我另一方面明白了对于自定义函数的调用,它的文件名称应该与函数名称一样。
更重要的是,我学习到了一些基本的Matlab调试方法,在确认所使用算法和数学公式无误的情况下,我通常会设置断点,一步一步先运行程序,逐步排查错误,如果出错,直接在命令行或者工作区间查看相关矩阵内容的情况,这样就能比较快速地找到错误的根源。
当然,一个好的程序的前期工作很重要,这就要求我们首先必须掌握扎实的理论基础,对于我们,特别是信号与系统的知识,先要建立起数学物理模型,根据其实现方法选择合适的数值算法,再用Matlab实现。
路漫漫其修远兮,吾将上下而求索!
知识的海洋广袤无垠,有待了解和学习的东西太多了。
总之,好好学习Matlab,并且及时应用它。