2. N of $n given."); } $6n⟮n − 1⟯ = 6 * $n * ($n - 1); $⟮n − 2⟯⟮n + 1⟯⟮n + 2⟯ = ($n - 2) * ($n + 1) * ($n + 3); return sqrt($6n⟮n − 1⟯ / $⟮n − 2⟯⟮n + 1⟯⟮n + 2⟯); } /** * Sample Excess Kurtosis * A measure of the "tailedness" of the probability distribution of a real-valued random variable. * https://en.wikipedia.org/wiki/Kurtosis * * μ₄ * γ₂ = ---- − 3 * μ₂² * * μ₂ is the second central moment * μ₄ is the fourth central moment * * This is the typical definition used in textbooks. In R (e1071) it is kurtosis type 1. * * @param float[] $X list of numbers (random variable X) * * @return float * * @throws Exception\BadDataException if the input array of numbers is empty */ public static function sampleKurtosis(array $X): float { if (empty($X)) { throw new Exception\BadDataException('Cannot find the kurtosis of an empty list of numbers'); } $μ₄ = self::centralMoment($X, 4); $μ₂² = pow(self::centralMoment($X, 2), 2); if ($μ₂² == 0) { return \NAN; } return ( $μ₄ / $μ₂² ) - 3; } /** * Population Excess Kurtosis * A measure of the "tailedness" of the probability distribution of a real-valued random variable. * https://en.wikipedia.org/wiki/Kurtosis * * (n - 1) * G₂ = [(n + 1) g₂ + 6] -------------- * (n - 2)(n - 3) * * μ₄ * where g₂ is the sample kurtotis = ---- − 3 * μ₂² * * * This is the common application version of kurtosis, used in Excel, SAS and SPSS. * In R (e1071) it is kurtosis type 2. Excel's KURT function. * * @param float[] $X list of numbers (random variable X) * * @return float * * @throws Exception\BadDataException if the input array of numbers is empty or has fewer than four elements */ public static function populationKurtosis(array $X): float { if (count($X) < 4) { throw new Exception\BadDataException('Cannot find the kurtosis of an empty list of numbers'); } $g₂ = self::sampleKurtosis($X); $n = count($X); $⟮n + 1⟯g₂ + 6 = ($n + 1) * $g₂ + 6; return ($⟮n + 1⟯g₂ + 6 * ($n - 1)) / (($n - 2) * ($n - 3)); } /** * Sample Excess Kurtosis * A measure of the "tailedness" of the probability distribution of a real-valued random variable. * https://en.wikipedia.org/wiki/Kurtosis * * μ₄ * γ₂ = ---- − 3 * μ₂² * * μ₂ is the second central moment * μ₄ is the fourth central moment * * This is the typical definition used in textbooks. In R (e1071) it is kurtosis type 1. * * @param float[] $X list of numbers (random variable X) * @param string $type (optional) determines the kurtsosis algorithm used (POPULATION_KURTOSIS (default), SAMPLE_KURTOSIS) * * @return float * * @throws Exception\BadDataException if the input array of numbers is empty * @throws Exception\IncorrectTypeException */ public static function kurtosis(array $X, string $type = self::POPULATION_KURTOSIS): float { switch ($type) { case self::SAMPLE_KURTOSIS: return self::sampleKurtosis($X); case self::POPULATION_KURTOSIS: return self::populationKurtosis($X); default: throw new Exception\IncorrectTypeException("Type $type is not a valid kurtosis algorithm type"); } } /** * Is the kurtosis negative? (Platykurtic) * Indicates a flat distribution. * * @param array $X list of numbers (random variable X) * @param string $type (optional) determines the kurtsosis algorithm used (POPULATION_KURTOSIS (default), SAMPLE_KURTOSIS) * * @return bool true if platykurtic * * @throws Exception\BadDataException if the input array of numbers is empty */ public static function isPlatykurtic(array $X, string $type = self::POPULATION_KURTOSIS): bool { return self::kurtosis($X, $type) < 0; } /** * Is the kurtosis postive? (Leptokurtic) * Indicates a peaked distribution. * * @param array $X list of numbers (random variable X) * @param string $type (optional) determines the kurtsosis algorithm used (POPULATION_KURTOSIS (default), SAMPLE_KURTOSIS) * * @return bool true if leptokurtic * * @throws Exception\BadDataException if the input array of numbers is empty */ public static function isLeptokurtic(array $X, string $type = self::POPULATION_KURTOSIS): bool { return self::kurtosis($X, $type) > 0; } /** * Is the kurtosis zero? (Mesokurtic) * Indicates a normal distribution. * * @param array $X list of numbers (random variable X) * @param string $type (optional) determines the kurtsosis algorithm used (POPULATION_KURTOSIS (default), SAMPLE_KURTOSIS) * * @return bool true if mesokurtic * * @throws Exception\BadDataException if the input array of numbers is empty */ public static function isMesokurtic(array $X, string $type = self::POPULATION_KURTOSIS): bool { return self::kurtosis($X, $type) == 0; } /** * Standard Error of Kurtosis (SEK) * * ______________ * / (n² - 1) * SEK = 2(SES) / -------------- * √ (n - 3)(n + 5) * * @param int $n Sample size * * @return float * * @throws Exception\BadDataException if n < 4 */ public static function sek(int $n): float { if ($n < 4) { throw new Exception\BadDataException("SEK requires a dataset of n > 3. N of $n given."); } $2⟮SES⟯ = 2 * self::ses($n); $⟮n² − 1⟯ = $n ** 2 - 1; $⟮n − 3⟯⟮n + 5⟯ = ($n - 3) * ($n + 5); return $2⟮SES⟯ * sqrt($⟮n² − 1⟯ / $⟮n − 3⟯⟮n + 5⟯); } /** * Standard error of the mean (SEM) * The standard deviation of the sample-mean's estimate of a population mean. * https://en.wikipedia.org/wiki/Standard_error * * s * SEₓ = -- * √n * * s = sample standard deviation * n = size (number of observations) of the sample * * @param float[] $X list of numbers (random variable X) * * @return float * * @throws Exception\OutOfBoundsException * @throws Exception\BadDataException if the input array of numbers is empty */ public static function standardErrorOfTheMean(array $X): float { if (empty($X)) { throw new Exception\BadDataException('Cannot find the SEM of an empty list of numbers'); } $s = Descriptive::standardDeviation($X, Descriptive::SAMPLE); $√n = sqrt(count($X)); return $s / $√n; } /** * SEM - Convenience method for standard error of the mean * * @param array $X list of numbers (random variable X) * * @return float * * @throws Exception\OutOfBoundsException * @throws Exception\BadDataException if the input array of numbers is empty */ public static function sem(array $X): float { return self::standardErrorOfTheMean($X); } /** * Confidence interval * Finds CI given a sample mean, sample size, and standard deviation. * Uses Z score. * https://en.wikipedia.org/wiki/Confidence_interval * σ * ci = z* -- * √n * * interval = (μ - ci, μ + ci) * * Available confidence levels: See Probability\StandardNormalTable::Z_SCORES_FOR_CONFIDENCE_INTERVALS * * @param float $μ sample mean * @param int $n sample size * @param float $σ standard deviation * @param string $cl confidence level (Ex: 95, 99, 99.5, 99.9, etc.) * * @return array [ ci, lower_bound, upper_bound ] * * @throws Exception\BadDataException */ public static function confidenceInterval(float $μ, int $n, float $σ, string $cl): array { if ($n === 0) { return ['ci' => null, 'lower_bound' => null, 'upper_bound' => null]; } $z = Table\StandardNormal::getZScoreForConfidenceInterval($cl); $ci = $z * ($σ / sqrt($n)); $lower_bound = $μ - $ci; $upper_bound = $μ + $ci; return [ 'ci' => $ci, 'lower_bound' => $lower_bound, 'upper_bound' => $upper_bound, ]; } /** * Sum of squares * * ∑⟮xᵢ⟯² * * @param float[] $numbers * * @return float * * @throws Exception\BadDataException if the input array of numbers is empty */ public static function sumOfSquares(array $numbers): float { if (empty($numbers)) { throw new Exception\BadDataException('Cannot find the sum of squares of an empty list of numbers'); } $∑⟮xᵢ⟯² = array_sum(Map\Single::square($numbers)); return $∑⟮xᵢ⟯²; } /** * Sum of squares deviations * * ∑⟮xᵢ - μ⟯² * * @param float[] $numbers * * @return float * * @throws Exception\BadDataException if the input array of numbers is empty */ public static function sumOfSquaresDeviations(array $numbers): float { if (empty($numbers)) { throw new Exception\BadDataException('Cannot find the sum of squares deviations of an empty list of numbers'); } $μ = Average::mean($numbers); $∑⟮xᵢ − μ⟯² = array_sum(array_map( function ($xᵢ) use ($μ) { return pow(($xᵢ - $μ), 2); }, $numbers )); return $∑⟮xᵢ − μ⟯²; } }