c-无填充FIR滤波的实现



是否可以在不填充输入和系数的情况下实现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];
}
}

要查看代码在做什么,请将计算更改为printfs,如下所示:

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]

这避免了浪费的计算,并且消除了填充hx阵列的需要。

您可以修改函数,使其仅在索引位于有效范围内时计算值:

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];
}
}

这将简单地丢弃数据和滤波器系数范围之外的所有值。

最新更新