是否可以在不填充输入和系数的情况下实现FIR滤波操作?
即,假设输入和滤波器系数的大小为4,则输出将为7个样本。因此,在实现时,我们通常会在输入和滤波器系数上再加3个零,使它们等于输出大小。
但是,如果输入和滤波器系数的大小为1024,则输出将为2047个样本。所以,现在,我们需要在输入系数和滤波器系数上加1023个零。这是低效的,对吧?
所以,我只想知道有没有其他方法可以在没有填充的情况下实现FIR滤波?
下面的代码给出了我所说的想法。
int x[7],h[7],y[7];
int i,j;
for(i=0;i<7;i++)
{
if(i<4)
{
x[i] = i+1;
h[i] = i+1;
}
if(i>=4)
{
x[i] = 0;
h[i] = 0;
}
}
for(i=0;i<7;i++)
{
y[i] = 0;
for(j=0;j<=i;j++)
{
y[i] = y[i] + h[j] * x [i-j];
}
}
要查看代码在做什么,请将计算更改为printf
s,如下所示:
for(int i = 0; i < 7; i++)
{
printf("y[%d] = 0n", i);
for(int j = 0; j <= i; j++)
{
printf("y[%d] += h[%d] * x[%d]n", i, j, i-j);
}
printf("n");
}
该代码的输出(添加注释(为:
y[0] = 0
y[0] += h[0] * x[0]
y[1] = 0
y[1] += h[0] * x[1]
y[1] += h[1] * x[0]
y[2] = 0
y[2] += h[0] * x[2]
y[2] += h[1] * x[1]
y[2] += h[2] * x[0]
y[3] = 0
y[3] += h[0] * x[3]
y[3] += h[1] * x[2]
y[3] += h[2] * x[1]
y[3] += h[3] * x[0]
y[4] = 0
y[4] += h[0] * x[4] // zero x
y[4] += h[1] * x[3]
y[4] += h[2] * x[2]
y[4] += h[3] * x[1]
y[4] += h[4] * x[0] // zero h
y[5] = 0
y[5] += h[0] * x[5] // zero x
y[5] += h[1] * x[4] // zero x
y[5] += h[2] * x[3]
y[5] += h[3] * x[2]
y[5] += h[4] * x[1] // zero h
y[5] += h[5] * x[0] // zero h
y[6] = 0
y[6] += h[0] * x[6] // zero x
y[6] += h[1] * x[5] // zero x
y[6] += h[2] * x[4] // zero x
y[6] += h[3] * x[3]
y[6] += h[4] * x[2] // zero h
y[6] += h[5] * x[1] // zero h
y[6] += h[6] * x[0] // zero h
注释的计算只是浪费时间,因为h
值或x
值都将为零。为了避免浪费计算,代码需要调整j
的起始值和结束值。
当i<=3
时,j
的起始值为0
,否则起始值为i-3
i<=3
时,j
的结束值为i
,否则结束值为3
。
因此,循环应该是这样的:
for(int i = 0; i < 7; i++)
{
printf("y[%d] = 0n", i);
int start = (i <= 3) ? 0 : i-3;
int end = (i <= 3) ? i : 3;
for(int j = start; j <= end; j++)
{
printf("y[%d] += h[%d] * x[%d]n", i, j, i-j);
}
printf("n");
}
输出为:
y[0] = 0
y[0] += h[0] * x[0]
y[1] = 0
y[1] += h[0] * x[1]
y[1] += h[1] * x[0]
y[2] = 0
y[2] += h[0] * x[2]
y[2] += h[1] * x[1]
y[2] += h[2] * x[0]
y[3] = 0
y[3] += h[0] * x[3]
y[3] += h[1] * x[2]
y[3] += h[2] * x[1]
y[3] += h[3] * x[0]
y[4] = 0
y[4] += h[1] * x[3]
y[4] += h[2] * x[2]
y[4] += h[3] * x[1]
y[5] = 0
y[5] += h[2] * x[3]
y[5] += h[3] * x[2]
y[6] = 0
y[6] += h[3] * x[3]
这避免了浪费的计算,并且消除了填充h
和x
阵列的需要。
您可以修改函数,使其仅在索引位于有效范围内时计算值:
int x[4], h[4], y[7];
for (i = 0; i < 4; i++) {
if (i < 4) {
x[i] = i + 1;
h[i] = i + 1;
}
}
for (j = 0; j < 4; j++) {
if (i - j > 0 && i - j < 4) {
y[i] = y[i] + h[j] * x[i - j];
}
}
这将简单地丢弃数据和滤波器系数范围之外的所有值。