Esempio n. 1
0
 /**
  * Log normal distribution - cumulative distribution function
  *
  * https://en.wikipedia.org/wiki/Log-normal_distribution
  *
  *       1   1      / ln x - μ \
  * cdf = - + - erf |  --------  |
  *       2   2      \   √2σ     /
  *
  * @param  number $x > 0
  * @param  number $μ location parameter
  * @param  number $σ scale parameter > 0
  * @return number
  */
 public static function CDF($x, $μ, $σ)
 {
     Support::checkLimits(self::LIMITS, ['x' => $x, 'μ' => $μ, 'σ' => $σ]);
     $π = \M_PI;
     $⟮ln x − μ⟯ = log($x) - $μ;
     $√2σ = sqrt(2) * $σ;
     return 1 / 2 + 1 / 2 * Special::erf($⟮ln x − μ⟯ / $√2σ);
 }
Esempio n. 2
0
 /**
  * Cumulative distribution function
  *
  * Cumulative t value up to a point, left tail.
  *
  *          / k   x  \
  *       γ |  - , -  |
  *          \ 2   2 /
  * CDF = -------------
  *            / k \
  *         Γ |  -  |
  *            \ 2 /
  *
  * @param number $x Chi-square critical value (CV) > 0
  * @param int    $k degrees of freedom > 0
  *
  * @return number cumulative probability
  */
 public static function CDF($x, int $k)
 {
     Support::checkLimits(self::LIMITS, ['x' => $x, 'k' => $k]);
     // Numerator
     $γ⟮k/2、x/2⟯ = Special::γ($k / 2, $x / 2);
     // Demoninator
     $Γ⟮k/2⟯ = Special::Γ($k / 2);
     return $γ⟮k/2、x/2⟯ / $Γ⟮k/2⟯;
 }
Esempio n. 3
0
 /**
  * Verify the input arguments are valid for correct use of the bisection
  * method. If the tolerance is less than zero, an Exception will be thrown.
  * If f($a) and f($b) have the same sign, we cannot use the intermediate
  * value theorem to guarantee a root is between $a and $b. This exposes the
  * risk of an endless loop, so we throw an Exception. If $a = $b, then clearly
  * we cannot run our loop as $a and $b will themselves be the midpoint, so we
  * throw an Exception.
  *
  * @param Callable $function f(x) callback function
  * @param number   $a        The start of the interval which contains a root
  * @param number   $b        The end of the interval which contains a root
  * @param number   $tol      Tolerance; How close to the actual solution we would like.
  *
  * @throws Exception if $tol (the tolerance) is negative
  * @throws Exception if $a = $b
  * @throws Exception if f($a) and f($b) share the same sign
  */
 private static function validate(callable $function, $a, $b, $tol)
 {
     Validation::tolerance($tol);
     Validation::interval($a, $b);
     $f⟮a⟯ = $function($a);
     $f⟮b⟯ = $function($b);
     if (Special::sgn($f⟮a⟯) === Special::sgn($f⟮b⟯)) {
         throw new Exception\BadDataException('Input function has the same sign at the start and end of the interval. Choose start and end points such that the function evaluated at those points has a different sign (one positive, one negative).');
     }
 }
Esempio n. 4
0
 /**
  * Cumulative distribution function
  * Calculate the cumulative t value up to a point, left tail.
  *
  * cdf = 1 - ½Iₓ₍t₎(ν/2, ½)
  *
  *                 ν
  *  where x(t) = ------
  *               t² + ν
  *
  *        Iₓ₍t₎(ν/2, ½) is the regularized incomplete beta function
  *
  * @param number $t t score
  * @param int    $ν degrees of freedom > 0
  */
 public static function CDF($t, int $ν)
 {
     Support::checkLimits(self::LIMITS, ['t' => $t, 'ν' => $ν]);
     if ($t == 0) {
         return 0.5;
     }
     $x⟮t⟯ = $ν / ($t ** 2 + $ν);
     $ν/2 = $ν / 2;
     $½ = 0.5;
     $Iₓ = Special::regularizedIncompleteBeta($x⟮t⟯, $ν/2, $½);
     if ($t < 0) {
         return $½ * $Iₓ;
     }
     // $t ≥ 0
     return 1 - $½ * $Iₓ;
 }
Esempio n. 5
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);
 }
Esempio n. 6
0
 /**
  * Mean of the distribution
  *
  * μ = λΓ(1 + 1/k)
  *
  * @param number $k shape parameter
  * @param number $λ scale parameter
  *
  * @return number
  */
 public static function mean($k, $λ)
 {
     Support::checkLimits(self::LIMITS, ['k' => $k, 'λ' => $λ]);
     return $λ * Special::gamma(1 + 1 / $k);
 }
Esempio n. 7
0
 /**
  * Cumulative distribution function
  * Probability of being below X.
  * Area under the normal distribution from -∞ to X.
  *             _                  _
  *          1 |         / x - μ \  |
  * cdf(x) = - | 1 + erf|  ----- |  |
  *          2 |_        \  σ√2  / _|
  *
  * @param number $x upper bound
  * @param number $μ mean
  * @param number $σ standard deviation
  *
  * @return float cdf(x) below
  */
 public static function CDF($x, $μ, $σ) : float
 {
     Support::checkLimits(self::LIMITS, ['x' => $x, 'μ' => $μ, 'σ' => $σ]);
     return 1 / 2 * (1 + Special::erf(($x - $μ) / ($σ * sqrt(2))));
 }
Esempio n. 8
0
 /**
  * Cumulative distribution function
  *
  * cdf = Iₓ(α,β)
  *
  * @param number $α shape parameter α > 0
  * @param number $β shape parameter β > 0
  * @param number $x x ∈ (0,1)
  *
  * @return float
  */
 public static function CDF($x, $α, $β)
 {
     Support::checkLimits(self::LIMITS, ['x' => $x, 'α' => $α, 'β' => $β]);
     return Special::regularizedIncompleteBeta($x, $α, $β);
 }
Esempio n. 9
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);
 }