2

I have a homework to implement an FIR filter in C and I wonder whether you think I understood the assignment correctly. The program I wrote that I think solves the problem is:

#include <stdio.h>
float FIRfloats[5];
void floatFIR(float newsample)
{
  int i;
  float sum=0;

  FIRfloats[0]=newsample*0.0299;
  FIRfloats[1]=FIRfloats[2]*0.4701;
  FIRfloats[2]=FIRfloats[3]*0.4701;
  FIRfloats[3]=FIRfloats[4]*0.0299;

  /* sum */
   for(i=0;i<5;i++)
  {
    sum=sum+FIRfloats[i];
  }
  printf("Sum: %f\n", sum);
}

int main ()
{

  float n=0.0f; 
  while (scanf("%f", &n) > 0)
  {
  floatFIR(n);
  }
  return 0;
}

And the specification is

Before a new sample xk arrives the old samples are shifted to the right and then each sample is scaled with a coefficient before the result yk, the total sum of all scaled samples, is calculated

Coefficients should be c0=0.0299, c1=0.4701, c2=0.4701, c3=0.0299.

Do you think that I solved the assignment correctly? I think it seemed too easy and therefore I wonder.

Niklas Rosencrantz
  • 25,640
  • 75
  • 229
  • 424
  • Can't see any shifting. You seem to be scaling a single value. Surely you should be inputting several values and then scaling when you have enough values? – Neil Sep 30 '13 at 11:43
  • 1
    what is FIRfloats[2], FIRfloats[3] and FIRfloats[4] at initial condition, Is it zero? Is it correct? – dexterous Sep 30 '13 at 11:52
  • The delays should be for the input only, without multiplication with the coefficients. The coefficients should be used in your sum loop instead. See diagram in: http://en.wikipedia.org/wiki/Finite_impulse_response – bavaza Sep 30 '13 at 12:05
  • @SHREYASJOSHI arent those _always_ initialized to `0.0f` if no specific value initializer is given? see: http://stackoverflow.com/questions/3803153/what-are-primitive-types-default-initialized-to-in-c – Daan Timmer Sep 30 '13 at 13:36

1 Answers1

2

I'm afraid the implementation provided in the question will not provide the correct results.

In FIR (Finite Impulse Response) filter with 4 coefficients the output series (y) for input series (x) is:

y[t] = c0*x[t] + c1*x[t-1] + c2*x[t-2] + c3*x[t-3]

Therefore the implementation should be similar to:

/* add includes (stdio.h and whatever else you'll need...) */

float floatFIR(float inVal, float* x, float* coef, int len)
{
    float y = 0.0;
    for (int i = (len-1) ; i > 0 ; i--)
    {
         x[i] = x[i-1];
         y = y + (coef[i] * x[i]);
    }
    x[0] = inVal;
    y = y + (coef[0] * x[0]);
    return y;
}

main(int argc, char** argv)
{
    float coef[4] = {0.0299, 0.4701, 0.4701, 0.0299};
    float x[4] = {0, 0, 0, 0}; /* or any other initial condition*/
    float y;
    float inVal;

    while (scanf("%f", &inVal) > 0)
    {
        y = floatFIR(inVal, x, coef, 4);
    }
    return 0;

}

This does the shift and multiplication at the same loop (which does not affect results - only is more efficient.) If you want to follow the spec exactly, you can change floatFir like this:

float floatFIR(float inVal, float* x, float* coef, int len)
{
    float y = 0.0;
    for (int i = (len-1) ; i > 0 ; i--)
    {
         x[i] = x[i-1];
    }
    x[0] = inVal;

    for (int i = 0 ; i < len ; i++)
    {
        y = y + (coef[i] * x[i]);
    }
    return y;
}
Avi Perel
  • 422
  • 3
  • 8