MathPHP\NumericalAnalysis\NumericalDifferentiation\FivePointFormula::differentiate PHP Method

differentiate() public static method

The Five Point Formula requires we supply 5 points that are evenly spaced apart, and that our target equals the x-components of one of our 5 points. Example: differentiation(2, function($x) {return $x**2;}, 0, 4 ,5) will produce a set of arrays by evaluating the callback at 5 evenly spaced points between 0 and 4. Then, this array will be used in our approximation. Five Point Formula: - If the 3rd point is our $target, use the Midpoint Formula: 1 h⁴ f′(x₀) = - [f(x₀-2h)-8f(x₀-h)+8f(x₀+h)-f(x₀+2h)] - - f⁽⁵⁾(ζ₁) 12h 30 where ζ₁ lies between x₀ - 2h and x₀ + 2h - If the 1st or 5th point is our $target, use the Endpoint Formula: - Note that when the 3rd point is our $target, we use a negative h. 1 h⁴ f′(x₀) = - [-25f(x₀)+48f(x₀+h)-36f(x₀+2h)+16f(x₀+3h)-3f(x₀+4h)] + - f⁽⁵⁾(ζ₀) 12h 5 where ζ₀ lies between x₀ and x₀ + 4h
public static differentiate ( numbers $target, $source, $args ) : number
$target numbers The value at which we are approximating the derivative
$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 of f'($target), i.e. the derivative of our input at our target point
    public static function differentiate($target, $source, ...$args)
    {
        // get an array of points from our $source argument
        $points = self::getPoints($source, $args);
        // Validate input, sort points, make sure spacing is constant, and make
        // sure our target is contained in an interval supplied by our $source
        self::validate($points, $degree = 5);
        $sorted = self::sort($points);
        self::isSpacingConstant($sorted);
        self::isTargetInPoints($target, $sorted);
        // Descriptive constants
        $x = self::X;
        $y = self::Y;
        // Initialize
        $n = count($sorted);
        $h = ($sorted[4][$x] - $sorted[0][$x]) / 4;
        /*
         * Five Point Formula:
         *
         *   - If the 3rd point is our $target, use the Midpoint Formula:
         *
         *              1                                         h⁴
         *     f′(x₀) = - [f(x₀-2h)-8f(x₀-h)+8f(x₀+h)-f(x₀+2h)] - - f⁽⁵⁾(ζ₁)
         *             12h                                        30
         *
         *         where ζ₁ lies between x₀ - 2h and x₀ + 2h
         *
         *   - If the 1st or 5th point is our $target, use the Endpoint Formula:
         *   - Note that when the 3rd point is our $target, we use a negative h.
         *
         *              1                                                        h⁴
         *     f′(x₀) = - [-25f(x₀)+48f(x₀+h)-36f(x₀+2h)+16f(x₀+3h)-3f(x₀+4h)] + - f⁽⁵⁾(ζ₀)
         *             12h                                                       5
         *
         *         where ζ₀ lies between x₀ and x₀ + 4h
         */
        // If the 3nd point is our $target, use the Midpoint Formula
        if ($sorted[2][$x] == $target) {
            $f⟮x₀⧿2h⟯ = $sorted[0][$y];
            $f⟮x₀⧿h⟯ = $sorted[1][$y];
            $f⟮x₀⧾h⟯ = $sorted[3][$y];
            $f⟮x₀⧾2h⟯ = $sorted[4][$y];
            $derivative = ($f⟮x₀⧿2h⟯ - 8 * $f⟮x₀⧿h⟯ + 8 * $f⟮x₀⧾h⟯ - $f⟮x₀⧾2h⟯) / (12 * $h);
            // If the 1st or 5th point is our $target, use the Endpoint Formula
        } else {
            // The 1st point is our $target
            if ($sorted[0][$x] == $target) {
                $f⟮x₀⟯ = $sorted[0][$y];
                $f⟮x₀⧾h⟯ = $sorted[1][$y];
                $f⟮x₀⧾2h⟯ = $sorted[2][$y];
                $f⟮x₀⧾3h⟯ = $sorted[3][$y];
                $f⟮x₀⧾4h⟯ = $sorted[4][$y];
                // If the 5th point is our $target, use negative h
            } else {
                $h = -$h;
                $f⟮x₀⟯ = $sorted[4][$y];
                $f⟮x₀⧾h⟯ = $sorted[3][$y];
                $f⟮x₀⧾2h⟯ = $sorted[2][$y];
                $f⟮x₀⧾3h⟯ = $sorted[1][$y];
                $f⟮x₀⧾4h⟯ = $sorted[0][$y];
            }
            $derivative = (-25 * $f⟮x₀⟯ + 48 * $f⟮x₀⧾h⟯ - 36 * $f⟮x₀⧾2h⟯ + 16 * $f⟮x₀⧾3h⟯ - 3 * $f⟮x₀⧾4h⟯) / (12 * $h);
        }
        return $derivative;
    }
FivePointFormula