INTERPN
This function interpolates values on a regular or rectilinear 2D grid and evaluates the interpolant at specified query points. It supports linear, nearest-neighbor, and spline-based 2D interpolation modes supported by the underlying library.
If grid axes are x_i and y_j with tabulated values f(x_i, y_j), the function estimates \hat{f}(x, y) for each query coordinate pair (x, y) using the selected interpolation method.
Excel Usage
=INTERPN(points_x, points_y, values, xi, interpn_method, bounds_error, fill_value)
points_x(list[list], required): Column vector of x-coordinates of the grid pointspoints_y(list[list], required): Column vector of y-coordinates of the grid pointsvalues(list[list], required): 2D array of data values on the gridxi(list[list], required): Points at which to interpolate data (n_points, 2)interpn_method(str, optional, default: “linear”): Interpolation methodbounds_error(bool, optional, default: true): If True, error on out-of-bounds pointsfill_value(float, optional, default: null): Value for out-of-bounds points if bounds_error is False
Returns (list[list]): 2D list (column vector) of interpolated values, or error message (str) if invalid.
Example 1: Linear interpolation at grid center
Inputs:
| points_x | points_y | values | xi | ||
|---|---|---|---|---|---|
| 0 | 0 | 0 | 1 | 0.5 | 0.5 |
| 1 | 1 | 1 | 2 |
Excel formula:
=INTERPN({0;1}, {0;1}, {0,1;1,2}, {0.5,0.5})
Expected output:
1
Example 2: Nearest-neighbor on 3x3 grid
Inputs:
| points_x | points_y | values | xi | interpn_method | |||
|---|---|---|---|---|---|---|---|
| 0 | 0 | 1 | 2 | 3 | 0.4 | 0.6 | nearest |
| 1 | 1 | 4 | 5 | 6 | |||
| 2 | 2 | 7 | 8 | 9 |
Excel formula:
=INTERPN({0;1;2}, {0;1;2}, {1,2,3;4,5,6;7,8,9}, {0.4,0.6}, "nearest")
Expected output:
2
Example 3: Out-of-bounds query with custom fill value
Inputs:
| points_x | points_y | values | xi | interpn_method | bounds_error | fill_value | ||
|---|---|---|---|---|---|---|---|---|
| 0 | 0 | 1 | 2 | 1.5 | 1.5 | linear | false | -999 |
| 1 | 1 | 3 | 4 |
Excel formula:
=INTERPN({0;1}, {0;1}, {1,2;3,4}, {1.5,1.5}, "linear", FALSE, -999)
Expected output:
-999
Example 4: Linear interpolation at multiple query points
Inputs:
| points_x | points_y | values | xi | interpn_method | bounds_error | |||
|---|---|---|---|---|---|---|---|---|
| 0 | 0 | 1 | 2 | 3 | 0.5 | 0.5 | linear | true |
| 1 | 1 | 2 | 3 | 4 | 1.5 | 1 | ||
| 2 | 2 | 3 | 4 | 5 | 2 | 1.5 | ||
| 3 | 4 | 5 | 6 |
Excel formula:
=INTERPN({0;1;2;3}, {0;1;2}, {1,2,3;2,3,4;3,4,5;4,5,6}, {0.5,0.5;1.5,1;2,1.5}, "linear", TRUE)
Expected output:
| Result |
|---|
| 2 |
| 3.5 |
| 4.5 |
Python Code
import math
import numpy as np
from scipy.interpolate import interpn as scipy_interpn
def interpn(points_x, points_y, values, xi, interpn_method='linear', bounds_error=True, fill_value=None):
"""
Multidimensional interpolation on regular grids (2D).
See: https://docs.scipy.org/doc/scipy/reference/generated/scipy.interpolate.interpn.html
This example function is provided as-is without any representation of accuracy.
Args:
points_x (list[list]): Column vector of x-coordinates of the grid points
points_y (list[list]): Column vector of y-coordinates of the grid points
values (list[list]): 2D array of data values on the grid
xi (list[list]): Points at which to interpolate data (n_points, 2)
interpn_method (str, optional): Interpolation method Valid options: Linear, Nearest, Spline 2D. Default is 'linear'.
bounds_error (bool, optional): If True, error on out-of-bounds points Default is True.
fill_value (float, optional): Value for out-of-bounds points if bounds_error is False Default is None.
Returns:
list[list]: 2D list (column vector) of interpolated values, or error message (str) if invalid.
"""
try:
def to2d(x):
return [[x]] if not isinstance(x, list) else x
def flatten(arr):
return [item for sublist in arr for item in sublist]
def validate_numeric_2d(arr, name):
if not isinstance(arr, list):
return f"Error: Invalid input: {name} must be a 2D list."
if not all(isinstance(row, list) for row in arr):
return f"Error: Invalid input: {name} must be a 2D list."
flat = flatten(arr)
if not flat:
return f"Error: Invalid input: {name} must not be empty."
for val in flat:
if not isinstance(val, (int, float)):
return f"Error: Invalid input: {name} must contain only numeric values."
if math.isnan(val) or math.isinf(val):
return f"Error: Invalid input: {name} must contain only finite values."
return None
# Normalize inputs
points_x = to2d(points_x)
points_y = to2d(points_y)
values = to2d(values)
xi = to2d(xi)
# Validate inputs
err = validate_numeric_2d(points_x, "points_x")
if err:
return err
err = validate_numeric_2d(points_y, "points_y")
if err:
return err
err = validate_numeric_2d(values, "values")
if err:
return err
err = validate_numeric_2d(xi, "xi")
if err:
return err
# Validate interpn_method
valid_methods = ['linear', 'nearest', 'splinef2d']
if not isinstance(interpn_method, str) or interpn_method not in valid_methods:
return f"Error: Invalid input: interpn_method must be one of {valid_methods}."
# Validate bounds_error
if not isinstance(bounds_error, bool):
return "Error: Invalid input: bounds_error must be a boolean."
# Validate and set fill_value
if fill_value is None:
fill_value = float('nan')
else:
if not isinstance(fill_value, (int, float)):
return "Error: Invalid input: fill_value must be a number."
fill_value = float(fill_value)
# Flatten grid coordinates
points_x_flat = flatten(points_x)
points_y_flat = flatten(points_y)
# Check grid monotonicity
if len(points_x_flat) < 2 or len(points_y_flat) < 2:
return "Error: Invalid input: grid coordinates must have at least 2 points."
for i in range(len(points_x_flat) - 1):
if points_x_flat[i] >= points_x_flat[i + 1]:
return "Error: Invalid input: points_x must be strictly increasing."
for i in range(len(points_y_flat) - 1):
if points_y_flat[i] >= points_y_flat[i + 1]:
return "Error: Invalid input: points_y must be strictly increasing."
# Validate values dimensions
if len(values) != len(points_x_flat):
return f"Error: Invalid input: values must have {len(points_x_flat)} rows to match points_x."
for row in values:
if len(row) != len(points_y_flat):
return f"Error: Invalid input: each row in values must have {len(points_y_flat)} columns to match points_y."
# Validate xi dimensions
for row in xi:
if len(row) != 2:
return "Error: Invalid input: each row in xi must have exactly 2 columns [x, y]."
# Convert to numpy arrays
try:
values_arr = np.array(values, dtype=float)
xi_arr = np.array(xi, dtype=float)
points = (np.array(points_x_flat, dtype=float), np.array(points_y_flat, dtype=float))
except Exception as exc:
return f"Error: Invalid input: unable to convert inputs to arrays: {exc}"
# Perform interpolation
try:
result = scipy_interpn(
points,
values_arr,
xi_arr,
method=interpn_method,
bounds_error=bounds_error,
fill_value=fill_value,
)
except Exception as exc:
return f"Error: scipy.interpolate.interpn error: {exc}"
# Convert result to 2D list (column vector)
if not isinstance(result, np.ndarray):
return "Error: scipy.interpolate.interpn error: unexpected result type."
result_list = [[float(val)] for val in result.flatten()]
# Validate result
for row in result_list:
for val in row:
if not isinstance(val, float):
return "Error: scipy.interpolate.interpn error: non-numeric result."
# Allow NaN if fill_value is NaN, but not inf
if math.isinf(val):
return "Error: scipy.interpolate.interpn error: result contains infinite values."
return result_list
except Exception as e:
return f"Error: {str(e)}"Online Calculator
Column vector of x-coordinates of the grid points
Column vector of y-coordinates of the grid points
2D array of data values on the grid
Points at which to interpolate data (n_points, 2)
Interpolation method
If True, error on out-of-bounds points
Value for out-of-bounds points if bounds_error is False