Skip to content

Instantly share code, notes, and snippets.

@jaandrle
Last active March 21, 2021 21:57
Show Gist options
  • Save jaandrle/4589bcac955d01dc609c0ce4fd624fea to your computer and use it in GitHub Desktop.
Save jaandrle/4589bcac955d01dc609c0ce4fd624fea to your computer and use it in GitHub Desktop.
Geothmetic Meandian comparing with others (implementation `gmdn` in JavaScript)
const means= (()=>{
return { gmdn, median, meanArithmetic, meanGeometric };
/* See
* https://xkcd.com/2435/
* https://www.explainxkcd.com/wiki/index.php/2435:_Geothmetic_Meandian
* For sure, this is a joke!
* Stats tip: If you aren't sure whether to use the mean, median,
* or geometric mean, just calculate all three, then repeat until it converges
*/
function gmdn(vector, max_iterations= 10, precision= 0.00000001, l= vector.length){
if(l<2) return vector[0];
vector= gmdnNth(vector, l);
while(--max_iterations&&!isDiagonal(vector, precision))
vector= gmdnNth(vector, 3);
return vector[0];
}
/* eg. [ x, x, x ] */
function isDiagonal(vector, precision){
const { abs, min, max }= Math;
return abs(max(...vector)-min(...vector)) <= precision;
}
function gmdnNth(vector, l= vector.length){
return [ meanArithmetic(vector, l), meanGeometric(vector, l), median(vector, l) ];
}
function median(vector, l= vector.length){
if(l<2) return vector[0];
const vector_sorted= [...vector].sort();
if(l%2) return vector_sorted[(l-1)/2];
const quotient= l/2;
return (vector_sorted[quotient-1]+vector_sorted[quotient])/2;
}
function meanGeometric(vector, l= vector.length){
if(l<2) return vector[0];
return Math.pow(vector.reduce((acc, v)=> acc*v), 1/l);
}
function meanArithmetic(vector, l= vector.length){
if(l<2) return vector[0];
return vector.reduce((acc, v)=> acc+v, 0)/l;
}
})();
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment