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

differentiate() public static method

The Three Point Formula requires we supply 3 points that are evenly spaced apart, and that our target equals the x-components of one of our 3 points. Example: differentiation(2, function($x) {return $x**2;}, 0, 4 ,3) will produce a set of arrays by evaluating the callback at 3 evenly spaced points between 0 and 4. Then, this array will be used in our approximation. Three Point Formula: - If the 2nd point is our $target, use the Midpoint Formula: 1 h² f′(x₀) = - [f(x₀+h)-f(x₀-h)] - - f⁽³⁾(ζ₁) 2h 6 where ζ₁ lies between x₀ - h and x₀ + h - If the 1st or 3rd 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₀) = - [-3f(x₀)+4f(x₀+h)-f(x₀+2h)] + - f⁽³⁾(ζ₀) 2h 3 where ζ₀ lies between x₀ and x₀ + 2h
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]]. 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 = 3);
        $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[2][$x] - $sorted[0][$x]) / 2;
        /*
         * If the 2nd point is our $target, use the Midpoint Formula:
         *
         *          1                     h²
         * f′(x₀) = - [f(x₀+h)-f(x₀-h)] - - f⁽³⁾(ζ₁)
         *          2h                    6
         *
         *     where ζ₁ lies between x₀ - h and x₀ + h
         *
         * If the 1st or 3rd 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₀) = - [-3f(x₀)+4f(x₀+h)-f(x₀+2h)] + - f⁽³⁾(ζ₀)
         *          2h                              3
         *
         *     where ζ₀ lies between x₀ and x₀ + 2h
         */
        // If the 2nd point is our $target, use the Midpoint Formula
        if ($sorted[1][$x] == $target) {
            $f⟮x₀⧿h⟯ = $sorted[0][$y];
            $f⟮x₀⧾h⟯ = $sorted[2][$y];
            $derivative = ($f⟮x₀⧾h⟯ - $f⟮x₀⧿h⟯) / (2 * $h);
            // If the 1st or 3rd 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];
                // If the 3rd point is our $target, use negative h
            } else {
                $h = -$h;
                $f⟮x₀⟯ = $sorted[2][$y];
                $f⟮x₀⧾h⟯ = $sorted[1][$y];
                $f⟮x₀⧾2h⟯ = $sorted[0][$y];
            }
            $derivative = (-3 * $f⟮x₀⟯ + 4 * $f⟮x₀⧾h⟯ - $f⟮x₀⧾2h⟯) / (2 * $h);
        }
        return $derivative;
    }
ThreePointFormula