废话: 上信号与系统后,做实验用Matlab做的卷积,一个函数搞定,但是写实验报告时需要用C语言实现,额,虽说原理不难,实现起来浪费了我好久时间
一、卷积公式
Y(n)=x(n)h(n)=∑x(i)h(n-i)
先用Matlab演示卷积,后面以这个为例。 ![在这里插入图片描述](https://img-blog.csdnimg.cn/20190529232323170.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3dlaXhpbl80MjEwOTAxMg==,size_16,color_FFFFFF,t_70)
a=[1,2,3,4]
b=[1,2,3]
conv(a,b)
ans =
1 4 10 16 17 12
二、对卷积的求解
这个一般有两种方法实现 1、第一种是交叉相乘相加法(对于1维的卷积,注意一定要将其中一个倒叙或者翻转180度)
对于同一时间接触到的面积进行相乘,再相加即是这个时刻的值 例子 代码实现
#include
#include
int min(int x, int y) {
return x < y ? x : y;
}
int max(int x, int y) {
return x > y ? x : y;
}
void convolution(int* input1, int* input2, int* output, int mm, int nn)
{
//存储地址
int* xx = (int*)malloc(sizeof(int) * (mm + nn - 1));
//开始卷积
for (int i = 0; i < mm + nn - 1; i++)
{
xx[i] = 0;
//以位数最少的卷积作为卷积次数
for (int j = 0; j < min(mm,nn) ; j++) {
//第一个卷积比第二个卷数积少执行
if (mm = 0 && i - j < max(mm, nn)) {
printf("%d ", input1[j]);
printf("%d ", input2[i-j]);
xx[i] += input1[j] * input2[i - j];
}
}
//第一个卷积比第二个卷积数多执行
else {
if (i - j >= 0 && i - j < max(mm, nn)) {
printf("%d ", input1[i-j]);
printf("%d ", input2[j]);
xx[i] += input2[j] * input1[i - j];
}
}
printf("\n");
}
}
printf("\n");
for (int i = 0; i < mm+nn-1; i++) {
output[i] = xx[i];
}
delete[] xx;
}
int main() {
int mm, nn;
printf("请输入第一个卷积数目\n");
scanf_s("%d", &mm);
//malloc分配空间
int* input1 = (int*)malloc(sizeof(int) * mm);
printf("请输入第一个卷积数值\n");
for (int i = 0; i < mm; i++) {
scanf_s("%d", &input1[i]);
}
printf("请输入第二个卷积数目\n");
scanf_s("%d", &nn);
int* input2 = (int*)malloc(sizeof(int) * nn);
printf("请输入第二个卷积数值\n");
for (int j = 0; j < nn; j++) {
scanf_s("%d", &input2[j]);
}
//卷积最大空间
int* output = (int*)malloc(sizeof(int) * (mm+nn-1));
convolution(input1, input2, output, mm, nn);
printf("卷积结果\n");
for (int i = 0; i < mm + nn - 1; i++)
{
printf("%d ", output[i]);
}
printf("\n");
return 0;
}
![在这里插入图片描述](https://img-blog.csdnimg.cn/2019052923254212.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3dlaXhpbl80MjEwOTAxMg==,size_16,color_FFFFFF,t_70)
二、第二种方法是时延法(第二种方法相对来说比较简单,转到z域后,卷积变为多项式相乘,不需要对序列进行移动或处理,仅将结果延时相应位数,然后对应相加、提取系数即可。)
已知y[0] = i, y[1] = j, y[2]=k 下面通过演示求x[n] * y[n]的过程,揭示卷积的物理意义。 第一步,x[n]乘以y[0]并平移到位置0 ![在这里插入图片描述](https://img-blog.csdnimg.cn/20190529232902889.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3dlaXhpbl80MjEwOTAxMg==,size_16,color_FFFFFF,t_70)
第二步,x[n]乘以y[1]并平移到位置1 第三步,x[n]乘以y[2]并平移到位置2: 最后,把上面三个图叠加,就得到了x[n] * y[n]: 简单吧?无非是平移(没有反褶!)、叠加。 实例 代码实现
#include
#include
void convolution2(int* input1, int* input2, int* output, int mm, int nn)
{
//存储地址
int* xx = (int*)malloc(sizeof(int) * (mm + nn - 1));
for (int i = 0; i < mm + nn - 1; i++) {
xx[i] = 0;
}
//开始卷积
//利用时延效果,记录所有乘积后,时间位置一样的相加
for (int i = 0; i < mm; i++) {
for (int j = 0; j < nn; j++) {
xx[i + j] += input1[i] * input2[j];
}
}
for (int i = 0; i < mm + nn - 1; i++) {
output[i] = xx[i];
}
delete[] xx;
}
int main() {
int mm, nn;
printf("请输入第一个卷积数目\n");
scanf_s("%d", &mm);
//malloc分配空间
int* input1 = (int*)malloc(sizeof(int) * mm);
printf("请输入第一个卷积数值\n");
for (int i = 0; i < mm; i++) {
scanf_s("%d", &input1[i]);
}
printf("请输入第二个卷积数目\n");
scanf_s("%d", &nn);
int* input2 = (int*)malloc(sizeof(int) * nn);
printf("请输入第二个卷积数值\n");
for (int j = 0; j < nn; j++) {
scanf_s("%d", &input2[j]);
}
//卷积最大空间
int* output = (int*)malloc(sizeof(int) * (mm + nn - 1));
convolution2(input1, input2, output, mm, nn);
printf("卷积结果\n");
for (int i = 0; i < mm + nn - 1; i++)
{
printf("%d ", output[i]);
}
printf("\n");
return 0;
}
运行结果 ![在这里插入图片描述](https://img-blog.csdnimg.cn/20190529233504151.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3dlaXhpbl80MjEwOTAxMg==,size_16,color_FFFFFF,t_70)
|