This tutorial shows you how to use the ndpolator Python API for n-dimensional interpolation.
Basic 2D Example
Here's a simple 2D interpolation example:
import numpy as np
from ndpolator import Ndpolator
x = np.linspace(0, 10, 11)
y = np.linspace(0, 5, 6)
ndp = Ndpolator(basic_axes=(x, y))
values = np.sin(x[:, None]) * np.cos(y[None, :])
grid = values.reshape(11, 6, 1)
ndp.register(name='my_function', associated_axes=None, grid=grid)
query_points = np.array([[2.5, 1.5],
[5.0, 3.0],
[0.0, 0.0]])
result = ndp.ndpolate('my_function', query_points)
print("Interpolated values:", result['interps'])
Nearest Extrapolation
ndpolator can also extrapolate beyond the grid boundaries:
query_points = np.array([[15.0, 2.0],
[5.0, 10.0],
[-1.0, -1.0]])
result = ndp.ndpolate('my_function', query_points,
extrapolation_method='nearest')
print("Extrapolated values:", result['interps'])
print("Distances to nearest points:", result['dists'])
Linear Extrapolation
result = ndp.ndpolate('my_function', query_points,
extrapolation_method='linear')
print("Extrapolated values:", result['interps'])
print("Distances to nearest points:", result['dists'])
Advanced Usage
Working with Associated Axes
For more complex grids with both basic and associated dimensions:
basic_axes = (np.linspace(0, 1, 5),
np.linspace(0, 1, 4))
associated_axes = (np.linspace(0, 2*np.pi, 8),)
ndp = Ndpolator(basic_axes)
grid = np.random.random((5, 4, 8, 2))
ndp.register('complex_function', associated_axes, grid)
query_pts = np.array([[0.5, 0.5, np.pi],
[0.8, 0.2, np.pi/2]])
result = ndp.ndpolate('complex_function', query_pts)
Multiple Interpolation Tables
You can register multiple functions on the same axes:
ndp.register('temperature', None, temp_grid)
ndp.register('pressure', None, pressure_grid)
ndp.register('density', None, density_grid)
temp_result = ndp.ndpolate('temperature', query_points)
pressure_result = ndp.ndpolate('pressure', query_points)
density_result = ndp.ndpolate('density', query_points)
print("Available tables:", ndp.tables)
Sparse Grids
Ndpolator handles sparse grids where some vertices contain NaN values. This is useful for irregular data or when some combinations of parameters are invalid:
import numpy as np
from ndpolator import Ndpolator
x = np.array([1.0, 2.0, 3.0])
y = np.array([10.0, 20.0, 30.0, 40.0])
ndp = Ndpolator((x, y))
grid = np.array([
[[1.0], [2.0], [np.nan], [4.0]],
[[5.0], [np.nan], [7.0], [8.0]],
[[np.nan], [10.0], [11.0], [12.0]]
])
ndp.register('sparse_function', None, grid)
query_points = np.array([
[2.5, 35.0],
[1.5, 35.0],
[1.0, 30.0],
[1.5, 15.0],
[3.5, 45.0]
])
result = ndp.ndpolate('sparse_function', query_points)
print("Interpolated values:", result['interps'])
result = ndp.ndpolate('sparse_function', query_points, extrapolation_method='nearest')
print("With nearest extrapolation:", result['interps'])
result = ndp.ndpolate('sparse_function', query_points, extrapolation_method='linear')
print("With linear extrapolation:", result['interps'])
Performance Tips
Search Algorithms
Choose the right search algorithm for your data size:
result = ndp.ndpolate('my_function', query_points,
search_algorithm='kdtree')
result = ndp.ndpolate('my_function', query_points,
search_algorithm='linear')
Common Errors and Solutions
Grid Shape Errors
Make sure your grid dimensions match your axes:
x = np.linspace(0, 1, 5)
y = np.linspace(0, 1, 4)
grid = np.random.random((3, 3, 1))
grid = np.random.random((5, 4, 1))
Extrapolation Errors
Handle out-of-bounds queries appropriately:
result = ndp.ndpolate('my_function', query_points,
extrapolation_method='none')
result = ndp.ndpolate('my_function', query_points,
extrapolation_method='nearest')
See Also