Example #1
0
 /**
  * Cumulative Poisson Probability (lower culmulative distribution) - CDF
  * The probability that the Poisson random variable is greater than some specified lower limit,
  * and less than some specified upper limit.
  *
  *           k  λˣℯ^⁻λ
  * P(k,λ) =  ∑  ------
  *          ₓ₌₀  xᵢ!
  *
  * @param  int   $k events in the interval
  * @param  float $λ average number of successful events per interval
  *
  * @return float The cumulative Poisson probability
  */
 public static function CDF(int $k, float $λ) : float
 {
     Support::checkLimits(self::LIMITS, ['k' => $k, 'λ' => $λ]);
     return array_sum(array_map(function ($k) use($λ) {
         return self::PMF($k, $λ);
     }, range(0, $k)));
 }
Example #2
0
 /**
  * Mean of the distribution
  *
  * μ = ∞ for a ≤ 1
  *
  *      ab
  * μ = ----- for a > 1
  *     a - 1
  *
  * @param  number $a shape parameter
  * @param  number $b scale parameter
  *
  * @return number
  */
 public static function mean($a, $b)
 {
     Support::checkLimits(self::LIMITS, ['a' => $a, 'b' => $b]);
     if ($a <= 1) {
         return INF;
     }
     return $a * $b / ($a - 1);
 }
 /**
  * Probability mass function
  *
  * b(x; r, p) = ₓ₋₁Cᵣ₋₁ pʳ * (1 - p)ˣ⁻ʳ
  *
  * @param  int   $x number of trials required to produce r successes
  * @param  int   $r number of successful events
  * @param  float $p probability of success on an individual trial
  *
  * @return float
  */
 public static function PMF(int $x, int $r, float $p) : float
 {
     Support::checkLimits(self::LIMITS, ['x' => $x, 'r' => $r, 'p' => $p]);
     $ₓ₋₁Cᵣ₋₁ = Combinatorics::combinations($x - 1, $r - 1);
     $pʳ = pow($p, $r);
     $⟮1 − p⟯ˣ⁻ʳ = pow(1 - $p, $x - $r);
     return $ₓ₋₁Cᵣ₋₁ * $pʳ * $⟮1 − p⟯ˣ⁻ʳ;
 }
Example #4
0
 /**
  * Binomial distribution - cumulative distribution function
  * Computes and sums the binomial distribution at each of the values in r.
  *
  * @param  int   $n number of events
  * @param  int   $r number of successful events
  * @param  float $P probability of success
  *
  * @return float
  */
 public static function CDF(int $n, int $r, float $p) : float
 {
     Support::checkLimits(self::LIMITS, ['n' => $n, 'r' => $r, 'p' => $p]);
     $cumulative_probability = 0;
     for ($i = $r; $i >= 0; $i--) {
         $cumulative_probability += self::PMF($n, $i, $p);
     }
     return $cumulative_probability;
 }
Example #5
0
 /**
  * Bernoulli distribution - cumulative distribution function
  *
  * https://en.wikipedia.org/wiki/Bernoulli_distribution
  *
  * 0      for k < 0
  * 1 - p  for 0 ≤ k < 1
  * 1      for k ≥ 1
  *
  * @param  int   $k number of successes  k ∈ {0, 1}
  * @param  float $p success probability  0 < p < 1
  *
  * @return  float
  */
 public static function CDF(int $k, float $p) : float
 {
     Support::checkLimits(self::LIMITS, ['p' => $p]);
     if ($k < 0) {
         return 0;
     }
     if ($k < 1) {
         return 1 - $p;
     }
     return 1;
 }
Example #6
0
 /**
  * Cumulative distribution function
  * P value for a z score.
  *
  * @param number $z random variable
  *
  * @return float f(z|μ,σ)
  */
 public static function CDF($z)
 {
     Support::checkLimits(self::LIMITS, ['z' => $z]);
     return Normal::CDF($z, self::μ, self::σ);
 }
Example #7
0
 /**
  * Mean of the distribution
  *
  * μ = exp(μ + σ²/2)
  *
  * @param  number $μ
  * @param  number $σ
  *
  * @return number
  */
 public static function mean($μ, $σ)
 {
     Support::checkLimits(self::LIMITS, ['μ' => $μ, 'σ' => $σ]);
     return exp($μ + $σ ** 2 / 2);
 }
Example #8
0
 /**
  * Mean of the distribution
  *
  * μ = λ⁻¹
  *
  * @param float $λ often called the rate parameter
  *
  * @return number
  */
 public static function mean(float $λ)
 {
     Support::checkLimits(self::LIMITS, ['λ' => $λ]);
     return 1 / $λ;
 }
Example #9
0
 /**
  * Median of the distribution
  *
  * μ = 0
  *
  * @param number $ν Degrees of freedom
  *
  * @return number
  */
 public static function median($ν)
 {
     Support::checkLimits(self::LIMITS, ['ν' => $ν]);
     return 0;
 }
Example #10
0
 /**
  * Regularized incomplete beta function - Iₓ(a, b)
  *
  * https://en.wikipedia.org/wiki/Beta_function#Incomplete_beta_function
  *
  * This function looks at the values of x, a, and b, and determines which algorithm is best to calculate
  * the value of Iₓ(a, b)
  *
  * http://www.boost.org/doc/libs/1_35_0/libs/math/doc/sf_and_dist/html/math_toolkit/special/sf_beta/ibeta_function.html
  * https://github.com/boostorg/math/blob/develop/include/boost/math/special_functions/beta.hpp
  *
  * @param  $x Upper limit of the integration 0 ≦ x ≦ 1
  * @param  $a Shape parameter a > 0
  * @param  $b Shape parameter b > 0
  *
  * @return number
  */
 public static function regularizedIncompleteBeta($x, $a, $b)
 {
     $limits = ['x' => '[0, 1]', 'a' => '(0,∞)', 'b' => '(0,∞)'];
     Support::checkLimits($limits, ['x' => $x, 'a' => $a, 'b' => $b]);
     if ($x == 1 || $x == 0) {
         return $x;
     }
     if ($a == 1) {
         return 1 - (1 - $x) ** $b;
     }
     if ($b == 1) {
         return $x ** $a;
     }
     if ($x > 0.9 || $b > $a && $x > 0.5) {
         $y = 1 - $x;
         return 1 - self::regularizedIncompleteBeta($y, $b, $a);
     }
     if ($a > 1 && $b > 1) {
         // Tolerance on evaluating the continued fraction.
         $tol = 1.0E-15;
         $dif = $tol + 1;
         // Initialize
         // We will calculate the continuous fraction with a minimum depth of 10.
         $m = 10;
         // Counter
         do {
             $I_new = self::iBetaCF($m, $x, $a, $b);
             if ($m > 10) {
                 $dif = abs(($I - $I_new) / $I_new);
             }
             $I = $I_new;
             $m++;
         } while ($dif > $tol);
         return $I;
     } else {
         if ($a <= 1) {
             // We shift a up by one, to the region that the continuous fraction works best.
             $offset = $x ** $a * (1 - $x) ** $b / $a / self::beta($a, $b);
             return self::regularizedIncompleteBeta($x, $a + 1, $b) + $offset;
         } else {
             // $b <= 1
             // We shift a up by one, to the region that the continuous fraction works best.
             $offset = $x ** $a * (1 - $x) ** $b / $b / self::beta($a, $b);
             return self::regularizedIncompleteBeta($x, $a, $b + 1) - $offset;
         }
     }
 }
Example #11
0
 /**
  * Inverse CDF (Quantile function)
  *
  * Q(p;x₀,γ) = x₀ + γ tan[π(p - ½)]
  *
  * @param number $p
  * @param number $x₀
  * @param number $γ
  *
  * @return number
  */
 public static function inverse($p, ...$params)
 {
     $x₀ = $params[0];
     $γ = $params[1];
     Support::checkLimits(self::LIMITS, ['x₀' => $x₀, 'γ' => $γ, 'p' => $p]);
     $π = \M_PI;
     return $x₀ + $γ * tan($π * ($p - 0.5));
 }
Example #12
0
 /**
  * Mean of the distribution
  *
  *       α
  * μ = -----
  *     α + β
  *
  * @param number $α shape parameter α > 0
  * @param number $β shape parameter β > 0
  *
  * @return number
  */
 public static function mean($α, $β)
 {
     Support::checkLimits(self::LIMITS, ['α' => $α, 'β' => $β]);
     return $α / ($α + $β);
 }
Example #13
0
 /**
  * Inverse CDF (Quantile function)
  *
  *                 /   p   \ 1/β
  * F⁻¹(p;α,β) = α |  -----  |
  *                 \ 1 - p /
  *
  * @param number $p
  * @param number $α
  * @param number $β
  *
  * @return number
  */
 public static function inverse($p, ...$params)
 {
     $α = $params[0];
     $β = $params[1];
     Support::checkLimits(self::LIMITS, ['α' => $α, 'β' => $β, 'p' => $p]);
     return $α * ($p / (1 - $p)) ** (1 / $β);
 }
Example #14
0
 /**
  * Mean of the distribution
  *
  * μ = k
  *
  * @param int $k degrees of freedom > 0
  *
  * @return int k
  */
 public static function mean(int $k)
 {
     Support::checkLimits(self::LIMITS, ['k' => $k]);
     return $k;
 }
Example #15
0
 /**
  * Geometric distribution - cumulative distribution function (lower cumulative)
  *
  * The probability distribution of the number Y = X − 1 of failures
  * before the first success, supported on the set { 0, 1, 2, 3, ... }
  * https://en.wikipedia.org/wiki/Geometric_distribution
  *
  * k failures where k ∈ {0, 1, 2, 3, ...}
  *
  * pmf = 1 - (1 - p)ᵏ⁺¹
  *
  * @param  int   $k number of trials     k ≥ 0
  * @param  float $p success probability  0 < p ≤ 1
  *
  * @return float
  */
 public static function CDF(int $k, float $p) : float
 {
     Support::checkLimits(self::LIMITS, ['k' => $k, 'p' => $p]);
     $⟮1 − p⟯ᵏ⁺¹ = pow(1 - $p, $k + 1);
     return 1 - $⟮1 − p⟯ᵏ⁺¹;
 }
Example #16
0
 /**
  * Inverse CDF (Quantile function)
  *
  * Q(p;k,λ) = λ(-ln(1 - p))¹/ᵏ
  *
  * @param number $p
  * @param number $k
  * @param number $λ
  *
  * @return number
  */
 public static function inverse($p, ...$params)
 {
     $k = $params[0];
     $λ = $params[1];
     Support::checkLimits(self::LIMITS, ['k' => $k, 'λ' => $λ, 'p' => $p]);
     return $λ * (-1 * log(1 - $p)) ** (1 / $k);
 }
Example #17
0
 /**
  * Mean of the distribution
  *            _
  *           /ν Γ((ν - 1)/2)
  * E[T] = μ / - ------------    if ν > 1
  *         √  2    Γ(ν/2)
  *
  *      = Does not exist        if ν ≤ 1
  *
  * @param int    $ν Degrees of freedom
  * @param number $μ Noncentrality parameter
  *
  * @return number
  */
 public static function mean(int $ν, $μ)
 {
     Support::checkLimits(self::LIMITS, ['ν' => $ν, 'μ' => $μ]);
     if ($ν == 1) {
         return \NAN;
     }
     return $μ * sqrt($ν / 2) * Special::gamma(($ν - 1) / 2) / Special::gamma($ν / 2);
 }
Example #18
0
 /**
  * Inverse CDF (quantile function)
  *
  *                     /   p   \
  * Q(p;μ,s) = μ + s ln|  -----  |
  *                     \ 1 - p /
  *
  * @param number $p
  * @param number $μ
  * @param number $s
  *
  * @return number
  */
 public static function inverse($p, ...$params)
 {
     $μ = $params[0];
     $s = $params[1];
     Support::checkLimits(self::LIMITS, ['μ' => $μ, 's' => $s, 'p' => $p]);
     return $μ + $s * log($p / (1 - $p));
 }
Example #19
0
 /**
  * Mean of the distribution
  *
  * μ = μ
  *
  * @param  number $μ location parameter
  * @param  number $b scale parameter (diversity)  b > 0
  *
  * @return μ
  */
 public static function mean($μ, $b)
 {
     Support::checkLimits(self::LIMITS, ['μ' => $μ, 'b' => $b]);
     return $μ;
 }
Example #20
0
 /**
  * Cumulative distribution function
  *
  *          / d₁  d₂ \
  *  I      |  --, --  |
  *   ᵈ¹ˣ    \ 2   2  /
  *   ------
  *   ᵈ¹ˣ⁺ᵈ²
  *
  * Where I is the regularized incomplete beta function.
  *
  * @param number $x  percentile ≥ 0
  * @param int    $d₁ degree of freedom v1 > 0
  * @param int    $d₂ degree of freedom v2 > 0
  *
  * @return number
  */
 public static function CDF($x, int $d₁, int $d₂)
 {
     Support::checkLimits(self::LIMITS, ['x' => $x, 'd₁' => $d₁, 'd₂' => $d₂]);
     $ᵈ¹ˣ/d₁x+d₂ = $d₁ * $x / ($d₁ * $x + $d₂);
     return Special::regularizedIncompleteBeta($ᵈ¹ˣ/d₁x+d₂, $d₁ / 2, $d₂ / 2);
 }