distriprob
Version:
A library for calculating the PDF, CDFs, and quantile function values of common probability distributions
151 lines (150 loc) • 4.61 kB
JavaScript
;
const continuedFractionSolver_1 = require("./continuedFractionSolver");
const gamma = require("./gamma");
const rf = require("./rootFind");
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 lowerIncompleteGamma = gamma.lowerIncompleteGamma;
const upperIncompleteGamma = gamma.upperIncompleteGamma;
const rootFind = rf.rootFind;
function pdfSync(x, mu, sigma) {
if (typeof mu === "undefined" || mu === null) {
mu = 0;
}
if (typeof sigma === "undefined" || sigma === null) {
sigma = 1;
}
const coefficient = 1 / (sigma * Math.sqrt(2 * Math.PI));
const exponentNumerator = Math.pow((x - mu), 2);
const exponentDenominator = 2 * Math.pow(sigma, 2);
const exponent = -(exponentNumerator / exponentDenominator);
return coefficient * Math.pow(Math.E, exponent);
}
exports.pdfSync = pdfSync;
function pdf(x, mu, sigma) {
function script(a, b, c) {
return pdfSync(a, b, c);
}
return async_1.asyncGen([pdfSync], script, [x, mu, sigma]);
}
exports.pdf = pdf;
function cdfSync(x, mu, sigma, lowerTail = true) {
if (typeof mu === "undefined" || mu === null) {
mu = 0;
}
if (typeof sigma === "undefined" || sigma === null) {
sigma = 1;
}
const z = (x - mu) / sigma;
function nonNegativeCase(val) {
return (1 / 2) * (1 + lowerIncompleteGamma((val * val) / 2, 1 / 2));
}
if ((z >= 0 && lowerTail) || (z < 0 && !lowerTail)) {
return (1 / 2) + (lowerIncompleteGamma((x * x) / 2, 1 / 2) / 2);
}
else {
return upperIncompleteGamma((x * x) / 2, 1 / 2) / 2;
}
}
exports.cdfSync = cdfSync;
function cdf(x, mu, sigma, lowerTail = true) {
return async_1.asyncGen([
continuedFractionSolver_1.continuedFractionSolver,
gamma.lnGamma,
gamma.gammaContinuedFraction,
gamma.lnLowerIncompleteGammaA,
gamma.lnUpperIncompleteGammaB,
gamma.lnLowerIncompleteGamma,
gamma.lowerIncompleteGamma,
gamma.upperIncompleteGamma
], cdfSync, [x, mu, sigma, lowerTail]);
}
exports.cdf = cdf;
function quantileSync(p, mu, sigma, lowerTail = true) {
if (typeof mu === "undefined" || mu === null) {
mu = 0;
}
if (typeof sigma === "undefined" || sigma === null) {
sigma = 1;
}
function f(val) {
return cdfSync(val, 0, 1);
}
function fPrime(val) {
if (lowerTail) {
return pdfSync(val, 0, 1);
}
else {
return -pdfSync(val, 0, 1);
}
}
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 {
let z = rootFind(f, fPrime, p, 0, null, null);
return (z * sigma) + mu;
}
}
exports.quantileSync = quantileSync;
function quantile(p, mu, sigma, lowerTail = true) {
return async_1.asyncGen([
rf.newton,
rf.bisection,
rootFind,
continuedFractionSolver_1.continuedFractionSolver,
gamma.lnGamma,
gamma.gammaContinuedFraction,
gamma.lnLowerIncompleteGammaA,
gamma.lnUpperIncompleteGammaB,
gamma.lnLowerIncompleteGamma,
gamma.lowerIncompleteGamma,
gamma.upperIncompleteGamma,
pdfSync,
cdfSync
], quantileSync, [p, mu, sigma, lowerTail]);
}
exports.quantile = quantile;
function randomSync(n, mu, sigma, seed, randoms) {
if (typeof mu === "undefined" || mu === null) {
mu = 0;
}
if (typeof sigma === "undefined" || sigma === null) {
sigma = 1;
}
return random_1.randSync(n, quantileSync, [mu, sigma, true], seed, randoms);
}
exports.randomSync = randomSync;
function random(n, mu, sigma, seed) {
return random_1.rand(n, quantileSync, [mu, sigma], seed, [
rf.newton,
rf.bisection,
rootFind,
continuedFractionSolver_1.continuedFractionSolver,
gamma.lnGamma,
gamma.gammaContinuedFraction,
gamma.lnLowerIncompleteGammaA,
gamma.lnUpperIncompleteGammaB,
gamma.lnLowerIncompleteGamma,
gamma.lowerIncompleteGamma,
gamma.upperIncompleteGamma,
pdfSync,
cdfSync
]);
}
exports.random = random;