Thread: Trying to calculate a running average

  1. #1
    Registered User
    Join Date
    Oct 2011
    Posts
    41

    Trying to calculate a running average

    I am trying to figure out how to keep a running average of the last 5 temps read in. I don't know how/where to reset my counter to 0 or increment it? Will something like the code below work to keep a running average of last 5 values read in?

    Code:
    Average()
    {
    int loop_counter= 0;
    while (!0)
    {
    Current_Temp= Get_Temp():
    Temp_Array[loop_counter] = Current_Temp;
    
         
        if ((loop_counter % 4) == 0)
         {
    
          Temp_Avg = Calculate_Average(Temp_Array);
         loop_counter = 0;
         }
         
    loop_counter++;
    }
    }

  2. #2
    Registered User
    Join Date
    Dec 2017
    Posts
    943
    Maybe something like this. Fill up a 5 element array and use its sum to calculate the average. Cycle around the elements subtracting the value at the current index from the sum and adding in the new temperature (and storing it at the current index). I just left it in an infinite loop for testing.
    Code:
    #include <stdio.h>
     
    #define NumTempsToAvg  5
     
    double GetTemp() {
        printf("temp: ");
        double d = 0.0;
        scanf("%lf", &d);
        return d;
    }
     
    void average() {
        double temps[NumTempsToAvg];
        double sum = 0.0;
     
        for (int i = 0; i < NumTempsToAvg; i++) {
            temps[i] = GetTemp();
            sum += temps[i];
        }
     
        for ( ; ; ) {
            for (int i = 0; i < NumTempsToAvg; i++) {
                printf("avg: %f\n", sum / NumTempsToAvg);
                sum -= temps[i];
                temps[i] = GetTemp();
                sum += temps[i];
            }
        }
    }
     
    int main() {
        average();
    }
    If you want the truth to stand clear before you, never be for or against. - Sent-ts'an

  3. #3
    Registered User
    Join Date
    Oct 2011
    Posts
    41
    Quote Originally Posted by john.c View Post
    Maybe something like this. Fill up a 5 element array and use its sum to calculate the average. Cycle around the elements subtracting the value at the current index from the sum and adding in the new temperature (and storing it at the current index). I just left it in an infinite loop for testing.
    Code:
    #include <stdio.h>
     
    #define NumTempsToAvg  5
     
    double GetTemp() {
        printf("temp: ");
        double d = 0.0;
        scanf("%lf", &d);
        return d;
    }
     
    void average() {
        double temps[NumTempsToAvg];
        double sum = 0.0;
     
        for (int i = 0; i < NumTempsToAvg; i++) {
            temps[i] = GetTemp();
            sum += temps[i];
        }
     
        for ( ; ; ) {
            for (int i = 0; i < NumTempsToAvg; i++) {
                printf("avg: %f\n", sum / NumTempsToAvg);
                sum -= temps[i];
                temps[i] = GetTemp();
                sum += temps[i];
            }
        }
    }
     
    int main() {
        average();
    }
    So I got a little bit more information. It should be a running average will each time a new value is read in, an average is calculated on the last 5 readings, by replacing the oldest value read in. Can you please help with this?
    Last edited by knik653; 10-31-2018 at 03:41 PM.

  4. #4
    and the Hat of Guessing tabstop's Avatar
    Join Date
    Nov 2007
    Posts
    14,336
    Quote Originally Posted by knik653 View Post
    So I got a little bit more information. It should be a running average will each time a new value is read in, an average is calculated on the last 5 readings, by replacing the oldest value read in. Can you please help with this?
    That is, in fact, what's up there!

  5. #5
    Registered User
    Join Date
    Dec 2017
    Posts
    943
    Now that I think about it, the above procedure will presumably accumulate errors. Since there's only 5 values, you could just add them all up every time. If the above procedure is used you should maybe sum the whole array every 250th (or whatever) iteration so the error doesn't get too big.
    If you want the truth to stand clear before you, never be for or against. - Sent-ts'an

  6. #6
    Registered User
    Join Date
    May 2010
    Posts
    4,539
    Doesn't a running average usually use a circular buffer?

  7. #7
    Registered User
    Join Date
    Dec 2017
    Posts
    943
    Yes, but if you do it the way I did it (subtract the oldest from the sum, add in the newest) then you will accumulate errors from the actual sum of the array (kind of a drunkards walk up and down but ultimately away from the true value).
    If you want the truth to stand clear before you, never be for or against. - Sent-ts'an

  8. #8
    Registered User
    Join Date
    May 2010
    Posts
    4,539
    Yes, but if you do it the way I did it (subtract the oldest from the sum, add in the newest) then you will accumulate errors
    So don't subtract and add, just replace the oldest value and recompute the sum and average. You're only talking about 5 numbers so the time shouldn't be an issue in most cases.

  9. #9
    Registered User
    Join Date
    Dec 2017
    Posts
    943
    In this case, sure, but if you had a lot of values you might only want to recompute the true average every nth iteration. That's all I was saying.
    If you want the truth to stand clear before you, never be for or against. - Sent-ts'an

  10. #10
    Registered User
    Join Date
    Oct 2011
    Posts
    41
    Quote Originally Posted by john.c View Post
    Yes, but if you do it the way I did it (subtract the oldest from the sum, add in the newest) then you will accumulate errors from the actual sum of the array (kind of a drunkards walk up and down but ultimately away from the true value).
    But don't you have to rotate the the other values?
    I having a hard time wrapping my mind around this.
    I get to read in one value at a time

  11. #11
    and the Hat of Guessing tabstop's Avatar
    Join Date
    Nov 2007
    Posts
    14,336
    Quote Originally Posted by knik653 View Post
    But don't you have to rotate the the other values?
    I having a hard time wrapping my mind around this.
    I get to read in one value at a time
    You could rotate the values, if you are sufficiently bored. Generally though you just keep track of where the oldest value is, and replace that value.

  12. #12
    Registered User
    Join Date
    Oct 2011
    Posts
    41
    Quote Originally Posted by tabstop View Post
    You could rotate the values, if you are sufficiently bored. Generally though you just keep track of where the oldest value is, and replace that value.
    Any hints on how to keep track of the oldest?

  13. #13
    and the Hat of Guessing tabstop's Avatar
    Join Date
    Nov 2007
    Posts
    14,336
    Quote Originally Posted by knik653 View Post
    Any hints on how to keep track of the oldest?
    It starts at 0, then goes up by one each time, until you get to the end, and then it becomes zero again.

  14. #14
    Registered User
    Join Date
    May 2010
    Posts
    4,539
    I having a hard time wrapping my mind around this.
    Yea, doing a running average can get a little confusing. I started out creating a structure to "house" the CircularBuffer, something like:
    Code:
    #define MAX_ITEMS 5
    
    typedef struct CircularBuffer
    {
        int max_items;
        int items[MAX_ITEMS];
        int current_index;
        int num_items;
    } CircularBuffer;
    
    void init_buffer(CircularBuffer* buffer);
    double average(CircularBuffer* buffer, int value);
    The first function is to "initialize" the buffer to the starting values, zero for everything except max_items which should be the same as the array size, this function should be fairly easy.

    The second function is where the "magic" takes place. It handles placing the "new" value into the array and modifying the current_index (insuring that this value stays within the bounds of the array) when this variable reaches the end of the array it is reset to zero to start back at the beginning of the array for the next value.

    The num_items variable keeps track of how many items are actually in the array and is used to compute the average. This value will increment until it reaches the size of the array, then it stays constant.

    Hopefully this gives you enough hints.

  15. #15
    Registered User
    Join Date
    Oct 2011
    Posts
    41
    Quote Originally Posted by tabstop View Post
    It starts at 0, then goes up by one each time, until you get to the end, and then it becomes zero again.

    This is what I need to do and I get one value at a time.

    /* if first time /
    * set all array values to current value
    * return average equals to current value
    */

    /* else
    * replace the oldest array value with current value
    * calculate average
    */

    I really can't figure it out how to keep track of the loop counter to know what position to replace and how to reset the loop count to zero
    Last edited by knik653; 11-02-2018 at 02:22 PM.

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. How to calculate the average of scores?
    By david.jones in forum C Programming
    Replies: 4
    Last Post: 05-02-2011, 06:33 AM
  2. Replies: 26
    Last Post: 08-19-2009, 07:59 AM
  3. calculate average
    By archriku in forum C Programming
    Replies: 23
    Last Post: 04-10-2009, 04:27 AM
  4. calculate average from a file
    By mrsirpoopsalot in forum C++ Programming
    Replies: 11
    Last Post: 01-20-2009, 02:25 PM

Tags for this Thread