CLOUGH_TOCHER
This function wraps SciPy’s Clough-Tocher interpolator to estimate values on a smooth surface from scattered points in two dimensions. The method triangulates the input points and builds a continuously differentiable piecewise-cubic interpolant.
Given data points (x_i, y_i) with values z_i, the interpolant returns an estimate \hat{z}(x, y) for each query point while approximately minimizing surface curvature.
Excel Usage
=CLOUGH_TOCHER(points, values, xi, fill_value, tol, maxiter, rescale)
points(list[list], required): Input point coordinates as (n_points, 2).values(list[list], required): Function values at input points as (n_points, 1).xi(list[list], required): Query coordinates as (n_query, 2).fill_value(float, optional, default: 0): Value used outside the convex hull.tol(float, optional, default: 0.000001): Tolerance used in gradient estimation.maxiter(int, optional, default: 400): Maximum iterations for gradient estimation.rescale(bool, optional, default: false): Rescale points to unit cube before interpolation.
Returns (list[list]): Interpolated values as a 2D list (column vector), or an error message string.
Example 1: Interpolate center point on planar data
Inputs:
| points | values | xi | ||
|---|---|---|---|---|
| 0 | 0 | 0 | 0.5 | 0.5 |
| 1 | 0 | 1 | ||
| 0 | 1 | 1 | ||
| 1 | 1 | 2 |
Excel formula:
=CLOUGH_TOCHER({0,0;1,0;0,1;1,1}, {0;1;1;2}, {0.5,0.5})
Expected output:
1
Example 2: Interpolate two interior points
Inputs:
| points | values | xi | ||
|---|---|---|---|---|
| 0 | 0 | 0 | 0.25 | 0.75 |
| 1 | 0 | 1 | 0.8 | 0.1 |
| 0 | 1 | 1 | ||
| 1 | 1 | 2 |
Excel formula:
=CLOUGH_TOCHER({0,0;1,0;0,1;1,1}, {0;1;1;2}, {0.25,0.75;0.8,0.1})
Expected output:
| Result |
|---|
| 1 |
| 0.9 |
Example 3: Use fill value outside convex hull
Inputs:
| points | values | xi | fill_value | ||
|---|---|---|---|---|---|
| 0 | 0 | 0 | 2 | 2 | -999 |
| 1 | 0 | 1 | |||
| 0 | 1 | 1 | |||
| 1 | 1 | 2 |
Excel formula:
=CLOUGH_TOCHER({0,0;1,0;0,1;1,1}, {0;1;1;2}, {2,2}, -999)
Expected output:
-999
Example 4: Interpolate with rescaling enabled
Inputs:
| points | values | xi | rescale | ||
|---|---|---|---|---|---|
| 0 | 0 | 0 | 5 | 0.05 | true |
| 10 | 0 | 10 | |||
| 0 | 0.1 | 0.1 | |||
| 10 | 0.1 | 10.1 |
Excel formula:
=CLOUGH_TOCHER({0,0;10,0;0,0.1;10,0.1}, {0;10;0.1;10.1}, {5,0.05}, TRUE)
Expected output:
5.05
Python Code
import math
import numpy as np
from scipy.interpolate import CloughTocher2DInterpolator as scipy_CloughTocher2DInterpolator
def clough_tocher(points, values, xi, fill_value=0, tol=1e-06, maxiter=400, rescale=False):
"""
Piecewise cubic C1 interpolation for scattered 2D data.
See: https://docs.scipy.org/doc/scipy/reference/generated/scipy.interpolate.CloughTocher2DInterpolator.html
This example function is provided as-is without any representation of accuracy.
Args:
points (list[list]): Input point coordinates as (n_points, 2).
values (list[list]): Function values at input points as (n_points, 1).
xi (list[list]): Query coordinates as (n_query, 2).
fill_value (float, optional): Value used outside the convex hull. Default is 0.
tol (float, optional): Tolerance used in gradient estimation. Default is 1e-06.
maxiter (int, optional): Maximum iterations for gradient estimation. Default is 400.
rescale (bool, optional): Rescale points to unit cube before interpolation. Default is False.
Returns:
list[list]: Interpolated values as a 2D list (column vector), or an error message string.
"""
try:
def to2d(x):
return [[x]] if not isinstance(x, list) else x
def flatten_2d(arr):
out = []
for row in arr:
for val in row:
out.append(val)
return out
points = to2d(points)
values = to2d(values)
xi = to2d(xi)
if not isinstance(points, list) or not all(isinstance(row, list) for row in points):
return "Error: Invalid input: points must be a 2D list."
if not isinstance(values, list) or not all(isinstance(row, list) for row in values):
return "Error: Invalid input: values must be a 2D list."
if not isinstance(xi, list) or not all(isinstance(row, list) for row in xi):
return "Error: Invalid input: xi must be a 2D list."
if len(points) == 0 or len(values) == 0 or len(xi) == 0:
return "Error: Invalid input: points, values, and xi must not be empty."
if any(len(row) != 2 for row in points):
return "Error: Invalid input: points must have exactly 2 columns."
if any(len(row) != 2 for row in xi):
return "Error: Invalid input: xi must have exactly 2 columns."
values_flat = flatten_2d(values)
if len(values_flat) != len(points):
return "Error: Invalid input: values must contain one value per point."
for i, row in enumerate(points):
for j, val in enumerate(row):
if not isinstance(val, (int, float)):
return f"Error: Invalid input: points[{i}][{j}] must be numeric."
if math.isnan(val) or math.isinf(val):
return f"Error: Invalid input: points[{i}][{j}] must be finite."
for i, val in enumerate(values_flat):
if not isinstance(val, (int, float)):
return f"Error: Invalid input: values element {i} must be numeric."
if math.isnan(val) or math.isinf(val):
return f"Error: Invalid input: values element {i} must be finite."
for i, row in enumerate(xi):
for j, val in enumerate(row):
if not isinstance(val, (int, float)):
return f"Error: Invalid input: xi[{i}][{j}] must be numeric."
if math.isnan(val) or math.isinf(val):
return f"Error: Invalid input: xi[{i}][{j}] must be finite."
if not isinstance(fill_value, (int, float)):
return "Error: Invalid input: fill_value must be numeric."
if not isinstance(tol, (int, float)):
return "Error: Invalid input: tol must be numeric."
if not isinstance(maxiter, int):
return "Error: Invalid input: maxiter must be an integer."
if maxiter <= 0:
return "Error: Invalid input: maxiter must be positive."
if not isinstance(rescale, bool):
return "Error: Invalid input: rescale must be boolean."
points_arr = np.array(points, dtype=float)
values_arr = np.array(values_flat, dtype=float)
xi_arr = np.array(xi, dtype=float)
interp = scipy_CloughTocher2DInterpolator(
points_arr,
values_arr,
fill_value=float(fill_value),
tol=float(tol),
maxiter=maxiter,
rescale=rescale
)
result = interp(xi_arr)
result_arr = np.asarray(result, dtype=float).reshape(-1)
return [[float(v)] for v in result_arr]
except Exception as e:
return f"Error: {str(e)}"Online Calculator
Input point coordinates as (n_points, 2).
Function values at input points as (n_points, 1).
Query coordinates as (n_query, 2).
Value used outside the convex hull.
Tolerance used in gradient estimation.
Maximum iterations for gradient estimation.
Rescale points to unit cube before interpolation.