卷积(不调包)"/>
c语言和matlab编程实现序列卷积(不调包)
文章目录
- c语言编程实现卷积
- matlab编程实现卷积
- 卷积结果验证
- 语音信号和随机序列的卷积(使用自己编写的卷积函数)
- 总结
对于离散的序列,卷积公式如下:
y ( n ) = ∑ i = − ∞ + ∞ x ( i ) h ( n − i ) = x ( n ) ∗ h ( n ) y(n)=\sum_{i=-\infty}^{+\infty}x(i)h(n-i)=x(n)*h(n) y(n)=i=−∞∑+∞x(i)h(n−i)=x(n)∗h(n)
卷积是两个变量在某范围内相乘后求和的结果。其中星号*表示卷积。当时序n=0时,序列h(-i)是h(i)的时序i取反的结果;时序取反使得h(i)以纵轴为中心翻转180度,所以这种相乘后求和的计算法称为卷积和,简称卷积。另外,n是使h(-i)位移的量,不同的n对应不同的卷积结果。
c语言编程实现卷积
编写的c程序如下:
#include<stdio.h>
#include<math.h>
int main()
{
double a_in[4]={4.0,3.2,1.5,8.3}; //输入序列1
double b_in[6]={3.3,5.4,7.6,10.2,1.8,2.6}; //输入序列2
double c_in[9]; //卷积后的输出序列
int i,j,k;for (i=0;i<9;i++) //对输出序列进行初始化,赋值为0{c_in[i]=0;}for (j=0;j<9;j++) //外循环控制输出序列{for (k=0;k<6;k++) //内循环控制卷积序列{if ((j-k) >= 0 && (j-k) < 4) //卷积控制{c_in[j] += a_in[j-k]*b_in[k]; //进行卷积}}}for (i=0;i<9;i++){printf("%f\n",c_in[i]); //打印卷积结果}
}
使用tcc运行,结果:
C:\Users\CL\Desktop\学习\C>tcc conv1.cC:\Users\CL\Desktop\学习\C>conv1.exe
13.200000
32.160000
52.630000
100.610000
96.060000
94.540000
95.680000
18.840000
21.580000
matlab编程实现卷积
matlab编写卷积函数,代码如下:
clc
clear
close all
a=[4.0,3.2,1.5,8.3]; %输入序列1
b=[3.3,5.4,7.6,10.2,1.8,2.6]; %输入序列2
c=zeros(1,9); %对用于保存卷积结果的c矩阵赋初值0
for i=1:1:9 %外循环控制输出序列for j=1:1:6 %内循环控制卷积序列if ((i-j)>=0 && (i-j)<4) %卷积控制c(i)=c(i)+a(i-j+1).*b(j) %卷积,并输出结果显示endend
end
运行结果:
c =13.2000 32.1600 52.6300 100.6100 96.0600 94.5400 95.6800 18.8400 21.5800
卷积结果验证
使用matlab调用卷积函数包,验证上面结果是否正确,编写的matlab程序:
clc
clear
close all
a=[4.0,3.2,1.5,8.3];
b=[3.3,5.4,7.6,10.2,1.8,2.6];
c=conv(a,b) %调用卷积函数
结果:
c =13.2000 32.1600 52.6300 100.6100 96.0600 94.5400 95.6800 18.8400 21.5800
经验证,结果正确。
语音信号和随机序列的卷积(使用自己编写的卷积函数)
程序如下:
%语音信号卷积
clc
clear all
[x,fs]=audioread('voice.wav'); %读取语音文件
s=1:length(x);
t=s/fs;
xmax=max(abs(x)); %取最大幅值
x=x/xmax; %归一化
y=randn(size(x));%产生同x相同长度的随机序列
ymax=max(abs(y));
y=y/ymax;
a=length(x) %计算x的长度
b=length(y) %计算y的长度
z=zeros(1,a+b-1); %对用于保存结果的矩阵赋初值%卷积开始
t1=clock; %计时开始
for i=1:1:(a+b-1) %外循环控制输出序列for j=1:1:b %内循环控制卷积序列if ((i-j)>=0 && (i-j)<a) %卷积控制z(i)=z(i)+x(i-j+1).*y(j); %卷积,并输出结果显示endend
end
t2=clock; %计时结束
time=etime(t2,t1) %计算卷积时间zmax=max(abs(z)); %取幅值
z=z/zmax; %归一化
t2=(1:length(z))/fs; %画图时的x轴
figure(1)
subplot(311)
plot(t,x);
xlabel('时间/s');
ylabel('归一化幅值');
title('(a)原始信号');
subplot(312)
plot(t,y);
xlabel('时间/s');
ylabel('归一化幅值');
title('(b)随机序列');
subplot(313)
plot(t2,z);
xlabel('时间/s');
ylabel('归一化幅值');
title('(c)信号卷积');
结果
运行时间:
time =11.1140
卷积结果:
使用matlab自带卷积函数进行卷积计算,程序如下:
%2.2.2-2:语音信号卷积
clc
clear all
[x,fs]=audioread('voice.wav'); %读取语音文件
s=1:length(x);
t=s/fs;
xmax=max(abs(x)); %取最大幅值
x=x/xmax; %归一化
y=randn(size(x));%产生同x相同长度的随机序列
ymax=max(abs(y));
y=y/ymax;t1=clock; %计时开始
z=conv(x,y); % 调用conv卷积函数进行卷积计算
t2=clock; %计时结束
time=etime(t2,t1) %计算卷积时间zmax=max(abs(z)); %取幅值
z=z/zmax; %归一化
t2=(1:length(z))/fs; %画图时的x轴
figure(1)
subplot(311)
plot(t,x);
xlabel('时间/s');
ylabel('归一化幅值');
title('(a)原始信号');
subplot(312)
plot(t,y);
xlabel('时间/s');
ylabel('归一化幅值');
title('(b)随机序列');
subplot(313)
plot(t2,z);
xlabel('时间/s');
ylabel('归一化幅值');
title('(c)信号卷积');
运行时间:
time =0.0960
运行结果:
总结
和matlab自带的卷积函数conv
进行比较,自己编写的卷积函数效率会低很多,需要进一步改进。对比运行结果,进行的卷积结果没什么差别,效果较好。
更多推荐
c语言和matlab编程实现序列卷积(不调包)
发布评论