PluginProbe
TablePress – Tables in WordPress made easy / 3.4
TablePress – Tables in WordPress made easy v3.4
3.4 3.3.4 3.3.3 3.3.2 3.3.1 trunk 1.12 1.14 1.9.2 2.0.4 2.1.7 2.1.8 2.2 2.2.1 2.2.2 2.2.3 2.2.4 2.2.5 2.3 2.3.1 2.3.2 2.4 2.4.1 2.4.2 2.4.3 All 45 releases
← All changes | libraries/vendor/PhpSpreadsheet/Calculation/Statistical/Distributions/ChiSquared.php +13 -75 3.3.3 → 3.4 View file →
@@ -49,9 +49,9 @@
49 49
50 50 return ExcelError::NAN();
51 51 }
52 52
53 - return 1 - (Gamma::incompleteGamma($degrees / 2, $value / 2) / Gamma::gammaValue($degrees / 2));
53 + return Gamma::regularizedGammaQ($degrees / 2, $value / 2);
54 54 }
55 55
56 56 /**
57 57 * CHIDIST.
@@ -98,10 +98,18 @@
98 98
99 99 return 1 - (is_numeric($temp) ? $temp : 0);
100 100 }
101 101
102 - return ($value ** (($degrees / 2) - 1) * exp(-$value / 2))
103 - / ((2 ** ($degrees / 2)) * Gamma::gammaValue($degrees / 2));
102 + if ($value == 0.0) {
103 + if ($degrees === 2) {
104 + return 0.5;
105 + }
106 +
107 + return ($degrees === 1) ? INF : 0.0;
108 + }
109 +
110 + // Log domain, so large degrees of freedom cannot overflow Gamma(d/2).
111 + return exp((($degrees / 2) - 1) * log($value) - $value / 2 - ($degrees / 2) * M_LN2 - Gamma::logGamma($degrees / 2));
104 112 }
105 113
106 114 /**
107 115 * CHIINV.
@@ -132,10 +140,9 @@
132 140 if ($degrees < 1) {
133 141 return ExcelError::NAN();
134 142 }
135 143
136 - $callback = fn (float $value): float => 1 - (Gamma::incompleteGamma($degrees / 2, $value / 2)
137 - / Gamma::gammaValue($degrees / 2));
144 + $callback = fn (float $value): float => Gamma::regularizedGammaQ($degrees / 2, $value / 2);
138 145
139 146 $newtonRaphson = new NewtonRaphson($callback);
140 147
141 148 return $newtonRaphson->execute($probability);
@@ -258,76 +265,7 @@
258 265 }
259 266
260 267 private static function pchisq(float $chi2, int $degrees): float
261 268 {
262 - return self::gammp($degrees, 0.5 * $chi2);
263 - }
264 -
265 - private static function gammp(int $n, float $x): float
266 - {
267 - if ($x < 0.5 * $n + 1) {
268 - return self::gser($n, $x);
269 - }
270 -
271 - return 1 - self::gcf($n, $x);
272 - }
273 -
274 - // Return the incomplete gamma function P(n/2,x) evaluated by
275 - // series representation. Algorithm from numerical recipe.
276 - // Assume that n is a positive integer and x>0, won't check arguments.
277 - // Relative error controlled by the eps parameter
278 - private static function gser(int $n, float $x): float
279 - {
280 - /** @var float $gln */
281 - $gln = Gamma::ln($n / 2);
282 - $a = 0.5 * $n;
283 - $ap = $a;
284 - $sum = 1.0 / $a;
285 - $del = $sum;
286 - for ($i = 1; $i < 101; ++$i) {
287 - ++$ap;
288 - $del = $del * $x / $ap;
289 - $sum += $del;
290 - if ($del < $sum * self::EPS) {
291 - break;
292 - }
293 - }
294 -
295 - return $sum * exp(-$x + $a * log($x) - $gln);
296 - }
297 -
298 - // Return the incomplete gamma function Q(n/2,x) evaluated by
299 - // its continued fraction representation. Algorithm from numerical recipe.
300 - // Assume that n is a postive integer and x>0, won't check arguments.
301 - // Relative error controlled by the eps parameter
302 - private static function gcf(int $n, float $x): float
303 - {
304 - /** @var float $gln */
305 - $gln = Gamma::ln($n / 2);
306 - $a = 0.5 * $n;
307 - $b = $x + 1 - $a;
308 - $fpmin = 1.e-300;
309 - $c = 1 / $fpmin;
310 - $d = 1 / $b;
311 - $h = $d;
312 - for ($i = 1; $i < 101; ++$i) {
313 - $an = -$i * ($i - $a);
314 - $b += 2;
315 - $d = $an * $d + $b;
316 - if (abs($d) < $fpmin) {
317 - $d = $fpmin;
318 - }
319 - $c = $b + $an / $c;
320 - if (abs($c) < $fpmin) {
321 - $c = $fpmin;
322 - }
323 - $d = 1 / $d;
324 - $del = $d * $c;
325 - $h = $h * $del;
326 - if (abs($del - 1) < self::EPS) {
327 - break;
328 - }
329 - }
330 -
331 - return $h * exp(-$x + $a * log($x) - $gln);
269 + return Gamma::regularizedGammaP($degrees / 2, 0.5 * $chi2);
332 270 }
333 271 }