/** * Some functions for calculating distributions of random variables. */ /** * Takes the factorial of n. * @param {number} n * @return {number} */ const fact = n => { if ( n == 0 || n == 1 ) return 1 for ( let i = n - 1; i >= 1; i -= 1 ) { n = n * i } return n } /** * Compute the {n}\choose{k} value. * @param {number} n the total number of items * @param {number} k the number to take at a time * @return {number} */ const choose = (n,k) => (fact(n))/(fact(k)*(fact(n-k))) /** * Calculate the binomial distribution of a random variable: * * b(x; n,p) for lower_x <= x <= upper_x */ const binom_range = (lower_x, upper_x, n, p) => { let sum = 0 for ( let i = lower_x; i <= upper_x; i += 1 ) { sum += choose(n, i) * Math.pow(p, i) * Math.pow(1-p, n-i) } return sum } /** * Calculate the binomial distribution for some specific x. * * b(x; n,p) */ const binom_dist = (x, n, p) => choose(n, x) * Math.pow(p, x) * Math.pow(1-p, n-x) /** * Calculate the poisson distribution for some specific x. * * p(x, lambda * t) */ const poisson_dist = (x, lambda, t) => { const numerator = Math.pow(Math.E, -1 * lambda * t) * Math.pow(lambda * t, x) const denom = fact(x) return numerator / denom } /** * Calculate the poisson range for some specific x: * * p(x, lambda * t) for lower_x <= x <= upper_x. */ const poisson_range = (lower_x, upper_x, lambda, t) => { let sum = 0 for ( let i = lower_x; i <= upper_x; i += 1 ) { sum += poisson_dist(i, lambda, t) } return sum } module.exports = exports = {fact, choose, binom_range, binom_dist, poisson_dist, poisson_range}