AKIMA_INTERP
Overview
The AKIMA_INTERP function performs one-dimensional interpolation using the Akima spline method, producing “visually pleasing” smooth curves that pass through given data points. This technique is particularly useful when you need to estimate intermediate values between measured data points, such as filling gaps in time-series data or creating smooth curves through experimental measurements.
The Akima interpolation method, introduced by Hiroshi Akima in 1970, constructs a continuously differentiable (C1 smooth) piecewise cubic polynomial. Unlike traditional cubic splines, Akima’s approach uses a locally-weighted average of neighboring slopes, which helps reduce unwanted oscillations near outliers or sharp changes in the data.
The algorithm computes derivatives at each data point using weighted averages of the slopes between adjacent intervals. For each point x_i, the derivative d_i is calculated as:
d_i = \frac{w_1 \cdot \delta_{i-1} + w_2 \cdot \delta_i}{w_1 + w_2}
where \delta_i = \frac{y_{i+1} - y_i}{x_{i+1} - x_i} represents the slope of the interval [x_i, x_{i+1}), and the weights are defined as w_1 = |\delta_{i+1} - \delta_i| and w_2 = |\delta_{i-1} - \delta_{i-2}|.
This implementation uses the Akima1DInterpolator class from SciPy, a fundamental library for scientific computing in Python. The function requires at least two data points and expects unique, monotonically increasing x-values. For related interpolation methods, see SciPy’s PchipInterpolator for monotonic interpolation or CubicSpline for traditional spline interpolation.
This example function is provided as-is without any representation of accuracy.
Excel Usage
=AKIMA_INTERP(x, y, x_new)
x(list[list], required): X-coordinates of the data points (column vector)y(list[list], required): Y-coordinates of the data points (column vector)x_new(list[list], required): X-coordinates at which to evaluate the interpolated values
Returns (list[list]): A 2D list of interpolated values, or an error message (str) if invalid.
Examples
Example 1: Demo case 1
Inputs:
| x | y | x_new |
|---|---|---|
| 0 | 0 | 1.5 |
| 1 | 1 | |
| 2 | 0 | |
| 3 | 1 |
Excel formula:
=AKIMA_INTERP({0;1;2;3}, {0;1;0;1}, 1.5)
Expected output:
| Result |
|---|
| 0.5 |
Example 2: Demo case 2
Inputs:
| x | y | x_new |
|---|---|---|
| 0 | 0 | 0.5 |
| 1 | 2 | 1.5 |
| 2 | 1 | 2.5 |
| 3 | 3 | |
| 4 | 2 |
Excel formula:
=AKIMA_INTERP({0;1;2;3;4}, {0;2;1;3;2}, {0.5;1.5;2.5})
Expected output:
| Result |
|---|
| 1.375 |
| 1.5 |
| 2 |
Example 3: Demo case 3
Inputs:
| x | y | x_new |
|---|---|---|
| 0 | 0 | 1.5 |
| 1 | 1 | 2.5 |
| 2 | 4 | |
| 3 | 9 | |
| 4 | 16 |
Excel formula:
=AKIMA_INTERP({0;1;2;3;4}, {0;1;4;9;16}, {1.5;2.5})
Expected output:
| Result |
|---|
| 2.25 |
| 6.25 |
Example 4: Demo case 4
Inputs:
| x | y | x_new |
|---|---|---|
| 0 | 0 | 0.3927 |
| 0.7854 | 0.7071 | 1.1781 |
| 1.5708 | 1 | |
| 2.3562 | 0.7071 | |
| 3.1416 | 0 |
Excel formula:
=AKIMA_INTERP({0;0.7854;1.5708;2.3562;3.1416}, {0;0.7071;1;0.7071;0}, {0.3927;1.1781})
Expected output:
| Result |
|---|
| 0.4009 |
| 0.9205 |
Python Code
import math
from scipy.interpolate import Akima1DInterpolator as scipy_Akima1DInterpolator
def akima_interp(x, y, x_new):
"""
Akima 1D interpolation.
See: https://docs.scipy.org/doc/scipy/reference/generated/scipy.interpolate.Akima1DInterpolator.html
This example function is provided as-is without any representation of accuracy.
Args:
x (list[list]): X-coordinates of the data points (column vector)
y (list[list]): Y-coordinates of the data points (column vector)
x_new (list[list]): X-coordinates at which to evaluate the interpolated values
Returns:
list[list]: A 2D list of interpolated values, or an error message (str) if invalid.
"""
def to2d(val):
"""Convert scalar or list to 2D list format."""
return [[val]] if not isinstance(val, list) else val
def flatten(arr):
"""Flatten a 2D list to 1D."""
return [item for sublist in arr for item in sublist]
def validate_numeric_array(arr, name):
"""Validate that array contains only finite numeric values."""
if not isinstance(arr, list):
return f"Invalid input: {name} must be a 2D list."
for row in arr:
if not isinstance(row, list):
return f"Invalid input: {name} must be a 2D list."
for val in row:
if not isinstance(val, (int, float)):
return f"Invalid input: {name} must contain only numeric values."
if math.isnan(val) or math.isinf(val):
return f"Invalid input: {name} must contain only finite values."
return None
try:
# Normalize inputs to 2D lists
x = to2d(x)
y = to2d(y)
x_new = to2d(x_new)
# Validate inputs
error = validate_numeric_array(x, "x")
if error:
return error
error = validate_numeric_array(y, "y")
if error:
return error
error = validate_numeric_array(x_new, "x_new")
if error:
return error
# Flatten arrays
x_flat = flatten(x)
y_flat = flatten(y)
x_new_flat = flatten(x_new)
# Check that x and y have the same length
if len(x_flat) != len(y_flat):
return "Invalid input: x and y must have the same length."
# Check minimum number of points
if len(x_flat) < 2:
return "Invalid input: at least 2 data points are required."
# Check for empty arrays before processing
if len(x_flat) == 0 or len(y_flat) == 0:
return "Invalid input: x and y cannot be empty."
# Sort by x
combined = sorted(zip(x_flat, y_flat), key=lambda pair: pair[0])
x_sorted, y_sorted = zip(*combined)
x_sorted = list(x_sorted)
y_sorted = list(y_sorted)
# Check for duplicates
for i in range(len(x_sorted) - 1):
if x_sorted[i] == x_sorted[i+1]:
return "Invalid input: x values must be unique."
# Create interpolator and evaluate
interp = scipy_Akima1DInterpolator(x_sorted, y_sorted)
result = interp(x_new_flat)
# Convert result to 2D list
output = [[float(val)] for val in result]
# Validate output
for row in output:
for val in row:
if math.isnan(val) or math.isinf(val):
return "Interpolation error: result contains non-finite values."
return output
except ValueError as e:
return f"Invalid input: {e}"
except Exception as e:
return f"scipy.interpolate.Akima1DInterpolator error: {e}"