-
Notifications
You must be signed in to change notification settings - Fork 224
/
binomial_distribution.js
50 lines (45 loc) · 2.16 KB
/
binomial_distribution.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
import epsilon from "./epsilon.js";
/**
* The [Binomial Distribution](http://en.wikipedia.org/wiki/Binomial_distribution) is the discrete probability
* distribution of the number of successes in a sequence of n independent yes/no experiments, each of which yields
* success with probability `probability`. Such a success/failure experiment is also called a Bernoulli experiment or
* Bernoulli trial; when trials = 1, the Binomial Distribution is a Bernoulli Distribution.
*
* @param {number} trials number of trials to simulate
* @param {number} probability
* @returns {number[]} output
*/
function binomialDistribution(trials, probability) /*: ?number[] */ {
// Check that `p` is a valid probability (0 ≤ p ≤ 1),
// that `n` is an integer, strictly positive.
if (probability < 0 || probability > 1 || trials <= 0 || trials % 1 !== 0) {
return undefined;
}
// We initialize `x`, the random variable, and `accumulator`, an accumulator
// for the cumulative distribution function to 0. `distribution_functions`
// is the object we'll return with the `probability_of_x` and the
// `cumulativeProbability_of_x`, as well as the calculated mean &
// variance. We iterate until the `cumulativeProbability_of_x` is
// within `epsilon` of 1.0.
let x = 0;
let cumulativeProbability = 0;
const cells = [];
let binomialCoefficient = 1;
// This algorithm iterates through each potential outcome,
// until the `cumulativeProbability` is very close to 1, at
// which point we've defined the vast majority of outcomes
do {
// a [probability mass function](https://en.wikipedia.org/wiki/Probability_mass_function)
cells[x] =
binomialCoefficient *
Math.pow(probability, x) *
Math.pow(1 - probability, trials - x);
cumulativeProbability += cells[x];
x++;
binomialCoefficient = (binomialCoefficient * (trials - x + 1)) / x;
// when the cumulativeProbability is nearly 1, we've calculated
// the useful range of this distribution
} while (cumulativeProbability < 1 - epsilon);
return cells;
}
export default binomialDistribution;