67 lines
1.6 KiB
JavaScript
67 lines
1.6 KiB
JavaScript
const ZSCORE_CRITICAL_THRESHOLD = 1.96; // 95-percentile
|
|
const ZSCORE_NINETYNINTH = 2.326347875; // 99-percentile
|
|
const ONE_DIV_SQRT_2PI = 0.3989422804014327; // V8 float of 1/SQRT(2 * PI)
|
|
const MAX_P_PRECISION = Math.exp(-16); // Rought estimation of V8 precision, -16 is 1.1253517471925912e-7
|
|
const MIN_P = -6.44357455534; // v8 float 0.0...0
|
|
const MAX_P = 6.44357455534; // v8 float 1.0...0
|
|
|
|
const getMean = (numArr) => {
|
|
let total = 0;
|
|
let length = numArr.length; // store local to reduce potential prop lookups
|
|
|
|
for (let i = 0; i < length; i++) {
|
|
total += numArr[i];
|
|
}
|
|
|
|
return total / length;
|
|
};
|
|
|
|
const getStandardDeviation = (numArr, mean) => {
|
|
return Math.sqrt(numArr.reduce((sq, n) => (
|
|
sq + Math.pow(n - mean, 2)
|
|
), 0) / (numArr.length - 1));
|
|
};
|
|
|
|
const getInformationFromValues = (numArr) => {
|
|
let mean = getMean(numArr);
|
|
|
|
return {
|
|
mean,
|
|
standardDeviation: getStandardDeviation(numArr, mean),
|
|
};
|
|
};
|
|
|
|
const getZScore = (value, mean, sDeviation) => (sDeviation !== 0 ? (value - mean) / sDeviation : 0);
|
|
|
|
const getFastPValue = (zScore) => {
|
|
if (zScore <= MIN_P) {
|
|
return 0;
|
|
}
|
|
if (zScore >= MAX_P) {
|
|
return 1;
|
|
}
|
|
|
|
let factorialK = 1;
|
|
let k = 0;
|
|
let sum = 0;
|
|
let term = 1;
|
|
|
|
while (Math.abs(term) > MAX_P_PRECISION) {
|
|
term = ONE_DIV_SQRT_2PI * Math.pow(-1, k) * Math.pow(zScore, k) / (2 * k + 1) / Math.pow(2, k) * Math.pow(zScore, k + 1) / factorialK;
|
|
sum += term;
|
|
k++;
|
|
factorialK *= k;
|
|
}
|
|
sum += 0.5;
|
|
|
|
return sum;
|
|
};
|
|
|
|
const getWeight = (zScore, pValue) => (zScore * pValue);
|
|
|
|
module.exports = {
|
|
getInformationFromValues,
|
|
getZScore,
|
|
getFastPValue,
|
|
getWeight,
|
|
};
|