19 releases (6 breaking)
new 0.7.0 | May 2, 2025 |
---|---|
0.6.3 | Mar 24, 2025 |
0.1.0 | Nov 27, 2024 |
#220 in Math
1,439 downloads per month
Used in 4 crates
(2 directly)
150KB
3.5K
SLoC
ninterp
The ninterp
crate provides multivariate interpolation over rectilinear grids of any dimensionality.
There are hard-coded interpolators for lower dimensionalities (up to N = 3) for better runtime performance. All interpolators work with both owned and borrowed arrays (array views) of various types.
A variety of interpolation strategies are implemented and exposed in the prelude
module.
Custom interpolation strategies can be defined in downstream crates.
cargo add ninterp
Cargo Features
serde
: support forserde
1.xcargo add ninterp --features serde
Examples
See examples in new
method documentation:
Also see the examples
directory for advanced examples:
-
Swapping strategies at runtime:
dynamic_strategy.rs
- Using strategy enums (
strategy::enums::Strategy1DEnum
/etc.)- Compatible with
serde
- Incompatible with custom strategies
- Compatible with
- Using
Box<dyn Strategy1D>
/etc. (dynamic dispatch)- Incompatible with
serde
- Compatible with custom strategies
- Runtime cost
- Incompatible with
- Using strategy enums (
-
Swapping interpolators at runtime:
dynamic_interpolator.rs
- Using
InterpolatorEnum
- Compatible with
serde
- Incompatible with custom strategies
- Compatible with
- Using
Box<dyn Interpolator>
(dynamic dispatch)- Incompatible with
serde
- Compatible with custom strategies
- Runtime cost
- Incompatible with
- Using
-
Defining custom strategies:
custom_strategy.rs
-
Using transmutable (transparent) types, such as
uom::si::Quantity
:uom.rs
Overview
A prelude
module has been defined:
use ninterp::prelude::*;
This exposes all strategies and a variety of interpolators:
There is also a constant-value 'interpolator':
Interp0D
.
This is useful when working with an InterpolatorEnum
or Box<dyn Interpolator>
Instantiation is done by calling an interpolator's new
method.
For dimensionalities N ≥ 1, this executes a validation step, preventing runtime panics.
After editing interpolator data,
call the InterpData's validate
method
or Interpolator::validate
to rerun these checks.
To change the extrapolation setting, call set_extrapolate
.
To change the interpolation strategy,
supply a Strategy1DEnum
/etc. or Box<dyn Strategy1D>
/etc. upon instantiation,
and call set_strategy
.
Strategies
An interpolation strategy (e.g.
Linear
,
Nearest
,
LeftNearest
,
RightNearest
)
must be specified.
Not all interpolation strategies are implemented for every dimensionality.
Linear
and Nearest
are implemented for all dimensionalities.
Custom strategies can be defined. See
examples/custom_strategy.rs
for an example.
Extrapolation
An Extrapolate
setting must be provided in the new
method.
This controls what happens when a point is beyond the range of supplied coordinates.
The following settings are applicable for all interpolators:
Extrapolate::Fill(T)
Extrapolate::Clamp
Extrapolate::Wrap
Extrapolate::Error
Extrapolate::Enable
is valid for Linear
for all dimensionalities.
If you are unsure which variant to choose, Extrapolate::Error
is likely what you want.
Interpolation
Interpolation is executed by calling Interpolator::interpolate
.
The length of the interpolant point slice must be equal to the interpolator dimensionality.
The interpolator dimensionality can be retrieved by calling Interpolator::ndim
.
Using Owned and Borrowed (Viewed) Data
All interpolators work with both owned and borrowed data.
This is accomplished by the generic D
, which has a bound on the
ndarray::Data
trait.
Type aliases are provided in the
prelude
for convenience, e.g. for 1-D:
Interp1DOwned
- Data is owned by the interpolator object
- Useful for struct fields
use ndarray::prelude::*; use ninterp::prelude::*; let interp: Interp1DOwned<f64, _> = Interp1D::new( array![0.0, 1.0, 2.0, 3.0], array![0.0, 1.0, 4.0, 9.0], strategy::Linear, Extrapolate::Error, ) .unwrap();
Interp1DViewed
- Data is borrowed by the interpolator object
- Use when interpolator data should be owned by another object
use ndarray::prelude::*; use ninterp::prelude::*; let x = array![0.0, 1.0, 2.0, 3.0]; let f_x = array![0.0, 1.0, 4.0, 9.0]; let interp: Interp1DViewed<&f64, _> = Interp1D::new( x.view(), f_x.view(), strategy::Linear, Extrapolate::Error, ) .unwrap();
Typically, the compiler can determine concrete types using the arguments provided to new
methods.
Examples throughout this crate have type annotions for clarity purposes; they are often unnecessary.
Dependencies
~2–2.7MB
~54K SLoC