Search moodle.org's
Developer Documentation

See Release Notes
Long Term Support Release

  • Bug fixes for general core bugs in 4.1.x will end 13 November 2023 (12 months).
  • Bug fixes for security issues in 4.1.x will end 10 November 2025 (36 months).
  • PHP version: minimum PHP 7.4.0 Note: minimum PHP version has increased since Moodle 4.0. PHP 8.0.x is supported too.

Differences Between: [Versions 400 and 401] [Versions 401 and 402] [Versions 401 and 403]

   1  <?php
   2  
   3  namespace PhpOffice\PhpSpreadsheet\Calculation\Engineering;
   4  
   5  use PhpOffice\PhpSpreadsheet\Calculation\ArrayEnabled;
   6  use PhpOffice\PhpSpreadsheet\Calculation\Functions;
   7  use PhpOffice\PhpSpreadsheet\Calculation\Information\ExcelError;
   8  
   9  class Erf
  10  {
  11      use ArrayEnabled;
  12  
  13      private static $twoSqrtPi = 1.128379167095512574;
  14  
  15      /**
  16       * ERF.
  17       *
  18       * Returns the error function integrated between the lower and upper bound arguments.
  19       *
  20       *    Note: In Excel 2007 or earlier, if you input a negative value for the upper or lower bound arguments,
  21       *            the function would return a #NUM! error. However, in Excel 2010, the function algorithm was
  22       *            improved, so that it can now calculate the function for both positive and negative ranges.
  23       *            PhpSpreadsheet follows Excel 2010 behaviour, and accepts negative arguments.
  24       *
  25       *    Excel Function:
  26       *        ERF(lower[,upper])
  27       *
  28       * @param mixed $lower Lower bound float for integrating ERF
  29       *                      Or can be an array of values
  30       * @param mixed $upper Upper bound float for integrating ERF.
  31       *                           If omitted, ERF integrates between zero and lower_limit
  32       *                      Or can be an array of values
  33       *
  34       * @return array|float|string
  35       *         If an array of numbers is passed as an argument, then the returned result will also be an array
  36       *            with the same dimensions
  37       */
  38      public static function ERF($lower, $upper = null)
  39      {
  40          if (is_array($lower) || is_array($upper)) {
  41              return self::evaluateArrayArguments([self::class, __FUNCTION__], $lower, $upper);
  42          }
  43  
  44          if (is_numeric($lower)) {
  45              if ($upper === null) {
  46                  return self::erfValue($lower);
  47              }
  48              if (is_numeric($upper)) {
  49                  return self::erfValue($upper) - self::erfValue($lower);
  50              }
  51          }
  52  
  53          return ExcelError::VALUE();
  54      }
  55  
  56      /**
  57       * ERFPRECISE.
  58       *
  59       * Returns the error function integrated between the lower and upper bound arguments.
  60       *
  61       *    Excel Function:
  62       *        ERF.PRECISE(limit)
  63       *
  64       * @param mixed $limit Float bound for integrating ERF, other bound is zero
  65       *                      Or can be an array of values
  66       *
  67       * @return array|float|string
  68       *         If an array of numbers is passed as an argument, then the returned result will also be an array
  69       *            with the same dimensions
  70       */
  71      public static function ERFPRECISE($limit)
  72      {
  73          if (is_array($limit)) {
  74              return self::evaluateSingleArgumentArray([self::class, __FUNCTION__], $limit);
  75          }
  76  
  77          return self::ERF($limit);
  78      }
  79  
  80      //
  81      //    Private method to calculate the erf value
  82      //
  83      public static function erfValue($value)
  84      {
  85          if (abs($value) > 2.2) {
  86              return 1 - ErfC::ERFC($value);
  87          }
  88          $sum = $term = $value;
  89          $xsqr = ($value * $value);
  90          $j = 1;
  91          do {
  92              $term *= $xsqr / $j;
  93              $sum -= $term / (2 * $j + 1);
  94              ++$j;
  95              $term *= $xsqr / $j;
  96              $sum += $term / (2 * $j + 1);
  97              ++$j;
  98              if ($sum == 0.0) {
  99                  break;
 100              }
 101          } while (abs($term / $sum) > Functions::PRECISION);
 102  
 103          return self::$twoSqrtPi * $sum;
 104      }
 105  }