$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;} * @param int|float ...$args * The arguments of our callback function: start, * end, and n. Example: differentiate($target, $source, 0, 8, 3). * If $source is a set of points, do not input any * $args. Example: approximate($source). * * @return float * The approximation of f'($target), i.e. the derivative * of our input at our target point * * @throws Exception\BadDataException */ public static function differentiate(float $target, $source, ...$args): float { // 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::assertSpacingConstant($sorted); self::assertTargetInPoints($target, $sorted); // Descriptive constants $x = self::X; $y = self::Y; // Initialize $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 ($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); return $derivative; } /* * 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 ($sorted[0][$x] == $target) { // The 1st point is our $target $f⟮x₀⟯ = $sorted[0][$y]; $f⟮x₀⧾h⟯ = $sorted[1][$y]; $f⟮x₀⧾2h⟯ = $sorted[2][$y]; } else { // The 3rd point is our $target, use negative h $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; } }