Search moodle.org's
Developer Documentation

See Release Notes

  • Bug fixes for general core bugs in 4.3.x will end 7 October 2024 (12 months).
  • Bug fixes for security issues in 4.3.x will end 21 April 2025 (18 months).
  • PHP version: minimum PHP 8.0.0 Note: minimum PHP version has increased since Moodle 4.1. PHP 8.2.x is supported too.

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  }