A callable model does not always expose a symbolic formula for its slope. Finite-difference differentiation estimates that slope by sampling nearby values, which makes it useful for checking black-box functions and validating hand-written gradients.

SciPy's scipy.differentiate.derivative() computes the first derivative of an elementwise real scalar function and returns both the estimate and convergence metadata. The scipy.differentiate namespace was added in SciPy 1.15, so older environments must be upgraded before this import is available.

Finite differences work best for smooth functions at points where nearby evaluations remain inside the function's domain. Near a boundary, use step_direction for one-sided differences; for a noisy function, compare the reported error with the precision the application actually needs.

Steps to compute a numerical derivative with SciPy:

  1. Create derivative_demo.py with the callable and evaluation point.
    derivative_demo.py
    import numpy as np
    from scipy.differentiate import derivative
     
     
    def f(x):
        return np.sin(x)
     
     
    x = np.pi / 4
  2. Add the derivative calculation and convergence guard after the evaluation point.
    result = derivative(f, x)
     
    if not result.success:
        raise RuntimeError(f"derivative failed with status {result.status}")
  3. Add an analytical comparison after the convergence guard.
    expected = np.cos(x)
    absolute_error = abs(result.df - expected)
    np.testing.assert_allclose(result.df, expected, rtol=1e-10, atol=1e-12)

    The known derivative of sin(x) is cos(x), so this assertion can fail independently if the numerical estimate is outside the chosen tolerance.

  4. Add concise result reporting after the analytical comparison.
    print(f"derivative: {result.df:.8f}")
    print(f"expected: {expected:.8f}")
    print(f"absolute error: {absolute_error:.2e}")
    print(f"status: {int(result.status)}")
    print(f"estimated error: {result.error:.2e}")
  5. Run the completed derivative script at pi/4.
    $ python3 derivative_demo.py
    derivative: 0.70710678
    expected: 0.70710678
    absolute error: 6.55e-15
    status: 0
    estimated error: 1.85e-12

    Status 0 means SciPy met its convergence tolerance. The NumPy assertion exits with an error instead of printing this block when the estimate differs from cos(pi/4) beyond the specified tolerance.