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