I am currently working with moving average and use an algorithm to calculate it quickly on the fly:
public void AddPoint(double input)
{
Value += (input - Value) / (dataLength * divergenceCorrection);
}
I noticed that the average can lag behind quite a bit as opposed to calculating it truely for each value.
Example:
double[] values = new double[] { 10, 10, 10, 10, 10, 2, 2, 2, 2, 2 };
double value = 0;
foreach(double num in values)
{
value += (num - value) / (5 * 1);
}
-> result: 3.54.. as opposed to 2
this becomes more prevalent if the array was
{ 100000, 100000, 100000, 100000, 100000, 2, 2, 2, 2, 2 }
-> 22031, which is waaaay off the chart vs (2+2+2+2+2)/5
For this reason, I started with experimenting with divergenceCorrection in an attempt to bring down the decay closer to the targeted length:
double[] values = new double[] { 100000, 100000, 100000, 100000, 100000, 2, 2, 2, 2, 2 };
double value = 0;
foreach(double num in values)
{
value += (num - value) / (5 * 0.25);
}
-> 33
I believe this might have different implications on the outcome so I wonder what the apropriate way to do this.
A solution could be like this but I will use this function on embedded systems as well. The low memory would restrict me a lot for either data legth or resolution (when pooling values)
double[] values = new double[] { 100000, 100000, 100000, 100000, 2, 2, 2, 2, 2 };
Queue<double> queue = new Queue<double>();
double value = 100000;
// prime queue with first value
for(int i = 0; i < 5; i++)
{
queue.Enqueue(value / 5);
}
// formula
double tempVal = double.NaN;
foreach(double num in values)
{
tempVal = num/5;
value += tempVal;
queue.Enqueue(tempVal);
value -= queue.Dequeue();
}
Note: the input is live fed sensor data, which is why I have to store the values in memory.