distriprob
Version:
A library for calculating the PDF, CDFs, and quantile function values of common probability distributions
119 lines (118 loc) • 3.79 kB
JavaScript
;
const gamma = require("./gamma");
const beta = require("./beta");
const rf = require("./rootFind");
const async_1 = require("./async");
const continuedFractionSolver_1 = require("./continuedFractionSolver");
const random_1 = require("./random");
// This import and then renaming of imports is necessary to allow the async module to
// correctly generate web worker scripts.
const lnGamma = gamma.lnGamma;
const incompleteBeta = beta.incompleteBeta;
const rootFind = rf.rootFind;
function pdfSync(x, degreesOfFreedom) {
const lnCoefficientNumerator = lnGamma((degreesOfFreedom + 1) / 2);
const lnCoefficientDenominator = ((1 / 2) * Math.log(degreesOfFreedom * Math.PI)) + lnGamma(degreesOfFreedom / 2);
const lnCoefficient = lnCoefficientNumerator - lnCoefficientDenominator;
const lnBase = Math.log(1 + ((x * x) / degreesOfFreedom));
const exponent = -(degreesOfFreedom + 1) / 2;
return Math.exp(lnCoefficient + (exponent * lnBase));
}
exports.pdfSync = pdfSync;
function pdf(x, degreesOfFreedom) {
return async_1.asyncGen([beta.lnBeta, gamma.lnGamma], pdfSync, [x, degreesOfFreedom]);
}
exports.pdf = pdf;
function cdfSync(x, degreesOfFreedom, lowerTail = true) {
const incompleteBetaEval = incompleteBeta(degreesOfFreedom / (degreesOfFreedom + x * x), degreesOfFreedom / 2, 1 / 2);
if ((x >= 0 && lowerTail) || (x < 0 && !lowerTail)) {
return 1 - incompleteBetaEval / 2;
}
else {
return incompleteBetaEval / 2;
}
}
exports.cdfSync = cdfSync;
function cdf(x, degreesOfFreedom, lowerTail = true) {
return async_1.asyncGen([
beta.lnBeta,
gamma.lnGamma,
continuedFractionSolver_1.continuedFractionSolver,
beta.d,
beta.continuedFraction,
beta.lnIncompleteBeta,
beta.incompleteBeta
], cdfSync, [x, degreesOfFreedom, lowerTail]);
}
exports.cdf = cdf;
function quantileSync(p, degreesOfFreedom, lowerTail = true) {
function f(val) {
return cdfSync(val, degreesOfFreedom);
}
function fPrime(val) {
if (lowerTail) {
return pdfSync(val, degreesOfFreedom);
}
else {
return -pdfSync(val, degreesOfFreedom);
}
}
if (p === 0) {
if (lowerTail) {
return Number.NEGATIVE_INFINITY;
}
else {
return Number.POSITIVE_INFINITY;
}
}
else if (p === 1) {
if (lowerTail) {
return Number.POSITIVE_INFINITY;
}
else {
return Number.NEGATIVE_INFINITY;
}
}
else {
return rootFind(f, fPrime, p, 0, null, null);
}
}
exports.quantileSync = quantileSync;
function quantile(p, degreesOfFreedom, lowerTail = true) {
return async_1.asyncGen([
rf.newton,
rf.bisection,
rootFind,
beta.lnBeta,
gamma.lnGamma,
continuedFractionSolver_1.continuedFractionSolver,
beta.d,
beta.continuedFraction,
beta.lnIncompleteBeta,
beta.incompleteBeta,
pdfSync,
cdfSync
], quantileSync, [p, degreesOfFreedom, lowerTail]);
}
exports.quantile = quantile;
function randomSync(n, degreesOfFreedom, seed, randoms) {
return random_1.randSync(n, quantileSync, [degreesOfFreedom], seed, randoms);
}
exports.randomSync = randomSync;
function random(n, degreesOfFreedom, seed) {
return random_1.rand(n, quantileSync, [degreesOfFreedom], seed, [
rf.newton,
rf.bisection,
rootFind,
beta.lnBeta,
gamma.lnGamma,
continuedFractionSolver_1.continuedFractionSolver,
beta.d,
beta.continuedFraction,
beta.lnIncompleteBeta,
beta.incompleteBeta,
pdfSync,
cdfSync
]);
}
exports.random = random;