c语言和matlab编程实现序列卷积(不调包)

编程入门 行业动态 更新时间:2024-10-28 00:17:52

c语言和matlab编程实现序列<a href=https://www.elefans.com/category/jswz/34/1765938.html style=卷积(不调包)"/>

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编程实现序列卷积(不调包)

本文发布于:2023-07-27 22:20:42,感谢您对本站的认可!
本文链接:https://www.elefans.com/category/jswz/34/1231596.html
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。
本文标签:卷积   序列   语言   matlab

发布评论

评论列表 (有 0 条评论)
草根站长

>www.elefans.com

编程频道|电子爱好者 - 技术资讯及电子产品介绍!