Created
August 8, 2017 14:28
-
-
Save spencerwilson/1fd612464829f2b7b9acb04c5e22e203 to your computer and use it in GitHub Desktop.
Discrete stats fns
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/** | |
* @typedef Point | |
* A pair of numbers suitable for plotting. | |
*/ | |
/** | |
* @param {Array.<number>} arr | |
* n observations of a continuous random variable (RV). | |
* @returns {Array.<Point>} | |
* The empirical probabilities of the given observed values of the RV. | |
* @see https://en.wikipedia.org/wiki/Empirical_probability | |
*/ | |
function emp(arr) { | |
if (arr.length === 1) { | |
return [[arr[0], 1]]; | |
} | |
arr.sort(); | |
let result = []; | |
let count = 1; | |
for (let i = 1; i < arr.length; i++) { | |
if (arr[i - 1] === arr[i]) { | |
count++; | |
} | |
else { | |
result.push([arr[i - 1], count / arr.length]); | |
count = 1; | |
} | |
} | |
// Get the last data point | |
result.push([arr[arr.length - 1], count / arr.length]); | |
return result; | |
} | |
test(emp, [3], [[3, 1]]); | |
test(emp, [1, 3, 2, 1, 2], [[1, 0.4], [2, 0.4], [3, 0.2]]); | |
/** | |
* @param {Array.<number>} arr | |
* n observations of a continuous random variable (RV). | |
* @returns {Array.<Point>} | |
* The empirical distribution function of the given observations. | |
* @see https://en.wikipedia.org/wiki/Empirical_distribution_function | |
*/ | |
function edf(arr) { | |
return emp(arr).reduce((acc, [value, prb], i) => { | |
const firstPoint = (i === 0); | |
const currentPrb = firstPoint ? prb : (acc[i - 1][1] + prb); | |
acc.push([value, currentPrb]); | |
return acc; | |
}, []); | |
} | |
test(edf, [3], [[3, 1]]); | |
test(edf, [1, 3, 2, 1, 2], [[1, 0.4], [2, 0.8], [3, 1]]); | |
function arrEq(a1, a2) { | |
if (a1.length !== a2.length) return false; | |
return a1.every((_, i) => { | |
// Be able to compare both array elements and number elements | |
switch (typeof a1[i]) { | |
case 'object': return arrEq(a1[i], a2[i]); | |
case 'number': return a1[i] === a2[i]; | |
} | |
}) | |
} | |
function test(fn, arr, expected) { | |
const actual = fn(arr); | |
const match = arrEq(expected, actual); | |
if (!match) throw new Error(`Expected ${expected}, got ${actual}`); | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment