MathPHP\NumericalAnalysis\NumericalIntegration\BoolesRule::approximate PHP Method

approximate() public static method

Note: Boole's rule requires that our number of subintervals is a factor of four (we must supply an n points such that n-1 is a multiple of four) and also that the size of each subinterval is equal (spacing between each point is equal). The bounds of the definite integral to which we are approximating is determined by the our inputs. Example: approximate([0, 10], [2, 5], [4, 7], [6,3]) will approximate the definite integral of the function that produces these coordinates with a lower bound of 0, and an upper bound of 6. Example: approximate(function($x) {return $x**2;}, [0, 3 ,5]) will produce a set of arrays by evaluating the callback at 5 evenly spaced points between 0 and 3. Then, this array will be used in our approximation. Boole's Rule: xn ⁿ⁻¹ xᵢ₊₁ ∫ f(x)dx = ∑ ∫ f(x)dx x₁ ⁱ⁼¹ xᵢ ⁽ⁿ⁻¹⁾/⁴ 2h = ∑ -- [7f⟮x₄ᵢ₋₃⟯ + 32f⟮x₄ᵢ₋₂⟯ + 12f⟮x₄ᵢ₋₁⟯ + 32f⟮x₄ᵢ⟯ + 7f⟮x₄ᵢ₊₁⟯] + O(h⁷f⁽⁶⁾(x)) ⁱ⁼¹ 45 where h = (xn - x₁) / (n - 1)
public static approximate ( $source, $args ) : number
$source The source of our approximation. Should be either a callback function or a set of arrays. Each array (point) contains precisely two numbers, an x and y. Example array: [[1,2], [2,3], [3,4], [4,5], [5,6]]. Example callback: function($x) {return $x**2;}
return number The approximation to the integral of f(x)
    public static function approximate($source, ...$args)
    {
        // get an array of points from our $source argument
        $points = self::getPoints($source, $args);
        // Validate input and sort points
        self::validate($points, $degree = 5);
        Validation::isSubintervalsMultiple($points, $m = 4);
        $sorted = self::sort($points);
        Validation::isSpacingConstant($sorted);
        // Descriptive constants
        $x = self::X;
        $y = self::Y;
        // Initialize
        $n = count($sorted);
        $subintervals = $n - 1;
        $a = $sorted[0][$x];
        $b = $sorted[$n - 1][$x];
        $h = ($b - $a) / $subintervals;
        $approximation = 0;
        /*
         * ⁽ⁿ⁻¹⁾/⁴ 2h
         *  = ∑    -- [7f⟮x₄ᵢ₋₃⟯ + 32f⟮x₄ᵢ₋₂⟯ + 12f⟮x₄ᵢ₋₁⟯ + 32f⟮x₄ᵢ⟯ + 7f⟮x₄ᵢ₊₁⟯] + O(h⁷f⁽⁶⁾(x))
         *   ⁱ⁼¹   45
         */
        for ($i = 1; $i < $subintervals / 4 + 1; $i++) {
            $x₄ᵢ₋₃ = $sorted[4 * $i - 4][$x];
            $x₄ᵢ₋₂ = $sorted[4 * $i - 3][$x];
            $x₄ᵢ₋₁ = $sorted[4 * $i - 2][$x];
            $x₄ᵢ = $sorted[4 * $i - 1][$x];
            $x₄ᵢ₊₁ = $sorted[4 * $i][$x];
            $f⟮x₄ᵢ₋₃⟯ = $sorted[4 * $i - 4][$y];
            // y₄ᵢ₋₃
            $f⟮x₄ᵢ₋₂⟯ = $sorted[4 * $i - 3][$y];
            // y₄ᵢ₋₂
            $f⟮x₄ᵢ₋₁⟯ = $sorted[4 * $i - 2][$y];
            // y₄ᵢ₋₁
            $f⟮x₄ᵢ⟯ = $sorted[4 * $i - 1][$y];
            // y₄ᵢ
            $f⟮x₄ᵢ₊₁⟯ = $sorted[4 * $i][$y];
            // y₄ᵢ₊₁
            $lagrange = LagrangePolynomial::interpolate([[$x₄ᵢ₋₃, $f⟮x₄ᵢ₋₃⟯], [$x₄ᵢ₋₂, $f⟮x₄ᵢ₋₂⟯], [$x₄ᵢ₋₁, $f⟮x₄ᵢ₋₁⟯], [$x₄ᵢ, $f⟮x₄ᵢ⟯], [$x₄ᵢ₊₁, $f⟮x₄ᵢ₊₁⟯]]);
            $integral = $lagrange->integrate();
            $approximation += $integral($x₄ᵢ₊₁) - $integral($x₄ᵢ₋₃);
            // definite integral of lagrange polynomial
        }
        return $approximation;
    }
BoolesRule