Skip to content

Instantly share code, notes, and snippets.

@abarnash
Last active October 31, 2020 23:22
Show Gist options
  • Save abarnash/61c3d4b5d1ed5a7720a5cf207d8280ab to your computer and use it in GitHub Desktop.
Save abarnash/61c3d4b5d1ed5a7720a5cf207d8280ab to your computer and use it in GitHub Desktop.
basic probability utility
//-----------------------------------
// Discrete Probability Distributions
let expectation = (xvals, pfn) => xvals.reduce((sum, x) => sum + x * pfn(x), 0)
let variance = (xvals, pfn) => {
const expect = expectation(xvals, pfn)
return xvals.reduce((sum, x) => sum + pfn(x) * (x - expect) ** 2, 0)
}
let slotfn = distribution => x => distribution[x]
let dkeys = dist => Object.keys(dist).map(x => parseInt(x))
let distribution = {
'-1': 0.977,
'4': 0.008,
'9': 0.008,
'14': 0.006,
'19': 0.001
}
let linearTransformE = (oldE, xtimes, xplus) => xtimes * oldE + xplus
let linearTransformVar = (oldE, xtimes) => xtimes ** 2 * oldE
let independentObsE = (ntimes, E) => ntimes * E
let independentObsVar = (ntimes, Var) => ntimes * Var
let sumExcpectation = (E1, E2) => E1 + E2
let sumVar = (Var1, Var2) => Var1 + Var2
let diffExcpectation = (E1, E2) => E1 - E2
let diffVar = (Var1, Var2) => Var1 + Var2 // always sum the variance
//-----------------------------------
// Permutations and Combinations
let range = (size, startAt = 0) => [...Array(size).keys()].map(i => i + startAt)
let factorial = (n) => range(n, 1).reduce((product, x) => product * x)
let arrangements = (n, type = 'default') => {
const types = {
'circle': n => factorial(n - 1),
'default': n => factorial(n)
}
return types[type](n)
}
let arrangeByType = typeCounts => {
const totalItems = typeCounts.reduce((sum, x) => sum + x, 0)
const factorials = typeCounts.map(x => factorial(x))
return factorial(totalItems) / factorials.reduce((product, x) => product * x)
}
//The number of arrangements of 3 objects taken from 20 is called the number of permutations.
// As you’ve seen, this is calculated using
let permutation = (n, r) => factorial(n) / factorial(n - r)
let combination = (n, r) => factorial(n) / (factorial(r) * factorial(n - r))
//-----------------------------------
// Geometric Distribution
/*
Use the Geometric distribution if you’re running independent trials,
each one can have a success or failure, and you’re interested in how
many trials are needed to get the first successful outcome
*/
let geometric = (r, ppass, pfail) => pfail ** r * pfail
// For the number of trials needed for a success to be greater than r,
// there must have been r failures.
let geometricGTr = (r, pfail) => pfail ** r
let geometricLTr = (r, pfail) => 1 - pfail ** r
let geomE = (ppass) => 1 / ppass
let geomVar = (ppass, pfail) => pfail / (ppass ** 2)
//-----------------------------------
// Binomial Distribution
/*
You’re running a series of independent trials.
There can be either a success or failure for each trial,
and the probability of success is the same for each trial.
There are a finite number of trials.
*/
let binomial = (r, n, ppass, pfail) =>
combination(n, r) * ppass**r * pfail**(n - r)
let binomialE = (n, ppass) => n * ppass
let binomialVar = (n, ppass, pfail) => n * ppass * pfail
/*
If you have a fixed number of trials and you want to know the probability of
getting a certain number of successes, you need to use the
binomial distribution.
You can also use this to find out how many successes
you can expect to have in your n trials.
If you’re interested in how many trials you’ll need before
you have your first
success, then you need to use the geometric distribution instead.
*/
//-----------------------------------
// Poisson Distribution
/*
The Poisson distribution covers situations where:
Individual events occur at random and independently in a given interval.
This can be an interval of time or space—for example, during a week,
or per mile.
You know the mean number of occurrences in the interval or the rate of
occurrences, and it’s finite. The mean number of occurrences is normally
represented by the Greek letter λ (lambda).
The key difference is that the Poisson distribution doesn’t involve a series of
trials. Instead, it models the number of occurrences in a particular interval.
*/
const e = Math.E
let poisson = (r, lambda) => (e**-lambda * lambda**r)/factorial(r)
let poissonE = (lambda) => lambda
let poissonVar = (lambda) => lambda
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment