distriprob
Version:
A library for calculating the PDF, CDFs, and quantile function values of common probability distributions
126 lines (125 loc) • 3.8 kB
JavaScript
;
const gamma = require("./gamma");
const rf = require("./rootFind");
const cfs = require("./continuedFractionSolver");
const async_1 = require("./async");
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 continuedFractionSolver = cfs.continuedFractionSolver;
const lnGamma = gamma.lnGamma;
const lnFactorial = gamma.lnFactorial;
const lowerIncompleteGamma = gamma.lowerIncompleteGamma;
const upperIncompleteGamma = gamma.upperIncompleteGamma;
const lnUpperIncompleteGammaB = gamma.lnUpperIncompleteGammaB;
const discreteQuantileFind = rf.discreteQuantileFind;
function pmfSync(k, lambda) {
if (k === 0) {
return Math.exp((k * Math.log(lambda)) - lambda);
}
else {
return Math.exp((k * Math.log(lambda)) - lambda - lnFactorial(k));
}
}
exports.pmfSync = pmfSync;
function pmf(k, lambda) {
return async_1.asyncGen([lnGamma, lnFactorial], pmfSync, [k, lambda]);
}
exports.pmf = pmf;
function cdfSync(k, lambda, lowerTail = true) {
if (k < 0) {
if (lowerTail) {
return 0;
}
else {
return 1;
}
}
else {
k = Math.floor(k);
// TODO: check into slow computation of lowerIncompleteGamma for large lambda
if (lowerTail) {
return upperIncompleteGamma(lambda, k + 1);
}
else {
return lowerIncompleteGamma(lambda, k + 1);
}
}
}
exports.cdfSync = cdfSync;
function cdf(k, lambda, lowerTail = true) {
return async_1.asyncGen([
continuedFractionSolver,
gamma.lnGamma,
gamma.gammaContinuedFraction,
gamma.lnLowerIncompleteGammaA,
gamma.lnUpperIncompleteGammaB,
gamma.lnLowerIncompleteGamma,
gamma.lnUpperIncompleteGamma,
gamma.lowerIncompleteGamma,
gamma.upperIncompleteGamma
], cdfSync, [k, lambda, lowerTail]);
}
exports.cdf = cdf;
function quantileSync(p, lambda, lowerTail = true) {
function simplifiedCDF(val) {
return cdfSync(val, lambda, lowerTail);
}
if (p === 0) {
if (lowerTail) {
return 0;
}
else {
return Number.POSITIVE_INFINITY;
}
}
else if (p === 1) {
if (lowerTail) {
return Number.POSITIVE_INFINITY;
}
else {
return 0;
}
}
else {
const mean = lambda;
return discreteQuantileFind(simplifiedCDF, p, null, 0, mean, lowerTail);
}
}
exports.quantileSync = quantileSync;
function quantile(p, lambda, lowerTail = true) {
return async_1.asyncGen([
discreteQuantileFind,
continuedFractionSolver,
gamma.lnGamma,
gamma.gammaContinuedFraction,
gamma.lnLowerIncompleteGammaA,
gamma.lnUpperIncompleteGammaB,
gamma.lnLowerIncompleteGamma,
gamma.lnUpperIncompleteGamma,
gamma.lowerIncompleteGamma,
gamma.upperIncompleteGamma,
cdfSync
], quantileSync, [p, lambda, lowerTail]);
}
exports.quantile = quantile;
function randomSync(n, lambda, seed, randoms) {
return random_1.randSync(n, quantileSync, [lambda], seed, randoms);
}
exports.randomSync = randomSync;
function random(n, lambda, seed) {
return random_1.rand(n, quantileSync, [lambda], seed, [
discreteQuantileFind,
continuedFractionSolver,
gamma.lnGamma,
gamma.gammaContinuedFraction,
gamma.lnLowerIncompleteGammaA,
gamma.lnUpperIncompleteGammaB,
gamma.lnLowerIncompleteGamma,
gamma.lnUpperIncompleteGamma,
gamma.lowerIncompleteGamma,
gamma.upperIncompleteGamma,
cdfSync
]);
}
exports.random = random;