no-std interpn

N-dimensional interpolation/extrapolation methods, no-std and no-alloc compatible

5 releases(3 breaking)

 0.4.2 Mar 12, 2024 Mar 6, 2024 Dec 18, 2023 Dec 7, 2023 Nov 22, 2023

#240 in Algorithms

Used in flaw

MIT/Apache

125KB
1.5K SLoC

InterpN

N-dimensional interpolation/extrapolation methods, no-std and no-alloc compatible, prioritizing correctness, performance, and compatiblity with memory-constrained environments.

Performance Scalings

Note that for a self-consistent multidimensional linear interpolation, there are 2^ndims grid values that contribute to each observation point, and as such, that is the theoretical floor for performance scaling. That said, depending on the implementation, the constant term can vary by more than an order of magnitude.

Cubic interpolations require two more degrees of freedom per dimension, which results in a minimal runtime scaling of 4^ndims. Similar to the linear methods, depending on implementation, the constant term can vary by orders of magnitude, as can the RAM usage.

Method RAM Interp. Cost (Best Case) Interp. Cost (Worst Case) Extrap. Cost (Worst Case)
multilinear::regular O(ndims) O(2^ndims * ndims) O(2^ndims * ndims) O(2^ndims + ndims^2)
multilinear::rectilinear O(ndims) O(2^ndims * ndims) O(ndims * (2^ndims + log2(gridsize))) O(ndims * (2^ndims + ndims + log2(gridsize)))
multicubic::regular O(ndims) O(4^ndims) O(4^ndims) O(4^ndims)
multicubic::rectilinear O(ndims) O(4^ndims) O(4^ndims) + ndims * log2(gridsize) O(4^ndims) + ndims * log2(gridsize)

Example: Multilinear and Multicubic w/ Regular Grid

``````use interpn::{multilinear, multicubic};

// Define a grid
let x = [1.0_f64, 2.0, 3.0, 4.0];
let y = [0.0_f64, 1.0, 2.0, 3.0];

// Grid input for rectilinear method
let grids = &[&x[..], &y[..]];

// Grid input for regular grid method
let dims = [x.len(), y.len()];
let starts = [x[0], y[0]];
let steps = [x[1] - x[0], y[1] - y[0]];

// Values at grid points
let z = [2.0; 16];

// Observation points to interpolate/extrapolate
let xobs = [0.0_f64, 5.0];
let yobs = [-1.0, 3.0];
let obs = [&xobs[..], &yobs[..]];

// Storage for output
let mut out = [0.0; 2];

// Do interpolation
multilinear::regular::interpn(&dims, &starts, &steps, &z, &obs, &mut out);
multicubic::regular::interpn(&dims, &starts, &steps, &z, false, &obs, &mut out);
``````

Example: Multilinear and Multicubic w/ Rectilinear Grid

``````use interpn::{multilinear, multicubic};

// Define a grid
let x = [1.0_f64, 2.0, 3.0, 4.0];
let y = [0.0_f64, 1.0, 2.0, 3.0];

// Grid input for rectilinear method
let grids = &[&x[..], &y[..]];

// Values at grid points
let z = [2.0; 16];

// Points to interpolate/extrapolate
let xobs = [0.0_f64, 5.0];
let yobs = [-1.0, 3.0];
let obs = [&xobs[..], &yobs[..]];

// Storage for output
let mut out = [0.0; 2];

// Do interpolation
multilinear::rectilinear::interpn(grids, &z, &obs, &mut out).unwrap();
multicubic::rectilinear::interpn(grids, &z, false, &obs, &mut out).unwrap();
``````

• Recursive multilinear methods (for better extrapolation speed and timing determinism)
• Methods for unstructured triangular and tetrahedral meshes