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