See Release Notes
Long Term Support Release
Differences Between: [Versions 400 and 401] [Versions 401 and 402] [Versions 401 and 403]
1 <?php 2 3 namespace PhpOffice\PhpSpreadsheet\Calculation\Statistical\Distributions; 4 5 use PhpOffice\PhpSpreadsheet\Calculation\ArrayEnabled; 6 use PhpOffice\PhpSpreadsheet\Calculation\Exception; 7 use PhpOffice\PhpSpreadsheet\Calculation\Functions; 8 use PhpOffice\PhpSpreadsheet\Calculation\Information\ExcelError; 9 10 class StudentT 11 { 12 use ArrayEnabled; 13 14 private const MAX_ITERATIONS = 256; 15 16 /** 17 * TDIST. 18 * 19 * Returns the probability of Student's T distribution. 20 * 21 * @param mixed $value Float value for the distribution 22 * Or can be an array of values 23 * @param mixed $degrees Integer value for degrees of freedom 24 * Or can be an array of values 25 * @param mixed $tails Integer value for the number of tails (1 or 2) 26 * Or can be an array of values 27 * 28 * @return array|float|string The result, or a string containing an error 29 * If an array of numbers is passed as an argument, then the returned result will also be an array 30 * with the same dimensions 31 */ 32 public static function distribution($value, $degrees, $tails) 33 { 34 if (is_array($value) || is_array($degrees) || is_array($tails)) { 35 return self::evaluateArrayArguments([self::class, __FUNCTION__], $value, $degrees, $tails); 36 } 37 38 try { 39 $value = DistributionValidations::validateFloat($value); 40 $degrees = DistributionValidations::validateInt($degrees); 41 $tails = DistributionValidations::validateInt($tails); 42 } catch (Exception $e) { 43 return $e->getMessage(); 44 } 45 46 if (($value < 0) || ($degrees < 1) || ($tails < 1) || ($tails > 2)) { 47 return ExcelError::NAN(); 48 } 49 50 return self::calculateDistribution($value, $degrees, $tails); 51 } 52 53 /** 54 * TINV. 55 * 56 * Returns the one-tailed probability of the chi-squared distribution. 57 * 58 * @param mixed $probability Float probability for the function 59 * Or can be an array of values 60 * @param mixed $degrees Integer value for degrees of freedom 61 * Or can be an array of values 62 * 63 * @return array|float|string The result, or a string containing an error 64 * If an array of numbers is passed as an argument, then the returned result will also be an array 65 * with the same dimensions 66 */ 67 public static function inverse($probability, $degrees) 68 { 69 if (is_array($probability) || is_array($degrees)) { 70 return self::evaluateArrayArguments([self::class, __FUNCTION__], $probability, $degrees); 71 } 72 73 try { 74 $probability = DistributionValidations::validateProbability($probability); 75 $degrees = DistributionValidations::validateInt($degrees); 76 } catch (Exception $e) { 77 return $e->getMessage(); 78 } 79 80 if ($degrees <= 0) { 81 return ExcelError::NAN(); 82 } 83 84 $callback = function ($value) use ($degrees) { 85 return self::distribution($value, $degrees, 2); 86 }; 87 88 $newtonRaphson = new NewtonRaphson($callback); 89 90 return $newtonRaphson->execute($probability); 91 } 92 93 /** 94 * @return float 95 */ 96 private static function calculateDistribution(float $value, int $degrees, int $tails) 97 { 98 // tdist, which finds the probability that corresponds to a given value 99 // of t with k degrees of freedom. This algorithm is translated from a 100 // pascal function on p81 of "Statistical Computing in Pascal" by D 101 // Cooke, A H Craven & G M Clark (1985: Edward Arnold (Pubs.) Ltd: 102 // London). The above Pascal algorithm is itself a translation of the 103 // fortran algoritm "AS 3" by B E Cooper of the Atlas Computer 104 // Laboratory as reported in (among other places) "Applied Statistics 105 // Algorithms", editied by P Griffiths and I D Hill (1985; Ellis 106 // Horwood Ltd.; W. Sussex, England). 107 $tterm = $degrees; 108 $ttheta = atan2($value, sqrt($tterm)); 109 $tc = cos($ttheta); 110 $ts = sin($ttheta); 111 112 if (($degrees % 2) === 1) { 113 $ti = 3; 114 $tterm = $tc; 115 } else { 116 $ti = 2; 117 $tterm = 1; 118 } 119 120 $tsum = $tterm; 121 while ($ti < $degrees) { 122 $tterm *= $tc * $tc * ($ti - 1) / $ti; 123 $tsum += $tterm; 124 $ti += 2; 125 } 126 127 $tsum *= $ts; 128 if (($degrees % 2) == 1) { 129 $tsum = Functions::M_2DIVPI * ($tsum + $ttheta); 130 } 131 132 $tValue = 0.5 * (1 + $tsum); 133 if ($tails == 1) { 134 return 1 - abs($tValue); 135 } 136 137 return 1 - abs((1 - $tValue) - $tValue); 138 } 139 }
title
Description
Body
title
Description
Body
title
Description
Body
title
Body