通过重叠相加法实现卷积.docx
《通过重叠相加法实现卷积.docx》由会员分享,可在线阅读,更多相关《通过重叠相加法实现卷积.docx(13页珍藏版)》请在冰豆网上搜索。
通过重叠相加法实现卷积
数字信号处理
课程设计
题目:
通过重叠相加法实现卷积
院系:
自动化与信息工程学院
专业:
通信工程
班级:
通信092
学号:
3090432051
姓名:
侯鹏
指导教师:
吴鹏飞
2012年6月23日-2012年6月30日
设计任务
通过重叠相加法实现卷积(C语言或MATLAB实现)。
计算一个给定序列与输入序列的卷积。
功能对给定的数据进行卷积计算,要求分算卷积由循环卷积实现要求设计有数据导入界面,各种参数可以由软件界面输入,其中给定序列可以由界面输入,对运算前后的数据绘制曲线。
设计步骤:
1)初步完成总体设计,搭好框架,确定人机对话界面,确定函数功能,控制参数的输入方法;
2)设计线性卷积的实现方案;
3)编写两序列做循环卷积的程序;
4)通过直接作线性卷积来检验最后结果;
设计要求:
1)用结构化设计方法。
一个程序划分成若干模块,每一个模块的函数功能要划分好,总体设计要画出流程图;
2)输入输出界面要友好;
3)源程序书写要规范,加必要的注释;
4)要提供直接通过卷积进行检验的结果;
5)程序一定要能运行起来。
课程设计的最后结果是提交一份实验报告,内容包括:
1)程序的设计思想,包括功能描述,函数接口的确定;
2)流程图;
3)程序源代码(需打印);
4)测试方法和结果;
5)小结。
1、原理
<一>设计思想:
运用分段处理方法中的重叠相加法计算两个序列的卷积运算。
设一个给定序列是长度为n1的A,另一个导入序列是长度为n2的B,其中B序列是相对A序列比较长的,所以可以把B分为和A一样长的若干段段,即B分后每一小段长度为n1。
根据书上的公式:
可知将B序列的每一小段与A序列做现行卷积,然后将所有的n2/n1段的线性卷积结果相加起来就是整个B序列和A序列的线性卷积结果,而又在本设计中,B序列的一小段和A序列的线性卷积又可由循环卷积来实现,只要让循环卷积的点数
,循环卷积的结果就和线性卷积的结果等价,在本实验中取
故A序列和B序列的线性卷积可认为是由A序列和B的每一小段做
点的循环卷积的最终累加和,
另外还有两个个问题需要考虑,首先是做循环卷积时要对A序列和B序列的那一小段补零做卷积后,最终做累加的时候要考虑重叠的片段,必须将重叠的两段加起来。
不重叠的片段直接赋值。
其次是如果B序列长度n2不是A序列长度n1的整数倍时,必须将B序列余下的那几个数补零后和A序列做
点循环卷积再加到最终的结果的相应位置。
下列是计算循环卷积的过程:
在本次课设题中序列A和B序列的某一小段做循环卷积,由于已知A序列的长度为n1,故可取B序列的每一小段都和A序列相等长度,并且取循环卷积的点数为
,这就保证每一组的循环卷积都等效于线性卷积。
做循环卷积可运用课本上82页上的循环卷积矩阵做,其第一步是将A序列和B序列的某一小段补零到长度为
,然后把A序列通过变换生成
的循环卷积矩阵,将补零后的B的某一小段转置,然后用循环卷积矩阵乘以它就可以得到循环卷积的结果,在此也即线性卷积。
重叠相加法的图示如下:
2、流程图
<主函数流程图>
<循环卷积子函数流程图>
3、实验结果验证
<一>当输入序列为x=[25436]时,输入前后以及结果图形对比。
分析:
当给定序列x和导入序列如图中所示时,二者做卷积结果在理论上应该是长度为5+200-1=204点的序列(如第四幅图所示),对比第二幅图和第四幅图可知运用分段重叠相加法计算的线性卷积完全正确。
4、界面设计
说明:
第一行第一个图是给定的序列,第二行第一个图是导入的序列的图形,第二行第一个图是本次设计的结果图形,第二行第二个图是直接调用系统函数y=conv(x)得到的结果。
界面上一个输入框,两个按钮,其中运行键控制整个系统的运行,退出键可以使其退出当前界面。
5、分析和总结
在重叠相加法实现卷积中,对导入的序列进行了分段,原导入序列长度为n2,输入的序列长度为n1,则分段数i=n2/n1并向下取整,当n2不是n1的整数倍时,在最后一段进行补零,循环卷积长度为L=N+M-1,因为在计算线性卷积时,可以先计算分段线性卷积,然后把分段卷积结果叠加起来即可,因为对n2进行了分段处理,处理后分段的长度和n1相等故n1=N,M=n1,M=N,即:
L=2*n1-1,否则将发生混叠。
叠加重叠点就可以得到输出序列的值。
通过自己编写函数的输出波形和系统自带函数的输出波形,对相同数据进行处理,进行对比,他们的结果完全相同,因此可以验证所编写的函数是正确的。
在进行matlab编程时,也出现了很多问题,通过和同学讨论,查阅相关资料最终都得以解决,同时也非常感谢指导老师的悉心指导。
参考文献
【1】高西全,丁玉美.数字信号处理(第三版).西安:
西安电子科技大学出版社,2008.05
附录:
主要程序
三、源程序
<一>、主函数源程序:
A=input('请输入给定序列:
');
c=load('huang.txt');%导入数据
B=c';
n1=length(A);%记序列A的长度
n2=length(B);%记序列B的长度
i=fix(n2/n1);%算B的长度是A的几倍,向下取整
L=2*n1-1;%取循环卷积的长度,使其每小段
%循环卷积满足和线性卷积等价
y(1:
L)=Convmy4(A,B(1:
n1),L);%调用编好的循环卷积函数
r(1:
L)=y(1:
L);%计算最终结果的前n1个点的值
forp=2:
1:
i%循环
s=B((p-2)*n1+1:
(p-2)*n1+n1);%取B序列的第一小段存到s
y((p-2)*n1+1:
(p-2)*n1+L)=Convmy4(A,s,L);%计算第一小段和A序列循环卷积的%L点结果
C(1:
L-n1)=y((p-2)*n1+n1+1:
(p-2)*n1+L);%将第一组做循环卷积得到的结果
%重叠部分先转存到临时变量C中
z=B((p-1)*n1+1:
(p-1)*n1+n1);%取B序列的第二小段存到z
y((p-1)*n1+1:
(p-1)*n1+L)=Convmy4(A,z,L);%将其和A的循环卷积的结果给y
forn=1:
1:
n1-1%-------------------------
y((p-1)*n1+n)=C(n)+y((p-1)*n1+n);%计算重叠部分的结果
r((p-1)*n1+n)=y((p-1)*n1+n);
end%-------------------------
forn=n1:
1:
n1%-------------------------
y((p-1)*n1+n)=y((p-1)*n1+n);%计算没重叠部分的结果
r((p-1)*n1+n)=y((p-1)*n1+n);
end%-------------------------
end%循环结束
D(1:
L-n1)=y((p-1)*n1+n1+1:
(p-1)*n1+L);%*************************
forn=n1+1:
1:
L%显示末尾的一段
r((p-1)*n1+n)=D(n-n1);
end%*************************
ifmod(n2,n1)~=0%-------------------------
h=mod(n2,n1);
E=[B(i*n1+1:
i*n1+h),zeros(1,n1-h)];
F(1:
L)=Convmy4(A,E,L);
P(1:
n1-1)=r((p-1)*n1+n1+1:
(p-1)*n1+L);%如果n2不是n1的整数倍,则应
forn=1:
1:
n1-1%将B序列多余的那几个点补零再
r(i*n1+n)=P(n)+F(n);%和A做循环卷积并显示出来
end
forn=n1:
1:
L
r(i*n1+n)=F(n);
end
end%-------------------------
q=conv(A,B);%调用系统函数做线性卷积,验证结%果
r;
x1=1:
1:
n1;%-------------------------
subplot(2,2,1);
stem(x1,A);
title('给定序列A');
gridon;%画原来输入的两个序列和最终
x2=1:
1:
n2;%序列的图形
subplot(2,2,3);
stem(x2,B);
title('导入序列B');
gridon;
x3=1:
1:
length(r);
subplot(2,2,2);
stem(x3,r);
title('线性卷积结果图形');
gridon;%-------------------------
x4=1:
1:
n1+n2-1;%*************************
subplot(2,2,4);%画调用系统函数得到的结果图形
stem(x4,q);
title('直接调用系统函数得到的图形');
gridon;%*************************
<二>、循环卷积子函数:
functiony=Convmy4(A,B,L)%创建循环卷积函数
ifLerror('出错');
end
ifL>length(A)%如果A序列长度小于L则补零到L
A=[A,zeros(1,L-length(A))];
end
ifL>length(B)%给B序列补零到L
B=[B,zeros(1,L-length(B))];
B=B';%B转置
end
E=A(1,1);%---------------------------------
C=A(1,[2:
L]);%写循环矩阵的第一行
D=fliplr(C);
A=[E,D];%---------------------------------
y
(1)=A(1,1).*B(1,1);
forh=2:
1:
L
y
(1)=y
(1)+A(1,h).*B(h,1);%%计算循环卷积序列的第一个值
end
fork=2:
1:
L%*********************************
t=A(1,L);
fori=L:
-1:
2
A(1,i)=A(1,i-1);%得到矩阵的第二到L行并计算循环卷积的
end%另外几个值
A(1,1)=t;
y(k)=0;
form=1:
1:
L
y(k)=y(k)+A(1,m).*B(m,1);%*********************************
end
end