本文介绍卷积运算及实现。
1.定义
线性时不变系统的输出是输入样本与系统的冲激响应的卷积。这里假设输入样本为x(n),系统冲激响应为h(n),系统输出为y(n),则
线性卷积计算过程包含以下4个步骤:
1)折叠,关于l=0,折叠x(l)得到x(-l)
2)移位,将x(-l)向右移动n个样本得到x(n-l)
3)相乘,对于所有l,将h(l)和x(n-l)重叠部分相乘得到h(l)x(n-l)的乘积
4)相加,将所有乘积相加得到在时刻n的输出y(n)
重复步骤2至4,计算系统在其它瞬时n的输出,注意:输入信号长度M和冲激响应长度L的卷积结果为一个长度为L+M-1的输出信号。
例:
x(0)=,x(1)=,x(3)=,x(4)=
h(0)=,h(1)=,h(2)=
则
y(0)=
y(1)=
y(2)=
y(3)=
y(4)=
y(5)=
这里y(n)的输出长度为4+3-1=6个数据。
2.性质
卷积运算具有如下性质:
1)交换律,
2)结合律,
3)分配律,
4)时域卷积定理,,2个信号卷积的傅里叶变换是它们各自傅里叶变换的逐点乘积,即时域卷积对应于频域相乘
5)频域卷积定理,,2个信号逐点乘积的傅里叶变换是它们各自傅里叶变换的卷积(这里有个系数),即频域卷积对应于时域相乘
3.实现
这里基于C语言来实现。参考代码如下:
void conv(float *pSrcA, uint32_t srcALen, float *pSrcB, uint32_t srcBLen, float *pDst)
{
float *pIn1 = pSrcA; /* inputA pointer */
float *pIn2 = pSrcB; /* inputB pointer */
float sum = 0; /* Accumulator */
uint32_t i = 0; /* loop counter */
uint32_t j = 0; /* loop counter */
if ((pSrcA == NULL) || (srcALen == 0) || (pSrcB == NULL) || (srcBLen == 0) || (pDst == NULL))
{
return ;
}
/* Loop to calculate convolution for output length number of times */
for (i = 0U; i < ((srcALen + srcBLen) - 1U); i++)
{
/* Initialize sum with zero to carry out MAC operations */
sum = 0.0f;
/* Loop to perform MAC operations according to convolution equation */
for (j = 0U; j <= i; j++)
{
/* Check the array limitations */
if ((((i - j) < srcBLen) && (j < srcALen)))
{
/* z[i] += x[i-j] * y[j] */
sum += pIn1[j] * pIn2[i - j];
}
}
/* Store the output in the destination buffer */
pDst[i] = sum;
}
}
总结,本文介绍了卷积运算及实现。