public function testSolveNonzeroError()
{
// f(x) = x⁴ + 8x³ -13x² -92x + 96
$f = new Polynomial([1, 8, -13, -92, 96]);
// The error is bounded by:
// |f(x)-p(x)| = tol <= (1/4!) * h⁴ * max f⁽⁴⁾(x)
// where h = max hᵢ
// f'(x) = 4x³ +24x² -26x - 92
// f''(x) = 12x² - 48x - 26
// f'''(x) = 24x - 48
// f⁽⁴⁾(x) = 24
$a = 0;
$b = 10;
$n = 51;
// So, tol <= (1/24) * (1/5)⁴ * 24 = (1/5)⁴
$tol = 0.2 ** 4;
$roundoff = 1.0E-6;
// round off error
$p = NaturalCubicSpline::interpolate($f, $a, $b, $n);
// Check that p(x) agrees with f(x) at x = 0
$target = 0;
$expected = $f($target);
$x = $p($target);
$this->assertEquals($expected, $x, '', $tol + $roundoff);
// Check that p(x) agrees with f(x) at x = 2
$target = 2;
$expected = $f($target);
$x = $p($target);
$this->assertEquals($expected, $x, '', $tol + $roundoff);
// Check that p(x) agrees with f(x) at x = 4
$target = 4;
$expected = $f($target);
$x = $p($target);
$this->assertEquals($expected, $x, '', $tol + $roundoff);
// Check that p(x) agrees with f(x) at x = 6
$target = 6;
$expected = $f($target);
$x = $p($target);
$this->assertEquals($expected, $x, '', $tol + $roundoff);
// Check that p(x) agrees with f(x) at x = 8
$target = 8;
$expected = $f($target);
$x = $p($target);
$this->assertEquals($expected, $x, '', $tol + $roundoff);
// Check that p(x) agrees with f(x) at x = 10
$target = 10;
$expected = $f($target);
$x = $p($target);
$this->assertEquals($expected, $x, '', $tol + $roundoff);
// Check that p(x) agrees with f(x) at x = 7.32 (not a node)
$target = 7.32;
$expected = $f($target);
$x = $p($target);
$this->assertEquals($expected, $x, '', $tol + $roundoff);
}