You are here

public static function PHPExcel_Calculation_Statistical::CRITBINOM in Loft Data Grids 6.2

Same name and namespace in other branches
  1. 7.2 vendor/phpoffice/phpexcel/Classes/PHPExcel/Calculation/Statistical.php \PHPExcel_Calculation_Statistical::CRITBINOM()

* CRITBINOM * * Returns the smallest value for which the cumulative binomial distribution is greater * than or equal to a criterion value * * See http://support.microsoft.com/kb/828117/ for details of the algorithm used * *

Parameters

float $trials number of Bernoulli trials: * @param float $probability probability of a success on each trial * @param float $alpha criterion value * @return int * * @todo Warning. This implementation differs from the algorithm detailed on the MS * web site in that $CumPGuessMinus1 = $CumPGuess - 1 rather than $CumPGuess - $PGuess * This eliminates a potential endless loop error, but may have an adverse affect on the * accuracy of the function (although all my tests have so far returned correct results). *

File

vendor/phpoffice/phpexcel/Classes/PHPExcel/Calculation/Statistical.php, line 1330

Class

PHPExcel_Calculation_Statistical
PHPExcel_Calculation_Statistical

Code

public static function CRITBINOM($trials, $probability, $alpha) {
  $trials = floor(PHPExcel_Calculation_Functions::flattenSingleValue($trials));
  $probability = PHPExcel_Calculation_Functions::flattenSingleValue($probability);
  $alpha = PHPExcel_Calculation_Functions::flattenSingleValue($alpha);
  if (is_numeric($trials) && is_numeric($probability) && is_numeric($alpha)) {
    if ($trials < 0) {
      return PHPExcel_Calculation_Functions::NaN();
    }
    if ($probability < 0 || $probability > 1) {
      return PHPExcel_Calculation_Functions::NaN();
    }
    if ($alpha < 0 || $alpha > 1) {
      return PHPExcel_Calculation_Functions::NaN();
    }
    if ($alpha <= 0.5) {
      $t = sqrt(log(1 / ($alpha * $alpha)));
      $trialsApprox = 0 - ($t + (2.515517 + 0.802853 * $t + 0.010328 * $t * $t) / (1 + 1.432788 * $t + 0.189269 * $t * $t + 0.001308 * $t * $t * $t));
    }
    else {
      $t = sqrt(log(1 / pow(1 - $alpha, 2)));
      $trialsApprox = $t - (2.515517 + 0.802853 * $t + 0.010328 * $t * $t) / (1 + 1.432788 * $t + 0.189269 * $t * $t + 0.001308 * $t * $t * $t);
    }
    $Guess = floor($trials * $probability + $trialsApprox * sqrt($trials * $probability * (1 - $probability)));
    if ($Guess < 0) {
      $Guess = 0;
    }
    elseif ($Guess > $trials) {
      $Guess = $trials;
    }
    $TotalUnscaledProbability = $UnscaledPGuess = $UnscaledCumPGuess = 0.0;
    $EssentiallyZero = 9.999999999999999E-12;
    $m = floor($trials * $probability);
    ++$TotalUnscaledProbability;
    if ($m == $Guess) {
      ++$UnscaledPGuess;
    }
    if ($m <= $Guess) {
      ++$UnscaledCumPGuess;
    }
    $PreviousValue = 1;
    $Done = False;
    $k = $m + 1;
    while (!$Done && $k <= $trials) {
      $CurrentValue = $PreviousValue * ($trials - $k + 1) * $probability / ($k * (1 - $probability));
      $TotalUnscaledProbability += $CurrentValue;
      if ($k == $Guess) {
        $UnscaledPGuess += $CurrentValue;
      }
      if ($k <= $Guess) {
        $UnscaledCumPGuess += $CurrentValue;
      }
      if ($CurrentValue <= $EssentiallyZero) {
        $Done = True;
      }
      $PreviousValue = $CurrentValue;
      ++$k;
    }
    $PreviousValue = 1;
    $Done = False;
    $k = $m - 1;
    while (!$Done && $k >= 0) {
      $CurrentValue = $PreviousValue * $k + 1 * (1 - $probability) / (($trials - $k) * $probability);
      $TotalUnscaledProbability += $CurrentValue;
      if ($k == $Guess) {
        $UnscaledPGuess += $CurrentValue;
      }
      if ($k <= $Guess) {
        $UnscaledCumPGuess += $CurrentValue;
      }
      if ($CurrentValue <= $EssentiallyZero) {
        $Done = True;
      }
      $PreviousValue = $CurrentValue;
      --$k;
    }
    $PGuess = $UnscaledPGuess / $TotalUnscaledProbability;
    $CumPGuess = $UnscaledCumPGuess / $TotalUnscaledProbability;

    //			$CumPGuessMinus1 = $CumPGuess - $PGuess;
    $CumPGuessMinus1 = $CumPGuess - 1;
    while (True) {
      if ($CumPGuessMinus1 < $alpha && $CumPGuess >= $alpha) {
        return $Guess;
      }
      elseif ($CumPGuessMinus1 < $alpha && $CumPGuess < $alpha) {
        $PGuessPlus1 = $PGuess * ($trials - $Guess) * $probability / $Guess / (1 - $probability);
        $CumPGuessMinus1 = $CumPGuess;
        $CumPGuess = $CumPGuess + $PGuessPlus1;
        $PGuess = $PGuessPlus1;
        ++$Guess;
      }
      elseif ($CumPGuessMinus1 >= $alpha && $CumPGuess >= $alpha) {
        $PGuessMinus1 = $PGuess * $Guess * (1 - $probability) / ($trials - $Guess + 1) / $probability;
        $CumPGuess = $CumPGuessMinus1;
        $CumPGuessMinus1 = $CumPGuessMinus1 - $PGuess;
        $PGuess = $PGuessMinus1;
        --$Guess;
      }
    }
  }
  return PHPExcel_Calculation_Functions::VALUE();
}