Внедрение FIR-фильтрации без заполнения - PullRequest
1 голос
/ 28 февраля 2020

Можно ли реализовать действие 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];
    }
 }

Ответы [ 2 ]

1 голос
/ 28 февраля 2020

Чтобы увидеть, что делает ваш код, измените вычисления на printf s, например:

for(int i = 0; i < 7; i++)
{
    printf("y[%d] = 0\n", 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] = 0\n", 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.

0 голосов
/ 28 февраля 2020

Вы можете изменить свою функцию так, чтобы она вычисляла значение только тогда, когда индексы находятся в допустимых диапазонах:

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

Это просто отбрасывает все значения, которые находятся за пределами диапазона данных и коэффициентов фильтра.

...