diff --git a/.vscode/settings.json b/.vscode/settings.json new file mode 100644 index 0000000..a4df25f --- /dev/null +++ b/.vscode/settings.json @@ -0,0 +1,3 @@ +{ + "cSpell.words": ["Stdev"] +} diff --git a/lib/findPaths.js b/lib/findPaths.js index 7f20757..947397f 100644 --- a/lib/findPaths.js +++ b/lib/findPaths.js @@ -5,6 +5,7 @@ import { formatLargeOrSmall, avg, hackyGeomMean, + getCoefficientOfVariation, } from "../lib/utils.js"; /* Functions */ @@ -301,6 +302,7 @@ export function CreateTable({ tableRows }) { Possible relative values     geomMean(relative values) + Coefficient of variation @@ -317,6 +319,9 @@ export function CreateTable({ tableRows }) { {formatLargeOrSmall(hackyGeomMean(row.distances))} + + {formatLargeOrSmall(getCoefficientOfVariation(row.distances))} + ))} diff --git a/lib/utils.js b/lib/utils.js index 5d48779..db131e8 100644 --- a/lib/utils.js +++ b/lib/utils.js @@ -117,3 +117,26 @@ export function conservativeNumMergeSortSteps(n) { // export const geomMean = (arr) => arr.reduce((a, b) => a * b, 1); // ^ (1 / arr.length); // didn't work so well for low numbers. export const increasingList = (n) => Array.from(Array(n).keys()); + +function getStdev(arr) { + if (Array.isArray(arr) && arr.length > 0) { + const n = arr.length; + const mean = arr.reduce((a, b) => a + b) / n; + return Math.sqrt( + arr.map((x) => Math.pow(x - mean, 2)).reduce((a, b) => a + b) / n + ); + } else { + return 0; + } +} + +export const getCoefficientOfVariation = (arr) => { + let nonPositiveNumbers = arr.filter((x) => x <= 0); + if (nonPositiveNumbers.length == 0) { + let gm = geomMean(arr); + let stdev = getStdev(arr); + return stdev / gm; + } else { + return getStdev(arr) / avg(arr); + } +};