Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Calculate rolling / moving average in C++

I know this is achievable with boost as per:

Using boost::accumulators, how can I reset a rolling window size, does it keep extra history?

But I really would like to avoid using boost. I have googled and not found any suitable or readable examples.

Basically I want to track the moving average of an ongoing stream of a stream of floating point numbers using the most recent 1000 numbers as a data sample.

What is the easiest way to achieve this?


I experimented with using a circular array, exponential moving average and a more simple moving average and found that the results from the circular array suited my needs best.

like image 841
goji Avatar asked Jun 12 '12 04:06

goji


People also ask

How do you calculate moving average in C++?

Calculate the moving average in C++ For calculating we need to make sure that all the declared elements are as per the requirement of the programmer. We also need to confirm that value of sum and average is initialized with zero else it may use the garbage value because of which the answer may vary.


1 Answers

If your needs are simple, you might just try using an exponential moving average.

http://en.wikipedia.org/wiki/Moving_average#Exponential_moving_average

Put simply, you make an accumulator variable, and as your code looks at each sample, the code updates the accumulator with the new value. You pick a constant "alpha" that is between 0 and 1, and compute this:

accumulator = (alpha * new_value) + (1.0 - alpha) * accumulator 

You just need to find a value of "alpha" where the effect of a given sample only lasts for about 1000 samples.

Hmm, I'm not actually sure this is suitable for you, now that I've put it here. The problem is that 1000 is a pretty long window for an exponential moving average; I'm not sure there is an alpha that would spread the average over the last 1000 numbers, without underflow in the floating point calculation. But if you wanted a smaller average, like 30 numbers or so, this is a very easy and fast way to do it.

like image 133
steveha Avatar answered Sep 21 '22 01:09

steveha