Numdifftools
The numdifftools library is a suite of tools written in Python to solve automatic numerical differentiation problems in one or more variables. It employs finite differences in an adaptive manner, coupled with a Richardson extrapolation methodology, to provide maximally accurate results. The library is currently at version 0.9.42 and sees active, though not rapid, development, with the documentation for 0.9.41 updated in late 2025 and PyPI showing an update for 0.9.42 in early 2022.
Warnings
- gotcha The complex-step differentiation method, while highly accurate and robust to round-off errors, requires the target function to be analytic and support complex number inputs. It will fail for non-analytic functions (e.g., `abs`, `max`, `min`) or functions that do not handle complex inputs gracefully.
- gotcha Selecting an inappropriate step size can lead to inaccurate results. Too small a step size may introduce round-off errors, while too large a step size can increase approximation errors. Numdifftools attempts to adaptively select an optimal step size, but manual override with `step` parameter should be done cautiously.
- breaking In versions around 0.9.15 to 0.9.18, a major API change occurred where the internal class member variable `self.f` was renamed to `self.fun`. If you were subclassing `numdifftools` classes or accessing these internal variables directly, your code would break.
- breaking In version 0.9.41, there was an update where an import path from `scipy.ndimage.filters` was replaced by `scipy.ndimage`. Code relying on direct imports from the `filters` submodule of `scipy.ndimage` might encounter `ImportError`.
Install
-
pip install numdifftools
Imports
- numdifftools
import numdifftools as nd
- Derivative
from numdifftools import Derivative
Quickstart
import numpy as np
import numdifftools as nd
def f(x):
return x**3 + x**2
# Compute the 1st derivative of f(x) at x=1
df = nd.Derivative(f)
result_df = df(1)
print(f"First derivative of f(x) at x=1: {result_df}")
# Compute the 2nd derivative of f(x) at x=1
ddf = nd.Derivative(f, n=2)
result_ddf = ddf(1)
print(f"Second derivative of f(x) at x=1: {result_ddf}")
# Compute the gradient of a multivariate function
def rosen(x):
return (1 - x[0])**2 + 100 * (x[1] - x[0]**2)**2
grad = nd.Gradient(rosen)
result_grad = grad([1, 1]) # At the minimum of Rosenbrock function
print(f"Gradient of Rosenbrock at (1,1): {result_grad}")