ILIAS  release_5-4 Revision v5.4.26-12-gabc799a52e6
Normal.php
Go to the documentation of this file.
1 <?php
2 
4 
8 
9 class Normal
10 {
11  public const SQRT2PI = 2.5066282746310005024157652848110452530069867406099;
12 
27  public static function distribution($value, $mean, $stdDev, $cumulative)
28  {
29  $value = Functions::flattenSingleValue($value);
30  $mean = Functions::flattenSingleValue($mean);
31  $stdDev = Functions::flattenSingleValue($stdDev);
32 
33  try {
36  $stdDev = DistributionValidations::validateFloat($stdDev);
37  $cumulative = DistributionValidations::validateBool($cumulative);
38  } catch (Exception $e) {
39  return $e->getMessage();
40  }
41 
42  if ($stdDev < 0) {
43  return Functions::NAN();
44  }
45 
46  if ($cumulative) {
47  return 0.5 * (1 + Engineering\Erf::erfValue(($value - $mean) / ($stdDev * sqrt(2))));
48  }
49 
50  return (1 / (self::SQRT2PI * $stdDev)) * exp(0 - (($value - $mean) ** 2 / (2 * ($stdDev * $stdDev))));
51  }
52 
64  public static function inverse($probability, $mean, $stdDev)
65  {
66  $probability = Functions::flattenSingleValue($probability);
67  $mean = Functions::flattenSingleValue($mean);
68  $stdDev = Functions::flattenSingleValue($stdDev);
69 
70  try {
71  $probability = DistributionValidations::validateProbability($probability);
73  $stdDev = DistributionValidations::validateFloat($stdDev);
74  } catch (Exception $e) {
75  return $e->getMessage();
76  }
77 
78  if ($stdDev < 0) {
79  return Functions::NAN();
80  }
81 
82  return (self::inverseNcdf($probability) * $stdDev) + $mean;
83  }
84 
85  /*
86  * inverse_ncdf.php
87  * -------------------
88  * begin : Friday, January 16, 2004
89  * copyright : (C) 2004 Michael Nickerson
90  * email : nickersonm@yahoo.com
91  *
92  */
93  private static function inverseNcdf($p)
94  {
95  // Inverse ncdf approximation by Peter J. Acklam, implementation adapted to
96  // PHP by Michael Nickerson, using Dr. Thomas Ziegler's C implementation as
97  // a guide. http://home.online.no/~pjacklam/notes/invnorm/index.html
98  // I have not checked the accuracy of this implementation. Be aware that PHP
99  // will truncate the coeficcients to 14 digits.
100 
101  // You have permission to use and distribute this function freely for
102  // whatever purpose you want, but please show common courtesy and give credit
103  // where credit is due.
104 
105  // Input paramater is $p - probability - where 0 < p < 1.
106 
107  // Coefficients in rational approximations
108  static $a = [
109  1 => -3.969683028665376e+01,
110  2 => 2.209460984245205e+02,
111  3 => -2.759285104469687e+02,
112  4 => 1.383577518672690e+02,
113  5 => -3.066479806614716e+01,
114  6 => 2.506628277459239e+00,
115  ];
116 
117  static $b = [
118  1 => -5.447609879822406e+01,
119  2 => 1.615858368580409e+02,
120  3 => -1.556989798598866e+02,
121  4 => 6.680131188771972e+01,
122  5 => -1.328068155288572e+01,
123  ];
124 
125  static $c = [
126  1 => -7.784894002430293e-03,
127  2 => -3.223964580411365e-01,
128  3 => -2.400758277161838e+00,
129  4 => -2.549732539343734e+00,
130  5 => 4.374664141464968e+00,
131  6 => 2.938163982698783e+00,
132  ];
133 
134  static $d = [
135  1 => 7.784695709041462e-03,
136  2 => 3.224671290700398e-01,
137  3 => 2.445134137142996e+00,
138  4 => 3.754408661907416e+00,
139  ];
140 
141  // Define lower and upper region break-points.
142  $p_low = 0.02425; //Use lower region approx. below this
143  $p_high = 1 - $p_low; //Use upper region approx. above this
144 
145  if (0 < $p && $p < $p_low) {
146  // Rational approximation for lower region.
147  $q = sqrt(-2 * log($p));
148 
149  return ((((($c[1] * $q + $c[2]) * $q + $c[3]) * $q + $c[4]) * $q + $c[5]) * $q + $c[6]) /
150  (((($d[1] * $q + $d[2]) * $q + $d[3]) * $q + $d[4]) * $q + 1);
151  } elseif ($p_high < $p && $p < 1) {
152  // Rational approximation for upper region.
153  $q = sqrt(-2 * log(1 - $p));
154 
155  return -((((($c[1] * $q + $c[2]) * $q + $c[3]) * $q + $c[4]) * $q + $c[5]) * $q + $c[6]) /
156  (((($d[1] * $q + $d[2]) * $q + $d[3]) * $q + $d[4]) * $q + 1);
157  }
158 
159  // Rational approximation for central region.
160  $q = $p - 0.5;
161  $r = $q * $q;
162 
163  return ((((($a[1] * $r + $a[2]) * $r + $a[3]) * $r + $a[4]) * $r + $a[5]) * $r + $a[6]) * $q /
164  ((((($b[1] * $r + $b[2]) * $r + $b[3]) * $r + $b[4]) * $r + $b[5]) * $r + 1);
165  }
166 }
static inverse($probability, $mean, $stdDev)
NORMINV.
Definition: Normal.php:64
$r
Definition: example_031.php:79
static distribution($value, $mean, $stdDev, $cumulative)
NORMDIST.
Definition: Normal.php:27
static flattenSingleValue($value='')
Convert an array to a single scalar value by extracting the first element.
Definition: Functions.php:649
for($i=6; $i< 13; $i++) for($i=1; $i< 13; $i++) $d
Definition: date.php:296