# tablepress/3.4/libraries/vendor/PhpSpreadsheet/Calculation/Statistical/Distributions/NewtonRaphson.php

TablePress – Tables in WordPress made easy, version 3.4. 72 lines.

- Page: https://pluginprobe.com/plugins/tablepress/3.4/code/libraries/vendor/PhpSpreadsheet/Calculation/Statistical/Distributions/NewtonRaphson.php
- Raw: https://pluginprobe.com/plugins/tablepress/3.4/raw/libraries/vendor/PhpSpreadsheet/Calculation/Statistical/Distributions/NewtonRaphson.php
- Modified: 2026-09-30T03:50:46+00:00

Line numbers below start at 1. Link to a line or a range by appending a fragment to the
page URL, for example `https://pluginprobe.com/plugins/tablepress/3.4/code/libraries/vendor/PhpSpreadsheet/Calculation/Statistical/Distributions/NewtonRaphson.php#L10-L20`.

```php
<?php

namespace TablePress\PhpOffice\PhpSpreadsheet\Calculation\Statistical\Distributions;

use TablePress\PhpOffice\PhpSpreadsheet\Calculation\Functions;
use TablePress\PhpOffice\PhpSpreadsheet\Calculation\Information\ExcelError;

class NewtonRaphson
{
	private const MAX_ITERATIONS = 256;

	/** @var callable(float): mixed */
	protected $callback;

	/** @param callable(float): mixed $callback */
	public function __construct(callable $callback)
	{
		$this->callback = $callback;
	}

	/**
				 * @return string|int|float
				 */
				public function execute(float $probability)
	{
		$xLo = 100;
		$xHi = 0;

		$dx = 1;
		$x = $xNew = 1;
		$i = 0;

		while ((abs($dx) > Functions::PRECISION) && ($i++ < self::MAX_ITERATIONS)) {
			// Apply Newton-Raphson step
			$result = call_user_func($this->callback, $x);
			if (!is_float($result)) {
				return ExcelError::VALUE();
			}
			$error = $result - $probability;

			if ($error == 0.0) {
				$dx = 0;
			} elseif ($error < 0.0) {
				$xLo = $x;
			} else {
				$xHi = $x;
			}

			// Avoid division by zero
			if ($result != 0.0) {
				$dx = $error / $result;
				$xNew = $x - $dx;
			}

			// If the NR fails to converge (which for example may be the
			// case if the initial guess is too rough) we apply a bisection
			// step to determine a more narrow interval around the root.
			if (($xNew < $xLo) || ($xNew > $xHi) || ($result == 0.0)) {
				$xNew = ($xLo + $xHi) / 2;
				$dx = $xNew - $x;
			}
			$x = $xNew;
		}

		if ($i == self::MAX_ITERATIONS) {
			return ExcelError::NA();
		}

		return $x;
	}
}

```
