Approximate Procedures

In this package, the following approximation algorithms for computing the Poisson Binomial distribution with Bernoulli probabilities \(p_1, ..., p_n\) are implemented:

The computation of these procedures is optimized and accelerated by some simple preliminary considerations:

  1. Are all \(p_i\) equal?
    In This case, we have an ordinary binomial distribution. The specified method of computation is then ignored.
  2. Are all of the \(p_i (i = 1, ..., n)\) 0 or 1?
    If one \(p_i\) is 1, it is impossible to measure 0 successes. Following the same logic, if two \(p_i\) are 1, we cannot observe 0 and 1 successes and so on. In general, a number of \(n_1 > 0\) values \(p_i = 1\) makes it impossible to measure \(0, ..., n_1 - 1\) successes. Likewise, if \(n_0 > 0\) of the \(p_i = 0\), we cannot observe \(n - n_0 + 1, ..., n\) successes. This leads to three cases (the specified method of computation is ignored in any of them):
    1. All \(p_i = 0\): The only observable value is \(0\), i.e. \(P(X = 0) = 1\) and \(P(X \neq 0) = 0\).
    2. All \(p_i = 1\): The only observable value is \(n\), i.e. \(P(X = n) = 1\) and \(P(X \neq n) = 0\).
    3. All \(p_i \in \{0, 1\}\): The only observable value is \(n_1\), i.e. \(P(X = n_1) = 1\) and \(P(X \neq n_1) = 0\).
  3. Are there \(p_i \notin \{0, 1\}\)?
    Then the only observable values are \(n_1, n_1 + 1, ..., n - n_0\), i.e. \(P(X \in \{n_1, ..., n - n_0\}) > 0\) and \(P(X < n_1) = P(X > n - n_0) = 0\). As a result, \(X\) can be expressed as \(X = n_1 + Y\) with \(Y \sim PBin(\{p_i|0 < p_i < 1\})\) and \(|\{p_i|0 < p_i < 1\}| = n - n_0 - n_1\). Thus, the Poisson Binomial distribution must only be computed for \(Y\).

These cases are illustrated in the following example:

library(PoissonBinomial)

# Case 1
dpbinom(NULL, rep(0.3, 7))
#> [1] 0.0823543 0.2470629 0.3176523 0.2268945 0.0972405 0.0250047 0.0035721
#> [8] 0.0002187
dbinom(0:7, 7, 0.3)
#> [1] 0.0823543 0.2470629 0.3176523 0.2268945 0.0972405 0.0250047 0.0035721
#> [8] 0.0002187
# equal results

# Case 2
dpbinom(NULL, c(0, 0, 0, 0, 0, 0, 0))
#> [1] 1 0 0 0 0 0 0 0
dpbinom(NULL, c(1, 1, 1, 1, 1, 1, 1))
#> [1] 0 0 0 0 0 0 0 1
dpbinom(NULL, c(0, 0, 0, 0, 1, 1, 1))
#> [1] 0 0 0 1 0 0 0 0

# Case 3
dpbinom(NULL, c(0, 0, 0.4, 0.2, 0.8, 0.1, 1), method = "RefinedNormal")
#> [1] 0.000000000 0.103624625 0.411600821 0.373552231 0.101048473 0.009882034
#> [7] 0.000000000 0.000000000

Poisson Approximation

The Poisson Approximation (DC) approach is requested with method = "Poisson". It is based on a Poisson distribution, whose parameter is the sum of the probabilities of success.

set.seed(1)
pp <- runif(10)
wt <- sample(1:10, 10, TRUE)

dpbinom(NULL, pp, wt, "Poisson")
#>  [1] 2.263593e-16 8.154460e-15 1.468798e-13 1.763753e-12 1.588454e-11
#>  [6] 1.144462e-10 6.871428e-10 3.536273e-09 1.592402e-08 6.373926e-08
#> [11] 2.296169e-07 7.519830e-07 2.257479e-06 6.255718e-06 1.609704e-05
#> [16] 3.865908e-05 8.704191e-05 1.844490e-04 3.691482e-04 6.999128e-04
#> [21] 1.260697e-03 2.162661e-03 3.541299e-03 5.546660e-03 8.325631e-03
#> [26] 1.199704e-02 1.662255e-02 2.217842e-02 2.853445e-02 3.544609e-02
#> [31] 4.256414e-02 4.946284e-02 5.568342e-02 6.078674e-02 6.440607e-02
#> [36] 6.629115e-02 6.633610e-02 6.458699e-02 6.122916e-02 5.655755e-02
#> [41] 5.093630e-02 4.475488e-02 3.838734e-02 3.216003e-02 2.633059e-02
#> [46] 2.107875e-02 1.650760e-02 1.265269e-02 9.495953e-03 6.981348e-03
#> [51] 5.029979e-03 3.552981e-03 2.461424e-03 1.673044e-03 1.116119e-03
#> [56] 7.310458e-04 4.702766e-04 2.972182e-04 1.846053e-04 1.127169e-04
#> [61] 6.767601e-05 3.996702e-05
ppbinom(NULL, pp, wt, "Poisson")
#>  [1] 2.263593e-16 8.380820e-15 1.552606e-13 1.919013e-12 1.780355e-11
#>  [6] 1.322498e-10 8.193925e-10 4.355666e-09 2.027968e-08 8.401894e-08
#> [11] 3.136359e-07 1.065619e-06 3.323097e-06 9.578815e-06 2.567585e-05
#> [16] 6.433494e-05 1.513768e-04 3.358259e-04 7.049740e-04 1.404887e-03
#> [21] 2.665584e-03 4.828245e-03 8.369543e-03 1.391620e-02 2.224184e-02
#> [26] 3.423887e-02 5.086142e-02 7.303984e-02 1.015743e-01 1.370204e-01
#> [31] 1.795845e-01 2.290474e-01 2.847308e-01 3.455175e-01 4.099236e-01
#> [36] 4.762147e-01 5.425508e-01 6.071378e-01 6.683670e-01 7.249245e-01
#> [41] 7.758608e-01 8.206157e-01 8.590031e-01 8.911631e-01 9.174937e-01
#> [46] 9.385724e-01 9.550800e-01 9.677327e-01 9.772287e-01 9.842100e-01
#> [51] 9.892400e-01 9.927930e-01 9.952544e-01 9.969275e-01 9.980436e-01
#> [56] 9.987746e-01 9.992449e-01 9.995421e-01 9.997267e-01 9.998394e-01
#> [61] 9.999071e-01 9.999471e-01

A comparison with exact computation shows that the approximation quality of the PA procedure increases with smaller probabilities of success. The reason is that the Poisson Binomial distribution approaches a Poisson distribution when the probabilities are very small.

set.seed(1)

# U(0, 1) random probabilities of success
pp <- runif(20)
ppbinom(NULL, pp, method = "Poisson")
#>  [1] 0.0000150619 0.0001822993 0.0011107465 0.0045470352 0.0140856079
#>  [6] 0.0352676152 0.0744661281 0.1366424859 0.2229381586 0.3294015353
#> [11] 0.4476114664 0.5669319503 0.6773366314 0.7716336284 0.8464201879
#> [16] 0.9017789057 0.9401955801 0.9652869616 0.9807646392 0.9898095840
#> [21] 0.9948310399
ppbinom(NULL, pp)
#>  [1] 4.401037e-11 7.917222e-09 3.703782e-07 8.322882e-06 1.097831e-04
#>  [6] 9.409389e-04 5.583409e-03 2.396866e-02 7.694213e-02 1.898556e-01
#> [11] 3.696636e-01 5.845355e-01 7.771823e-01 9.061530e-01 9.699956e-01
#> [16] 9.929871e-01 9.988588e-01 9.998799e-01 9.999928e-01 9.999998e-01
#> [21] 1.000000e+00
summary(ppbinom(NULL, pp, method = "Poisson") - ppbinom(NULL, pp))
#>       Min.    1st Qu.     Median       Mean    3rd Qu.       Max. 
#> -1.345e-01 -3.459e-02  1.506e-05  2.190e-04  3.433e-02  1.460e-01

# U(0, 0.01) random probabilities of success
pp <- runif(20, 0, 0.01)
ppbinom(NULL, pp, method = "Poisson")
#>  [1] 0.9095763 0.9957827 0.9998678 0.9999969 0.9999999 1.0000000 1.0000000
#>  [8] 1.0000000 1.0000000 1.0000000 1.0000000 1.0000000 1.0000000 1.0000000
#> [15] 1.0000000 1.0000000 1.0000000 1.0000000 1.0000000 1.0000000 1.0000000
ppbinom(NULL, pp)
#>  [1] 0.9093051 0.9960293 0.9998912 0.9999979 1.0000000 1.0000000 1.0000000
#>  [8] 1.0000000 1.0000000 1.0000000 1.0000000 1.0000000 1.0000000 1.0000000
#> [15] 1.0000000 1.0000000 1.0000000 1.0000000 1.0000000 1.0000000 1.0000000
summary(ppbinom(NULL, pp, method = "Poisson") - ppbinom(NULL, pp))
#>       Min.    1st Qu.     Median       Mean    3rd Qu.       Max. 
#> -2.467e-04 -1.000e-11  0.000e+00  0.000e+00  0.000e+00  2.712e-04

Arithmetic Mean Binomial Approximation

The Arithmetic Mean Binomial Approximation (AMBA) approach is requested with method = "Mean". It is based on a Binomial distribution, whose parameter is the arithmetic mean of the probabilities of success.

set.seed(1)
pp <- runif(10)
wt <- sample(1:10, 10, TRUE)
mean(rep(pp, wt))
#> [1] 0.5905641

dpbinom(NULL, pp, wt, "Mean")
#>  [1] 2.204668e-24 1.939788e-22 8.393759e-21 2.381049e-19 4.979863e-18
#>  [6] 8.188480e-17 1.102354e-15 1.249300e-14 1.216331e-13 1.033156e-12
#> [11] 7.749086e-12 5.182139e-11 3.114432e-10 1.693217e-09 8.373498e-09
#> [16] 3.784379e-08 1.569327e-07 5.991812e-07 2.112610e-06 6.896287e-06
#> [21] 2.088890e-05 5.882491e-05 1.542694e-04 3.773093e-04 8.616897e-04
#> [26] 1.839474e-03 3.673702e-03 6.868933e-03 1.203071e-02 1.974641e-02
#> [31] 3.038072e-02 4.382068e-02 5.925587e-02 7.510979e-02 8.921887e-02
#> [36] 9.927353e-02 1.034154e-01 1.007871e-01 9.181496e-02 7.810121e-02
#> [41] 6.195859e-02 4.577391e-02 3.143980e-02 2.003761e-02 1.182352e-02
#> [46] 6.442647e-03 3.232269e-03 1.487928e-03 6.259647e-04 2.395401e-04
#> [51] 8.292214e-05 2.579729e-05 7.155695e-06 1.752667e-06 3.745215e-07
#> [56] 6.875325e-08 1.062521e-08 1.344354e-09 1.337294e-10 9.807932e-12
#> [61] 4.716227e-13 1.110223e-14
ppbinom(NULL, pp, wt, "Mean")
#>  [1] 2.204668e-24 1.961834e-22 8.589942e-21 2.466948e-19 5.226557e-18
#>  [6] 8.711136e-17 1.189465e-15 1.368247e-14 1.353155e-13 1.168472e-12
#> [11] 8.917558e-12 6.073895e-11 3.721822e-10 2.065399e-09 1.043890e-08
#> [16] 4.828268e-08 2.052154e-07 8.043966e-07 2.917007e-06 9.813294e-06
#> [21] 3.070220e-05 8.952711e-05 2.437965e-04 6.211058e-04 1.482796e-03
#> [26] 3.322270e-03 6.995972e-03 1.386490e-02 2.589561e-02 4.564203e-02
#> [31] 7.602274e-02 1.198434e-01 1.790993e-01 2.542091e-01 3.434279e-01
#> [36] 4.427015e-01 5.461169e-01 6.469040e-01 7.387189e-01 8.168201e-01
#> [41] 8.787787e-01 9.245526e-01 9.559924e-01 9.760300e-01 9.878536e-01
#> [46] 9.942962e-01 9.975285e-01 9.990164e-01 9.996424e-01 9.998819e-01
#> [51] 9.999648e-01 9.999906e-01 9.999978e-01 9.999995e-01 9.999999e-01
#> [56] 1.000000e+00 1.000000e+00 1.000000e+00 1.000000e+00 1.000000e+00
#> [61] 1.000000e+00 1.000000e+00

A comparison with exact computation shows that the approximation quality of the AMBA procedure increases when the probabilities of success are closer to each other. The reason is that, although the expectation remains unchanged, the distribution’s variance becomes smaller the less the probabilities differ. Since this variance is minimized by equal probabilities (but still underestimated), the AMBA method is best suited for situations with very similar probabilities of success.

set.seed(1)

# U(0, 1) random probabilities of success
pp <- runif(20)
ppbinom(NULL, pp, method = "Mean")
#>  [1] 9.203176e-08 2.389209e-06 2.962532e-05 2.335750e-04 1.315355e-03
#>  [6] 5.635673e-03 1.911545e-02 5.276191e-02 1.209989e-01 2.345484e-01
#> [11] 3.904335e-01 5.672973e-01 7.328465e-01 8.599918e-01 9.393327e-01
#> [16] 9.789409e-01 9.943885e-01 9.989247e-01 9.998683e-01 9.999923e-01
#> [21] 1.000000e+00
ppbinom(NULL, pp)
#>  [1] 4.401037e-11 7.917222e-09 3.703782e-07 8.322882e-06 1.097831e-04
#>  [6] 9.409389e-04 5.583409e-03 2.396866e-02 7.694213e-02 1.898556e-01
#> [11] 3.696636e-01 5.845355e-01 7.771823e-01 9.061530e-01 9.699956e-01
#> [16] 9.929871e-01 9.988588e-01 9.998799e-01 9.999928e-01 9.999998e-01
#> [21] 1.000000e+00
summary(ppbinom(NULL, pp, method = "Mean") - ppbinom(NULL, pp))
#>       Min.    1st Qu.     Median       Mean    3rd Qu.       Max. 
#> -4.616e-02 -4.470e-03  9.000e-08  0.000e+00  4.695e-03  4.469e-02

# U(0.4, 0.6) random probabilities of success
pp <- runif(20, 0.3, 0.5)
ppbinom(NULL, pp, method = "Mean")
#>  [1] 4.348271e-05 6.107425e-04 4.125869e-03 1.788299e-02 5.602047e-02
#>  [6] 1.356249e-01 2.654363e-01 4.347835e-01 6.142845e-01 7.703982e-01
#> [11] 8.824113e-01 9.488333e-01 9.813277e-01 9.943711e-01 9.986251e-01
#> [16] 9.997350e-01 9.999612e-01 9.999960e-01 9.999997e-01 1.000000e+00
#> [21] 1.000000e+00
ppbinom(NULL, pp)
#>  [1] 4.015121e-05 5.746240e-04 3.945015e-03 1.733239e-02 5.489718e-02
#>  [6] 1.340486e-01 2.639932e-01 4.342003e-01 6.148558e-01 7.717620e-01
#> [11] 8.838897e-01 9.499333e-01 9.819393e-01 9.946318e-01 9.987105e-01
#> [16] 9.997562e-01 9.999651e-01 9.999965e-01 9.999998e-01 1.000000e+00
#> [21] 1.000000e+00
summary(ppbinom(NULL, pp, method = "Mean") - ppbinom(NULL, pp))
#>       Min.    1st Qu.     Median       Mean    3rd Qu.       Max. 
#> -1.478e-03 -2.607e-04 -3.900e-08  0.000e+00  1.809e-04  1.576e-03

# U(0.49, 0.51) random probabilities of success
pp <- runif(20, 0.39, 0.41)
ppbinom(NULL, pp, method = "Mean")
#>  [1] 3.638616e-05 5.218267e-04 3.598132e-03 1.591075e-02 5.081748e-02
#>  [6] 1.253300e-01 2.495921e-01 4.153745e-01 5.950801e-01 7.549145e-01
#> [11] 8.721969e-01 9.433198e-01 9.789027e-01 9.935096e-01 9.983815e-01
#> [16] 9.996814e-01 9.999524e-01 9.999949e-01 9.999997e-01 1.000000e+00
#> [21] 1.000000e+00
ppbinom(NULL, pp)
#>  [1] 3.636149e-05 5.215550e-04 3.596747e-03 1.590645e-02 5.080849e-02
#>  [6] 1.253169e-01 2.495796e-01 4.153687e-01 5.950840e-01 7.549255e-01
#> [11] 8.722095e-01 9.433296e-01 9.789083e-01 9.935120e-01 9.983823e-01
#> [16] 9.996816e-01 9.999524e-01 9.999949e-01 9.999997e-01 1.000000e+00
#> [21] 1.000000e+00
summary(ppbinom(NULL, pp, method = "Mean") - ppbinom(NULL, pp))
#>       Min.    1st Qu.     Median       Mean    3rd Qu.       Max. 
#> -1.258e-05 -2.472e-06 -4.410e-10  0.000e+00  1.385e-06  1.301e-05

Geometric Mean Binomial Approximation - Variant A

The Geometric Mean Binomial Approximation (Variant A) (GMBA-A) approach is requested with method = "GeoMean". It is based on a Binomial distribution, whose parameter is the geometric mean of the probabilities of success: \[\hat{p} = \sqrt[n]{p_1 \cdot ... \cdot p_n}\]

set.seed(1)
pp <- runif(10)
wt <- sample(1:10, 10, TRUE)
prod(rep(pp, wt))^(1/sum(wt))
#> [1] 0.4669916

dpbinom(NULL, pp, wt, "GeoMean")
#>  [1] 2.141782e-17 1.144670e-15 3.008684e-14 5.184208e-13 6.586057e-12
#>  [6] 6.578175e-11 5.379195e-10 3.703028e-09 2.189958e-08 1.129911e-07
#> [11] 5.147813e-07 2.091103e-06 7.633772e-06 2.520966e-05 7.572779e-05
#> [16] 2.078916e-04 5.236606e-04 1.214475e-03 2.601021e-03 5.157435e-03
#> [21] 9.489168e-03 1.623184e-02 2.585712e-02 3.841422e-02 5.328923e-02
#> [26] 6.909972e-02 8.382634e-02 9.520502e-02 1.012875e-01 1.009827e-01
#> [31] 9.437363e-02 8.268481e-02 6.791600e-02 5.229152e-02 3.772988e-02
#> [36] 2.550094e-02 1.613623e-02 9.552467e-03 5.285892e-03 2.731219e-03
#> [41] 1.316117e-03 5.906156e-04 2.464113e-04 9.539397e-05 3.419132e-05
#> [46] 1.131690e-05 3.448772e-06 9.643463e-07 2.464308e-07 5.728188e-08
#> [51] 1.204491e-08 2.276152e-09 3.835067e-10 5.705769e-11 7.406076e-12
#> [56] 8.257839e-13 7.760459e-14 5.884182e-15 4.440892e-16 0.000000e+00
#> [61] 0.000000e+00 0.000000e+00
ppbinom(NULL, pp, wt, "GeoMean")
#>  [1] 2.141782e-17 1.166088e-15 3.125293e-14 5.496737e-13 7.135731e-12
#>  [6] 7.291748e-11 6.108370e-10 4.313865e-09 2.621345e-08 1.392046e-07
#> [11] 6.539859e-07 2.745088e-06 1.037886e-05 3.558852e-05 1.113163e-04
#> [16] 3.192079e-04 8.428685e-04 2.057343e-03 4.658364e-03 9.815799e-03
#> [21] 1.930497e-02 3.553681e-02 6.139393e-02 9.980815e-02 1.530974e-01
#> [26] 2.221971e-01 3.060234e-01 4.012285e-01 5.025160e-01 6.034986e-01
#> [31] 6.978723e-01 7.805571e-01 8.484731e-01 9.007646e-01 9.384945e-01
#> [36] 9.639954e-01 9.801316e-01 9.896841e-01 9.949700e-01 9.977012e-01
#> [41] 9.990173e-01 9.996080e-01 9.998544e-01 9.999498e-01 9.999840e-01
#> [46] 9.999953e-01 9.999987e-01 9.999997e-01 9.999999e-01 1.000000e+00
#> [51] 1.000000e+00 1.000000e+00 1.000000e+00 1.000000e+00 1.000000e+00
#> [56] 1.000000e+00 1.000000e+00 1.000000e+00 1.000000e+00 1.000000e+00
#> [61] 1.000000e+00 1.000000e+00

It is known that the geometric mean of the probabilities of success is always smaller than their arithmetic mean. Thus, we get a stochastically smaller binomial distribution. A comparison with exact computation shows that the approximation quality of the GMBA-A procedure increases when the probabilities of success are closer to each other:

set.seed(1)

# U(0, 1) random probabilities of success
pp <- runif(20)
ppbinom(NULL, pp, method = "GeoMean")
#>  [1] 4.557123e-06 8.198697e-05 7.069000e-04 3.892259e-03 1.539324e-02
#>  [6] 4.665926e-02 1.130642e-01 2.258924e-01 3.816534e-01 5.580885e-01
#> [11] 7.229676e-01 8.503062e-01 9.314414e-01 9.738587e-01 9.918765e-01
#> [16] 9.979993e-01 9.996248e-01 9.999497e-01 9.999957e-01 9.999998e-01
#> [21] 1.000000e+00
ppbinom(NULL, pp)
#>  [1] 4.401037e-11 7.917222e-09 3.703782e-07 8.322882e-06 1.097831e-04
#>  [6] 9.409389e-04 5.583409e-03 2.396866e-02 7.694213e-02 1.898556e-01
#> [11] 3.696636e-01 5.845355e-01 7.771823e-01 9.061530e-01 9.699956e-01
#> [16] 9.929871e-01 9.988588e-01 9.998799e-01 9.999928e-01 9.999998e-01
#> [21] 1.000000e+00
summary(ppbinom(NULL, pp, method = "GeoMean") - ppbinom(NULL, pp))
#>     Min.  1st Qu.   Median     Mean  3rd Qu.     Max. 
#> 0.000000 0.000082 0.015284 0.091276 0.154259 0.368233

# U(0.4, 0.6) random probabilities of success
pp <- runif(20, 0.4, 0.6)
ppbinom(NULL, pp, method = "GeoMean")
#>  [1] 1.317886e-06 2.682989e-05 2.614174e-04 1.623781e-03 7.228045e-03
#>  [6] 2.458627e-02 6.658945e-02 1.479004e-01 2.757911e-01 4.408407e-01
#> [11] 6.165699e-01 7.711979e-01 8.834478e-01 9.503083e-01 9.826659e-01
#> [16] 9.951936e-01 9.989829e-01 9.998459e-01 9.999851e-01 9.999993e-01
#> [21] 1.000000e+00
ppbinom(NULL, pp)
#>  [1] 1.046635e-06 2.202850e-05 2.213291e-04 1.414007e-03 6.457121e-03
#>  [6] 2.247333e-02 6.211355e-02 1.404076e-01 2.657427e-01 4.299645e-01
#> [11] 6.070461e-01 7.644671e-01 8.796371e-01 9.486034e-01 9.820764e-01
#> [16] 9.950416e-01 9.989554e-01 9.998428e-01 9.999850e-01 9.999993e-01
#> [21] 1.000000e+00
summary(ppbinom(NULL, pp, method = "GeoMean") - ppbinom(NULL, pp))
#>      Min.   1st Qu.    Median      Mean   3rd Qu.      Max. 
#> 0.000e+00 4.801e-06 5.895e-04 2.789e-03 4.476e-03 1.088e-02

# U(0.49, 0.51) random probabilities of success
pp <- runif(20, 0.49, 0.51)
ppbinom(NULL, pp, method = "GeoMean")
#>  [1] 9.491177e-07 1.994056e-05 2.004457e-04 1.283995e-03 5.891288e-03
#>  [6] 2.064168e-02 5.753534e-02 1.313580e-01 2.513773e-01 4.114796e-01
#> [11] 5.876766e-01 7.479324e-01 8.681818e-01 9.422168e-01 9.792521e-01
#> [16] 9.940733e-01 9.987072e-01 9.997980e-01 9.999799e-01 9.999990e-01
#> [21] 1.000000e+00
ppbinom(NULL, pp)
#>  [1] 9.472606e-07 1.990710e-05 2.001610e-04 1.282476e-03 5.885583e-03
#>  [6] 2.062570e-02 5.750067e-02 1.312985e-01 2.512954e-01 4.113886e-01
#> [11] 5.875946e-01 7.478727e-01 8.681469e-01 9.422007e-01 9.792463e-01
#> [16] 9.940718e-01 9.987069e-01 9.997980e-01 9.999799e-01 9.999990e-01
#> [21] 1.000000e+00
summary(ppbinom(NULL, pp, method = "GeoMean") - ppbinom(NULL, pp))
#>      Min.   1st Qu.    Median      Mean   3rd Qu.      Max. 
#> 0.000e+00 3.394e-08 5.704e-06 2.338e-05 3.486e-05 9.105e-05

Geometric Mean Binomial Approximation - Variant B

The Geometric Mean Binomial Approximation (Variant B) (GMBA-B) approach is requested with method = "GeoMeanCounter". It is based on a Binomial distribution, whose parameter is 1 minus the geometric mean of the probabilities of failure: \[\hat{p} = 1 - \sqrt[n]{(1 - p_1) \cdot ... \cdot (1 - p_n)}\]

set.seed(1)
pp <- runif(10)
wt <- sample(1:10, 10, TRUE)
1 - prod(1 - rep(pp, wt))^(1/sum(wt))
#> [1] 0.7275426

dpbinom(NULL, pp, wt, "GeoMeanCounter")
#>  [1] 3.574462e-35 5.822379e-33 4.664248e-31 2.449471e-29 9.484189e-28
#>  [6] 2.887121e-26 7.195512e-25 1.509685e-23 2.721134e-22 4.279009e-21
#> [11] 5.941642e-20 7.356037e-19 8.184508e-18 8.237686e-17 7.541858e-16
#> [16] 6.310225e-15 4.844429e-14 3.424255e-13 2.235148e-12 1.350769e-11
#> [21] 7.574609e-11 3.948978e-10 1.917264e-09 8.681177e-09 3.670379e-08
#> [26] 1.450549e-07 5.363170e-07 1.856461e-06 6.019586e-06 1.829121e-05
#> [31] 5.209921e-05 1.391205e-04 3.482749e-04 8.172712e-04 1.797236e-03
#> [36] 3.702208e-03 7.139892e-03 1.288219e-02 2.172588e-02 3.421374e-02
#> [41] 5.024851e-02 6.872559e-02 8.738947e-02 1.031108e-01 1.126377e-01
#> [46] 1.136267e-01 1.055364e-01 8.994057e-02 7.004907e-02 4.962603e-02
#> [51] 3.180393e-02 1.831737e-02 9.406320e-03 4.265268e-03 1.687339e-03
#> [56] 5.734528e-04 1.640669e-04 3.843049e-05 7.077304e-06 9.609416e-07
#> [61] 8.553338e-08 3.744258e-09
ppbinom(NULL, pp, wt, "GeoMeanCounter")
#>  [1] 3.574462e-35 5.858123e-33 4.722829e-31 2.496699e-29 9.733859e-28
#>  [6] 2.984460e-26 7.493958e-25 1.584624e-23 2.879597e-22 4.566969e-21
#> [11] 6.398339e-20 7.995871e-19 8.984095e-18 9.136095e-17 8.455467e-16
#> [16] 7.155772e-15 5.560007e-14 3.980256e-13 2.633173e-12 1.614086e-11
#> [21] 9.188695e-11 4.867847e-10 2.404049e-09 1.108523e-08 4.778901e-08
#> [26] 1.928440e-07 7.291610e-07 2.585622e-06 8.605207e-06 2.689642e-05
#> [31] 7.899562e-05 2.181161e-04 5.663910e-04 1.383662e-03 3.180899e-03
#> [36] 6.883107e-03 1.402300e-02 2.690519e-02 4.863107e-02 8.284481e-02
#> [41] 1.330933e-01 2.018189e-01 2.892084e-01 3.923192e-01 5.049569e-01
#> [46] 6.185836e-01 7.241200e-01 8.140606e-01 8.841097e-01 9.337357e-01
#> [51] 9.655396e-01 9.838570e-01 9.932633e-01 9.975286e-01 9.992159e-01
#> [56] 9.997894e-01 9.999534e-01 9.999919e-01 9.999989e-01 9.999999e-01
#> [61] 1.000000e+00 1.000000e+00

It is known that the geometric mean of the probabilities of success is always greater than their arithmetic mean. Thus, we get a stochastically larger binomial distribution. A comparison with exact computation shows that the approximation quality of the GMBA-B procedure again increases when the probabilities of success are closer to each other:

set.seed(1)

# U(0, 1) random probabilities of success
pp <- runif(20)
ppbinom(NULL, pp, method = "GeoMeanCounter")
#>  [1] 4.401037e-11 2.063865e-09 4.609691e-08 6.523654e-07 6.565109e-06
#>  [6] 4.998354e-05 2.990694e-04 1.442248e-03 5.705124e-03 1.874809e-02
#> [11] 5.167146e-02 1.203540e-01 2.385610e-01 4.054872e-01 5.970141e-01
#> [16] 7.728165e-01 8.988859e-01 9.669560e-01 9.929899e-01 9.992785e-01
#> [21] 1.000000e+00
ppbinom(NULL, pp)
#>  [1] 4.401037e-11 7.917222e-09 3.703782e-07 8.322882e-06 1.097831e-04
#>  [6] 9.409389e-04 5.583409e-03 2.396866e-02 7.694213e-02 1.898556e-01
#> [11] 3.696636e-01 5.845355e-01 7.771823e-01 9.061530e-01 9.699956e-01
#> [16] 9.929871e-01 9.988588e-01 9.998799e-01 9.999928e-01 9.999998e-01
#> [21] 1.000000e+00
summary(ppbinom(NULL, pp, method = "GeoMeanCounter") - ppbinom(NULL, pp))
#>       Min.    1st Qu.     Median       Mean    3rd Qu.       Max. 
#> -0.5386214 -0.2201706 -0.0225264 -0.1345901 -0.0001032  0.0000000

# U(0.4, 0.6) random probabilities of success
pp <- runif(20, 0.4, 0.6)
ppbinom(NULL, pp, method = "GeoMeanCounter")
#>  [1] 1.046635e-06 2.178508e-05 2.169721e-04 1.377226e-03 6.262548e-03
#>  [6] 2.175051e-02 6.011109e-02 1.361203e-01 2.584891e-01 4.201335e-01
#> [11] 5.962922e-01 7.549505e-01 8.728399e-01 9.447141e-01 9.803177e-01
#> [16] 9.944269e-01 9.987952e-01 9.998135e-01 9.999816e-01 9.999991e-01
#> [21] 1.000000e+00
ppbinom(NULL, pp)
#>  [1] 1.046635e-06 2.202850e-05 2.213291e-04 1.414007e-03 6.457121e-03
#>  [6] 2.247333e-02 6.211355e-02 1.404076e-01 2.657427e-01 4.299645e-01
#> [11] 6.070461e-01 7.644671e-01 8.796371e-01 9.486034e-01 9.820764e-01
#> [16] 9.950416e-01 9.989554e-01 9.998428e-01 9.999850e-01 9.999993e-01
#> [21] 1.000000e+00
summary(ppbinom(NULL, pp, method = "GeoMeanCounter") - ppbinom(NULL, pp))
#>       Min.    1st Qu.     Median       Mean    3rd Qu.       Max. 
#> -1.075e-02 -4.287e-03 -6.147e-04 -2.755e-03 -4.357e-06  0.000e+00

# U(0.49, 0.51) random probabilities of success
pp <- runif(20, 0.49, 0.51)
ppbinom(NULL, pp, method = "GeoMeanCounter")
#>  [1] 9.472606e-07 1.990526e-05 2.001278e-04 1.282193e-03 5.884073e-03
#>  [6] 2.062003e-02 5.748478e-02 1.312640e-01 2.512363e-01 4.113072e-01
#> [11] 5.875040e-01 7.477911e-01 8.680875e-01 9.421661e-01 9.792303e-01
#> [16] 9.940660e-01 9.987053e-01 9.997977e-01 9.999799e-01 9.999990e-01
#> [21] 1.000000e+00
ppbinom(NULL, pp)
#>  [1] 9.472606e-07 1.990710e-05 2.001610e-04 1.282476e-03 5.885583e-03
#>  [6] 2.062570e-02 5.750067e-02 1.312985e-01 2.512954e-01 4.113886e-01
#> [11] 5.875946e-01 7.478727e-01 8.681469e-01 9.422007e-01 9.792463e-01
#> [16] 9.940718e-01 9.987069e-01 9.997980e-01 9.999799e-01 9.999990e-01
#> [21] 1.000000e+00
summary(ppbinom(NULL, pp, method = "GeoMeanCounter") - ppbinom(NULL, pp))
#>       Min.    1st Qu.     Median       Mean    3rd Qu.       Max. 
#> -9.052e-05 -3.466e-05 -5.669e-06 -2.324e-05 -3.377e-08  0.000e+00

Normal Approximation

The Normal Approximation (NA) approach is requested with method = "Normal". It is based on a Normal distribution, whose parameters are derived from the theoretical mean and variance of the input probabilities of success.

set.seed(1)
pp <- runif(10)
wt <- sample(1:10, 10, TRUE)
mean(rep(pp, wt))
#> [1] 0.5905641

dpbinom(NULL, pp, wt, "Normal")
#>  [1] 2.552770e-32 1.207834e-30 5.219650e-29 2.022022e-27 7.021785e-26
#>  [6] 2.185917e-24 6.100302e-23 1.526188e-21 3.423032e-20 6.882841e-19
#> [11] 1.240755e-17 2.005270e-16 2.905604e-15 3.774712e-14 4.396661e-13
#> [16] 4.591569e-12 4.299381e-11 3.609645e-10 2.717342e-09 1.834224e-08
#> [21] 1.110185e-07 6.025326e-07 2.932337e-06 1.279682e-05 5.007841e-05
#> [26] 1.757379e-04 5.530339e-04 1.560683e-03 3.949650e-03 8.963710e-03
#> [31] 1.824341e-02 3.329786e-02 5.450317e-02 8.000636e-02 1.053238e-01
#> [36] 1.243451e-01 1.316535e-01 1.250080e-01 1.064497e-01 8.129267e-02
#> [41] 5.567468e-02 3.419491e-02 1.883477e-02 9.303614e-03 4.121280e-03
#> [46] 1.637186e-03 5.832371e-04 1.863241e-04 5.337829e-05 1.371282e-05
#> [51] 3.159002e-06 6.525712e-07 1.208800e-07 2.007813e-08 2.990389e-09
#> [56] 3.993563e-10 4.782064e-11 5.134337e-12 4.942713e-13 4.263256e-14
#> [61] 3.330669e-15 2.220446e-16
ppbinom(NULL, pp, wt, "Normal")
#>  [1] 2.552770e-32 1.233362e-30 5.342987e-29 2.075452e-27 7.229330e-26
#>  [6] 2.258210e-24 6.326123e-23 1.589449e-21 3.581977e-20 7.241039e-19
#> [11] 1.313165e-17 2.136587e-16 3.119262e-15 4.086639e-14 4.805325e-13
#> [16] 5.072102e-12 4.806591e-11 4.090305e-10 3.126373e-09 2.146861e-08
#> [21] 1.324871e-07 7.350197e-07 3.667357e-06 1.646417e-05 6.654258e-05
#> [26] 2.422805e-04 7.953144e-04 2.355997e-03 6.305647e-03 1.526936e-02
#> [31] 3.351276e-02 6.681062e-02 1.213138e-01 2.013201e-01 3.066439e-01
#> [36] 4.309891e-01 5.626426e-01 6.876506e-01 7.941003e-01 8.753930e-01
#> [41] 9.310676e-01 9.652625e-01 9.840973e-01 9.934009e-01 9.975222e-01
#> [46] 9.991594e-01 9.997426e-01 9.999290e-01 9.999823e-01 9.999960e-01
#> [51] 9.999992e-01 9.999999e-01 1.000000e+00 1.000000e+00 1.000000e+00
#> [56] 1.000000e+00 1.000000e+00 1.000000e+00 1.000000e+00 1.000000e+00
#> [61] 1.000000e+00 1.000000e+00

A comparison with exact computation shows that the approximation quality of the NA procedure increases with larger numbers of probabilities of success:

set.seed(1)

# U(0, 1) random probabilities of success
pp <- runif(10)
summary(ppbinom(NULL, pp, method = "Normal") - ppbinom(NULL, pp))
#>       Min.    1st Qu.     Median       Mean    3rd Qu.       Max. 
#> -5.342e-03 -1.607e-03  2.291e-05  1.000e-08  1.830e-03  4.266e-03

# U(0.4, 0.6) random probabilities of success
pp <- runif(1000)
summary(ppbinom(NULL, pp, method = "Normal") - ppbinom(NULL, pp))
#>       Min.    1st Qu.     Median       Mean    3rd Qu.       Max. 
#> -5.836e-05  0.000e+00  0.000e+00  0.000e+00  0.000e+00  6.357e-05

# U(0.49, 0.51) random probabilities of success
pp <- runif(100000)
summary(ppbinom(NULL, pp, method = "Normal") - ppbinom(NULL, pp))
#>       Min.    1st Qu.     Median       Mean    3rd Qu.       Max. 
#> -4.769e-07  0.000e+00  0.000e+00  0.000e+00  0.000e+00  3.699e-07

Refined Normal Approximation

The Refined Normal Approximation (RNA) approach is requested with method = "RefinedNormal". It is based on a Normal distribution, whose parameters are derived from the theoretical mean, variance and skewness of the input probabilities of success.

set.seed(1)
pp <- runif(10)
wt <- sample(1:10, 10, TRUE)
mean(rep(pp, wt))
#> [1] 0.5905641

dpbinom(NULL, pp, wt, "RefinedNormal")
#>  [1] 2.579548e-31 1.128297e-29 4.507210e-28 1.611452e-26 5.156486e-25
#>  [6] 1.476806e-23 3.785627e-22 8.685911e-21 1.783953e-19 3.280039e-18
#> [11] 5.399492e-17 7.959230e-16 1.050796e-14 1.242802e-13 1.317210e-12
#> [16] 1.251531e-11 1.066498e-10 8.155390e-10 5.599786e-09 3.455053e-08
#> [21] 1.917106e-07 9.574753e-07 4.308224e-06 1.748069e-05 6.401569e-05
#> [26] 2.117447e-04 6.329842e-04 1.710740e-03 4.180480e-03 9.234968e-03
#> [31] 1.843341e-02 3.322175e-02 5.401115e-02 7.912655e-02 1.043358e-01
#> [36] 1.236782e-01 1.316360e-01 1.256489e-01 1.074322e-01 8.218619e-02
#> [41] 5.618825e-02 3.428872e-02 1.865323e-02 9.032795e-03 3.886960e-03
#> [46] 1.483178e-03 5.004545e-04 1.487517e-04 3.873113e-05 8.757189e-06
#> [51] 1.693868e-06 2.722346e-07 3.388544e-08 2.218356e-09 0.000000e+00
#> [56] 0.000000e+00 0.000000e+00 0.000000e+00 0.000000e+00 0.000000e+00
#> [61] 0.000000e+00 0.000000e+00
ppbinom(NULL, pp, wt, "RefinedNormal")
#>  [1] 2.579548e-31 1.154092e-29 4.622620e-28 1.657678e-26 5.322254e-25
#>  [6] 1.530028e-23 3.938629e-22 9.079774e-21 1.874750e-19 3.467514e-18
#> [11] 5.746244e-17 8.533855e-16 1.136134e-14 1.356415e-13 1.452852e-12
#> [16] 1.396817e-11 1.206179e-10 9.361569e-10 6.535943e-09 4.108647e-08
#> [21] 2.327971e-07 1.190272e-06 5.498496e-06 2.297918e-05 8.699487e-05
#> [26] 2.987396e-04 9.317238e-04 2.642463e-03 6.822944e-03 1.605791e-02
#> [31] 3.449132e-02 6.771307e-02 1.217242e-01 2.008508e-01 3.051866e-01
#> [36] 4.288648e-01 5.605008e-01 6.861497e-01 7.935820e-01 8.757682e-01
#> [41] 9.319564e-01 9.662451e-01 9.848984e-01 9.939312e-01 9.978181e-01
#> [46] 9.993013e-01 9.998018e-01 9.999505e-01 9.999892e-01 9.999980e-01
#> [51] 9.999997e-01 1.000000e+00 1.000000e+00 1.000000e+00 1.000000e+00
#> [56] 1.000000e+00 1.000000e+00 1.000000e+00 1.000000e+00 1.000000e+00
#> [61] 1.000000e+00 1.000000e+00

A comparison with exact computation shows that the approximation quality of the RNA procedure increases with larger numbers of probabilities of success:

set.seed(1)

# U(0, 1) random probabilities of success
pp <- runif(10)
summary(ppbinom(NULL, pp, method = "RefinedNormal") - ppbinom(NULL, pp))
#>       Min.    1st Qu.     Median       Mean    3rd Qu.       Max. 
#> -4.517e-03 -1.285e-03  3.278e-05 -7.600e-08  1.232e-03  4.431e-03

# U(0.4, 0.6) random probabilities of success
pp <- runif(1000)
summary(ppbinom(NULL, pp, method = "RefinedNormal") - ppbinom(NULL, pp))
#>       Min.    1st Qu.     Median       Mean    3rd Qu.       Max. 
#> -4.107e-05  0.000e+00  0.000e+00  0.000e+00  0.000e+00  4.117e-05

# U(0.49, 0.51) random probabilities of success
pp <- runif(100000)
summary(ppbinom(NULL, pp, method = "RefinedNormal") - ppbinom(NULL, pp))
#>       Min.    1st Qu.     Median       Mean    3rd Qu.       Max. 
#> -4.167e-07  0.000e+00  0.000e+00  0.000e+00  0.000e+00  4.167e-07

Performance Comparisons

To assess the performance of the approximation procedures, we use the microbenchmark package. Each algorithm has to calculate the PMF repeatedly based on random probability vectors. The run times are then summarized in a table that presents, among other statistics, their minima, maxima and means. The following results were recorded on an AMD Ryzen 7 1800X with 32 GiB of RAM and Ubuntu 18.04.3 (running inside a VirtualBox VM; the host system is Windows 10 Education).

library(microbenchmark)
set.seed(1)

f1 <- function() dpbinom(NULL, runif(4000), method = "Normal")
f2 <- function() dpbinom(NULL, runif(4000), method = "RefinedNormal")
f3 <- function() dpbinom(NULL, runif(4000), method = "Poisson")
f4 <- function() dpbinom(NULL, runif(4000), method = "Mean")
f5 <- function() dpbinom(NULL, runif(4000), method = "GeoMean")
f6 <- function() dpbinom(NULL, runif(4000), method = "GeoMeanCounter")
f7 <- function() dpbinom(NULL, runif(4000), method = "DivideFFT")

microbenchmark(f1(), f2(), f3(), f4(), f5(), f6(), f7())
#> Unit: microseconds
#>  expr      min        lq      mean    median        uq       max neval
#>  f1()  511.019  545.8695  597.1294  566.8085  630.1375  1479.055   100
#>  f2()  683.382  703.8960  832.6612  723.2970  801.8245  4456.861   100
#>  f3() 1141.181 1177.4195 1235.5048 1209.0490 1266.3210  2092.215   100
#>  f4() 1178.211 1217.7395 1310.6949 1248.4020 1317.0965  4420.985   100
#>  f5() 1308.455 1332.4700 1459.2589 1358.8390 1434.2505  4699.747   100
#>  f6() 1310.949 1332.3295 1505.7112 1358.1880 1437.8325  5187.021   100
#>  f7() 5532.098 5689.6645 6582.6371 5843.7885 6184.0165 13121.207   100

Clearly, the NA procedure is the fastest, followed by the RNA method, which needs roughly 30-40% more time, and the PA, AMBA and GMBA approaches that need almost twice as long as the NA algorithm. AMBA, GMBA-A and GMBA-B procedures exhibit almost equal mean execution speed, with the AMBA algorithm being slightly faster. All of the approximation procedures outperform the fastest exact approach, DC-FFT, by far. Even the slowest approximate algorithm is around 4x as fast as DC-FFT.