/** * 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σ); }
/** * 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⟯; }
/** * 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).'); } }
/** * 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ₓ; }
/** * 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); }
/** * 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); }
/** * 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)))); }
/** * 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, $α, $β); }
/** * 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); }