Thread: Help with Arrays and Moving Averages

  1. #1
    Registered User
    Join Date
    Mar 2007
    Posts
    8

    Help with Arrays and Moving Averages

    Hello all,

    I'm writing a code that generates sine waves, adds random noise, and then cleans it up by averaging those values. I've got it so it averages every 3 values using a sliding point window, however I need to write it as an array and to tell the truth, I'm stumped. I understand what to do...I just can't think of how to implement that in C.


    Code:
    /* Alexander DeTrano
     This program generates normal sine waves then creates noise using random
     numbers and the "cleans up the wave" by a series of averages and then plots
     them on screen.  When N = 40000 a high pitched noise is created intitally and
     then when the wave with noise is added, a static is picked  up, then the
     averaged values clean it up and reduce some static.
    */
    #include <stdio.h>
    #include <math.h>
    #include <stdlib.h>
    #include <time.h>
    #define N 40000
    double r, pi, f = 1500, w, t ; 
    int i; int n=N;
    void create_sine(double y[], int n)
    {
       for ( i = 0; i < n; ++i )
       {
          t = i/8000.0;
          y[i] =  sin(w*t);
       }
    }
    void print_array(double y[], int n)
    {
       for ( i=0; i<n; ++i )
       {
          printf("%f\n",y[i]);
       }
    }
    void add_noise(double y[], int n)
    {
     for( i=0; i<n; ++i)
      {
      r = 2*(rand()/(RAND_MAX+1.0)) - 1;
      t = i/8000.0;
      y[i]=r + sin(w*t);
      }
    } 
    void avgm( double y[], int n, int m)
    /* this is my old function using constant values for the moving point window.
     * Basically a0 a1 and a2 need to go inside an array that's size m and have
       them averaged similar to how they are averaged here  */
    
    { double a0=0, a1=0, a2=0;
      for (i=0;i<n;++i)
       {
        a0=a1;
        a1=a2;
        a2=y[i];
        y[i]=(a0+a1+a2)/3.0;
       }
    }
     
    int main( void)
    {
       int seed; double y[N]; int m;
       void create_sine(double y[], int n);
       void print_array(double y[], int n);
       void add_noise(double y[], int n);
       void avgm(double y[], int n, int m);
       pi = 4*atan(1);
       w = 2*pi*f;
       seed = time(0);
       srand(seed);
       create_sine( y, N);  
       print_array( y, N);
       add_noise(   y, N);
       print_array( y, N);
       avgm( y, N, 3);
        print_array( y, N);   
    return 0;
    }
    Any help would be greatly appreciated!

    Cheers,
    Alexander
    Last edited by Dave_Sinkula; 04-25-2007 at 07:33 PM. Reason: The magic of line wrap in comments.

  2. #2
    ATH0 quzah's Avatar
    Join Date
    Oct 2001
    Posts
    14,826
    What is it that you don't know how to do exactly?


    Quzah.
    Hope is the first step on the road to disappointment.

  3. #3
    Registered User
    Join Date
    Mar 2007
    Posts
    8
    Alright, the code as it stands uses a sliding point windows, see how a0=a1 and then a1=a2 and then a2=y[i], and then the new y[i] value is the average of those three? Well that's good for a 3 point moving average...but if I wanted to do it with say 5 points, I'd have to add a3 and a4...I don't want to have to manually add these variables, I want them to be created in an array of size m...in this case the array is size 3. So the array needs to be created and do the same averaging technique as before. Sorry if I wasn't clear before.

  4. #4
    ATH0 quzah's Avatar
    Join Date
    Oct 2001
    Posts
    14,826
    Use an array of pointers to type. Or a pointer to a pointer to type. Say you know your run length will be 100, but each of the elements in the run will range from 0 to 10. Now you could do an array of 100x10, or, you could use an array of pointers to type, and allocate each number / list as you run across them:
    Code:
    int *pa[ 100 ];
    size_t x;
    int n;
    
    for( x = 0; x < 100; x++ )
    {
        puts( "Enter the number of items here." );
        if( scanf( "&#37;d", &n ) == 1 )
        {
            pa[ x ] = malloc( sizeof( int ) * n );
            readnumbers( pa[ x ], n ); /* simplified for post length */
        }
    }
    If you're not sure how long your run is (where I used 100), or how long each is, you can prompt for that too, by using a pointer to pointer instead:
    Code:
    int **pa;
    ...
    puts( "How many?" );
    n = getnumber();
    pa = malloc( n * sizeof *pa ); /* allocate the run length */
    ... now allocate each one as I did earlier ...
    Then all you have to do is remember how long each sub-list is. You could use another array to store the length of each, or you could have allocated an extra element in each one (say the first one), and use it to store its length:
    Code:
    for( x = 0; x < array[ 0 ][ y ]; x++ )
    {
        printf( "array[ %d ][ y ] is %d\n", x + 1, array[ x + 1 ][ y ] );
    }
    Where this would be nested in a loop that ran through the length of the run. Now were I doing it this way, if my "usable" length was 3, I would have actually 4 element, but the value of the first spot, which was storing the length, wouldn't count itself as part of the length. So in this case, it would store 3, instead of 4.

    Search the forum for multi-dimensional arrays or dynamic arrays or something like that, and you should find plenty of hits on how to make and free them, because it gets asked all the time.


    Quzah.
    Hope is the first step on the road to disappointment.

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Conversion string to arrays
    By KoG Metalgod in forum C Programming
    Replies: 11
    Last Post: 05-18-2007, 11:06 PM
  2. Freecell game
    By SmellsLikeToast in forum C++ Programming
    Replies: 7
    Last Post: 12-10-2006, 04:01 PM
  3. I have a function and I need multiple averages returned
    By tommy69 in forum C++ Programming
    Replies: 20
    Last Post: 04-13-2004, 11:45 AM
  4. moving arrays
    By Unregistered in forum C++ Programming
    Replies: 1
    Last Post: 02-17-2002, 03:04 PM
  5. moving n-dimentional arrays in c++
    By kknla in forum C++ Programming
    Replies: 0
    Last Post: 02-06-2002, 05:15 PM