Non-Uniform Grids
findiff supports non-uniform (non-equidistant) grids. Instead of passing a scalar grid spacing, pass the full coordinate array.
import numpy as np
from findiff import Diff
import matplotlib.pyplot as plt
Example function
Consider \(f(x) = x \, e^{-x^2}\):
def f(x):
return x * np.exp(-x**2)
def df_dx(x):
return np.exp(-x**2) - 2*x**2*np.exp(-x**2)
Uniform grid limitations
On a coarse uniform grid, the derivative is inaccurate where the function has high curvature:
x_coarse = np.linspace(0, 10, 20)
d_dx = Diff(0, x_coarse[1] - x_coarse[0])
df = d_dx(f(x_coarse)) # large error near x < 3
Non-uniform grid
Instead, use a non-uniform grid with higher density where curvature is high:
x_nu = np.r_[
np.linspace(0, 0.5, 3, endpoint=False),
np.linspace(0.5, 1.2, 7, endpoint=False),
np.linspace(1.2, 1.9, 2, endpoint=False),
np.linspace(1.9, 2.9, 5, endpoint=False),
np.linspace(2.9, 10, 3),
]
# Pass the full coordinate array instead of a scalar spacing
d_dx = Diff(0, x_nu, acc=2)
df_nu = d_dx(f(x_nu))
The error is much smaller with the same number of points (20), because the grid density matches the function’s curvature.
Points near the boundary
Changed in version 0.16.
Points too close to the boundary for a centered stencil use the stencil points
closest to the boundary, including the boundary point itself. Besides being
accurate, this keeps the discrete second derivative stable in time-dependent
problems (diffusion and wave equations) for acc=2 and acc=4, also on
grids that are strongly clustered at the boundary, such as Chebyshev grids.
See Time-Dependent PDEs for stability with higher accuracy orders.