Running Average
Live example of http://stackoverflow.com/questions/12636613/how-to-calculate-moving-average-without-keeping-the-count-and-data-total
by drzaus
HTML
<pre id="log"></pre>
JavaScript
(function(){
// just so we can see something, in console too
var $log = document.getElementById('log');
function log(args) {
args = Array.prototype.slice.call(arguments);
console.log.apply(console, args);
var msg = args[0].replace(/\%d/g, '%s');
if(args.length > 1) {
var tokens = args.slice(1);
for(var i = 0; i < tokens.length; i++) msg = msg.replace('%s', tokens[i])
}
$log.innerHTML = $log.innerHTML + '\n' + msg;
}
// populate base list
var list = [];
function getSeedNumber() { return Math.random()*100; }
for(var i = 0; i < 50; i++) list.push( getSeedNumber() );
// our calculation functions, for comparison
function calcNormalAvg(list) {
// sum(list) / len(list)
return list.reduce(function(a, b) { return a + b; }) / list.length;
}
function calcRunningAvg(previousAverage, currentNumber, index) {
// [ avg' * (n-1) + x ] / n
return ( previousAverage * (index - 1) + currentNumber ) / index;
}
function calcMovingAvg(accumulator, new_value, alpha) {
return (alpha * new_value) + (1.0 - alpha) * accumulator;
}
// start our baseline
var baseAvg = calcNormalAvg(list);
var runningAvg = baseAvg, movingAvg = baseAvg;
log('base avg: %d', baseAvg);
var okay = true;
// table of output, cleaner console view
var results = [];
// add 10 more numbers to the list and compare calculations
for(var n = list.length, i = 0; i < 10; i++, n++) {
var newNumber = getSeedNumber();
runningAvg = calcRunningAvg(runningAvg, newNumber, n+1);
movingAvg = calcMovingAvg(movingAvg, newNumber, 1/(n+1));
list.push(newNumber);
baseAvg = calcNormalAvg(list);
// assert and inspect
log('added [%d] to list at pos %d, running avg = %d vs. regular avg = %d (%s)'
, newNumber, list.length, runningAvg, baseAvg, runningAvg == baseAvg
)
results.push( {x: newNumber, n:list.length, regular: baseAvg, running: runningAvg, moving: movingAvg, eqRun: baseAvg == runningAvg, eqMov: baseAvg == movingAvg } );
...