UNPKG

distriprob

Version:

A library for calculating the PDF, CDFs, and quantile function values of common probability distributions

119 lines (118 loc) 3.79 kB
"use strict"; 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;