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
tablepress / libraries / vendor / PhpSpreadsheet / Calculation / Statistical / Distributions / NewtonRaphson.php

NewtonRaphson.php in TablePress – Tables in WordPress made easy 3.4, at libraries/vendor/PhpSpreadsheet/Calculation/Statistical/Distributions/NewtonRaphson.php

72 lines 1.5 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2
3 namespace TablePress\PhpOffice\PhpSpreadsheet\Calculation\Statistical\Distributions;
4
5 use TablePress\PhpOffice\PhpSpreadsheet\Calculation\Functions;
6 use TablePress\PhpOffice\PhpSpreadsheet\Calculation\Information\ExcelError;
7
8 class NewtonRaphson
9 {
10 private const MAX_ITERATIONS = 256;
11
12 /** @var callable(float): mixed */
13 protected $callback;
14
15 /** @param callable(float): mixed $callback */
16 public function __construct(callable $callback)
17 {
18 $this->callback = $callback;
19 }
20
21 /**
22 * @return string|int|float
23 */
24 public function execute(float $probability)
25 {
26 $xLo = 100;
27 $xHi = 0;
28
29 $dx = 1;
30 $x = $xNew = 1;
31 $i = 0;
32
33 while ((abs($dx) > Functions::PRECISION) && ($i++ < self::MAX_ITERATIONS)) {
34 // Apply Newton-Raphson step
35 $result = call_user_func($this->callback, $x);
36 if (!is_float($result)) {
37 return ExcelError::VALUE();
38 }
39 $error = $result - $probability;
40
41 if ($error == 0.0) {
42 $dx = 0;
43 } elseif ($error < 0.0) {
44 $xLo = $x;
45 } else {
46 $xHi = $x;
47 }
48
49 // Avoid division by zero
50 if ($result != 0.0) {
51 $dx = $error / $result;
52 $xNew = $x - $dx;
53 }
54
55 // If the NR fails to converge (which for example may be the
56 // case if the initial guess is too rough) we apply a bisection
57 // step to determine a more narrow interval around the root.
58 if (($xNew < $xLo) || ($xNew > $xHi) || ($result == 0.0)) {
59 $xNew = ($xLo + $xHi) / 2;
60 $dx = $xNew - $x;
61 }
62 $x = $xNew;
63 }
64
65 if ($i == self::MAX_ITERATIONS) {
66 return ExcelError::NA();
67 }
68
69 return $x;
70 }
71 }
72