Skip to content

Instantly share code, notes, and snippets.

Embed
What would you like to do?
this.getReducedSTD = function(dimensionGroup, variable) {
// see https://en.wikipedia.org/wiki/Algorithms_for_calculating_variance#Decremental_algorithm
var reduceAdd = function (p, v) {
var obj = p;
var value = +v.variables[variable];
if( _.isNaN(value) ) {
//pass
} else {
obj.n = obj.n + 1;
var oldM2 = obj.M2;
var delta = value - obj.mean;
obj.mean = obj.mean + delta/obj.n;
obj.M2 = obj.M2 + delta*(value - obj.mean);
if( obj.M2 < 0 ) {
console.log("ADD passed to negative", variable, oldM2, "delta=", delta, JSON.stringify(obj));
}
}
// console.log("--> ADD", p.n, variable, JSON.stringify(p.valueOf()));
// console.log("--> ADD", JSON.stringify(p), "V = ", v);
return p;
};
var reduceRemove = function (p, v) {
var obj = p;
var value = +v.variables[variable];
if( _.isNaN(value) || obj.n < 2 ) {
//pass
} else {
obj.n = obj.n - 1;
var oldM2 = obj.M2;
var oldMean = obj.mean;
var delta = value - obj.mean;
obj.mean = obj.mean - delta/obj.n;
obj.M2 = obj.M2 - delta*(value - obj.mean);
if( obj.M2 < 0 ) {
console.log("REMOVE passed to negative", variable, oldM2, "delta=", delta, JSON.stringify(obj));
}
}
// console.log("--> REMOVE", p.n, variable, JSON.stringify(p.valueOf()));
// console.log("--> REMOVE", JSON.stringify(p), "V = ", v);
return p;
};
var reduceInitial = function () {
var p = {};
var obj = p;
obj.n = 0;
obj.mean = 0;
obj.M2 = 0;
obj.valueOf = function() {
var variance = (obj.n < 2) ? 0 : obj.M2 / (obj.n-1),
stddev = Math.sqrt(variance);
return {
variance: variance,
stddev: stddev,
mean: obj.mean
};
};
return p;
};
return dimensionGroup.reduce(reduceAdd, reduceRemove, reduceInitial);
};
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment