Skip to content

Commit 8400895

Browse files
committed
documentation cleanup
1 parent 66674ee commit 8400895

File tree

3 files changed

+164
-107
lines changed

3 files changed

+164
-107
lines changed

Cargo.toml

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
[package]
22
name = "ninterp"
3-
version = "0.2.4"
3+
version = "0.2.5"
44
edition = "2021"
55
description = "Numerical interpolation in N-dimensions over a regular, sorted, nonrepeating grid"
66
repository = "https://github.com/NREL/ninterp"

README.md

+28-3
Original file line numberDiff line numberDiff line change
@@ -6,11 +6,36 @@ The `ninterp` crate provides [multivariate interpolation](https://en.wikipedia.o
66

77
There are hard-coded interpolators for lower dimensionalities (up to N = 3) for better runtime performance.
88

9-
All interpolation is handled through instances of the [Interpolator](https://docs.rs/ninterp/latest/ninterp/enum.Interpolator.html) enum, with the selected tuple variant containing relevant data. Interpolation is executed by calling [Interpolator::interpolate](https://docs.rs/ninterp/latest/ninterp/enum.Interpolator.html#method.interpolate).
10-
119
## Feature Flags
1210
- `serde`: support for serde
1311

1412
## Getting Started
13+
A prelude module has been defined: `use ninterp::prelude::*`.
14+
This exposes the types necessary for usage: `Interpolator`, `Strategy`, `Extrapolate`, and the trait `InterpMethods`.
15+
16+
All interpolation is handled through instances of the [`Interpolator`](https://docs.rs/ninterp/latest/ninterp/enum.Interpolator.html) enum.
17+
18+
Interpolation is executed by calling [`Interpolator::interpolate`](https://docs.rs/ninterp/latest/ninterp/enum.Interpolator.html#method.interpolate).
19+
The length of the supplied point slice must be equal to the interpolator dimensionality.
20+
The interpolator dimensionality can be retrieved by calling [`Interpolator::ndim`](https://docs.rs/ninterp/latest/ninterp/enum.Interpolator.html#method.ndim).
21+
22+
### Note
23+
For interpolators of dimensionality N ≥ 1:
24+
- Instantiation is done via the Interpolator enum's `new_*` methods (`new_1d`, `new_2d`, `new_3d`, `new_nd`).
25+
These methods run a validation step that catches any potential errors early, preventing runtime panics.
26+
- To set or get field values, use the corresponding named methods (`x`, `set_x`, etc.).
27+
- An interpolation [`Strategy`](https://docs.rs/ninterp/latest/ninterp/enum.Strategy.html) (e.g. linear, left-nearest, etc.) must be specified.
28+
Not all interpolation strategies are implemented for every dimensionality.
29+
`Strategy::Linear` is implemented for all dimensionalities.
30+
- An [`Extrapolate`](https://docs.rs/ninterp/latest/ninterp/enum.Extrapolate.html) setting must be specified.
31+
This controls what happens when a point is beyond the range of supplied coordinates.
32+
If you are unsure which variant to choose, `Extrapolate::Error` is likely what you want.
33+
34+
For 0-D (constant-value) interpolators, instantiate directly, e.g. `Interpolator::Interp0D(0.5)`
1535

16-
See the [Interpolator](https://docs.rs/ninterp/latest/ninterp/enum.Interpolator.html) enum documentation for examples and notes on usage.
36+
### Examples
37+
- [`Interpolator::Interp0D`](https://docs.rs/ninterp/latest/ninterp/enum.Interpolator.html#variant.Interp0D)
38+
- [`Interpolator::new_1d`](https://docs.rs/ninterp/latest/ninterp/enum.Interpolator.html#method.new_1d)
39+
- [`Interpolator::new_2d`](https://docs.rs/ninterp/latest/ninterp/enum.Interpolator.html#method.new_2d)
40+
- [`Interpolator::new_3d`](https://docs.rs/ninterp/latest/ninterp/enum.Interpolator.html#method.new_3d)
41+
- [`Interpolator::new_nd`](https://docs.rs/ninterp/latest/ninterp/enum.Interpolator.html#method.new_nd)

src/lib.rs

+135-103
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,35 @@
1515
//! - `serde`: support for [`serde`](https://crates.io/crates/serde)
1616
//!
1717
//! # Getting Started
18-
//! See the [`Interpolator`] enum documentation for examples and notes on usage.
18+
//! A prelude module has been defined: `use ninterp::prelude::*`.
19+
//! This exposes the types necessary for usage: [`Interpolator`], [`Strategy`], [`Extrapolate`], and the trait [`InterpMethods`].
20+
//!
21+
//! All interpolation is handled through instances of the [`Interpolator`] enum.
22+
//!
23+
//! Interpolation is executed by calling [`Interpolator::interpolate`].
24+
//! The length of the supplied point slice must be equal to the interpolator dimensionality.
25+
//! The interpolator dimensionality can be retrieved by calling [`Interpolator::ndim`].
26+
//!
27+
//! ## Note
28+
//! For interpolators of dimensionality N ≥ 1:
29+
//! - Instantiation is done via the Interpolator enum's `new_*` methods (`new_1d`, `new_2d`, `new_3d`, `new_nd`).
30+
//! These methods run a validation step that catches any potential errors early, preventing runtime panics.
31+
//! - To set or get field values, use the corresponding named methods (`x`, `set_x`, etc.).
32+
//! - An interpolation [`Strategy`] (e.g. linear, left-nearest, etc.) must be specified.
33+
//! Not all interpolation strategies are implemented for every dimensionality.
34+
//! [`Strategy::Linear`] is implemented for all dimensionalities.
35+
//! - An [`Extrapolate`] setting must be specified.
36+
//! This controls what happens when a point is beyond the range of supplied coordinates.
37+
//! If you are unsure which variant to choose, [`Extrapolate::Error`] is likely what you want.
38+
//!
39+
//! For 0-D (constant-value) interpolators, instantiate directly, e.g. `Interpolator::Interp0D(0.5)`
40+
//!
41+
//! ## Examples
42+
//! - [`Interpolator::Interp0D`]
43+
//! - [`Interpolator::new_1d`]
44+
//! - [`Interpolator::new_2d`]
45+
//! - [`Interpolator::new_3d`]
46+
//! - [`Interpolator::new_nd`]
1947
//!
2048
2149
pub mod prelude {
@@ -68,34 +96,15 @@ fn find_nearest_index(arr: &[f64], target: f64) -> usize {
6896
}
6997

7098
/// An interpolator, with different functionality depending on variant.
71-
///
72-
/// Interpolation is executed by calling [`Interpolator::interpolate`].
73-
/// The length of the supplied point slice must be equal to the intepolator dimensionality.
74-
/// The interpolator dimensionality can be retrieved by calling [`Interpolator::ndim`].
75-
///
76-
/// # Note
77-
/// For interpolators of dimensionality N ≥ 1:
78-
/// - By design, instantiation must be done via the Interpolator enum's `new_*` methods (`new_1d`, `new_2d`, `new_3d`, `new_nd`).
79-
/// These run a validation step that catches any potential errors early.
80-
/// - To set or get field values, use the corresponding named methods (`x`, `set_x`, etc.).
81-
/// - An interpolation [`Strategy`] (e.g. linear, left-nearest, etc.) must be specified.
82-
/// Not all interpolation strategies are implemented for every dimensionality.
83-
/// [`Strategy::Linear`] is implemented for all dimensionalities.
84-
/// - An [`Extrapolate`] setting must be specified.
85-
/// This controls what happens when a point is beyond the range of supplied coordinates.
86-
/// If you are unsure which variant to choose, [`Extrapolate::Error`] is likely what you want.
87-
///
88-
/// For 0D (constant-value) interpolators, instantiate directly, e.g. `Interpolator::Interp0D(0.5)`
89-
///
9099
#[allow(private_interfaces)]
91100
#[derive(Clone, Debug, PartialEq)]
92101
#[cfg_attr(feature = "serde", derive(Deserialize, Serialize))]
93102
pub enum Interpolator {
94-
/// Useful for returning a constant-value result from an interpolator.
103+
/// Returns a constant value.
95104
///
96105
/// # Example:
97106
/// ```
98-
/// use ninterp::*;
107+
/// use ninterp::prelude::*;
99108
/// // 0-D is unique, the value is directly provided in the variant
100109
/// let const_value = 0.5;
101110
/// let interp = Interpolator::Interp0D(const_value);
@@ -106,37 +115,82 @@ pub enum Interpolator {
106115
/// ```
107116
Interp0D(f64),
108117
/// Interpolates in one dimension.
118+
///
119+
/// See [`Interpolator::new_1d`] documentation for example usage.
120+
Interp1D(Interp1D),
121+
/// Interpolates in two dimensions.
122+
///
123+
/// See [`Interpolator::new_2d`] documentation for example usage.
124+
Interp2D(Interp2D),
125+
/// Interpolates in three dimensions.
126+
///
127+
/// See [`Interpolator::new_3d`] documentation for example usage.
128+
Interp3D(Interp3D),
129+
/// Interpolates with any dimensionality.
130+
///
131+
/// See [`Interpolator::new_nd`] documentation for example usage.
132+
InterpND(InterpND),
133+
}
134+
135+
impl Interpolator {
136+
#[deprecated(note="instantiate directly via `Interpolator::Interp0D(value)` instead")]
137+
pub fn new_0d(
138+
value: f64,
139+
) -> Result<Self, ValidationError> {
140+
Ok(Self::Interp0D(value))
141+
}
142+
143+
/// Instantiate one-dimensional interpolator.
109144
///
110145
/// Applicable interpolation strategies:
111146
/// - [`Strategy::Linear`]
112-
/// - [`Strategy::LeftNearest`]
113-
/// - [`Strategy::RightNearest`]
114-
/// - [`Strategy::Nearest`]
115147
///
116148
/// Applicable extrapolation strategies:
117-
/// - [`Extrapolate::Enable`]
118149
/// - [`Extrapolate::Clamp`]
119150
/// - [`Extrapolate::Error`]
120151
///
121-
/// # Example (linear, using [`Extrapolate::Enable`]):
152+
/// # Example (using [`Extrapolate::Clamp`]):
122153
/// ```
123154
/// use ninterp::prelude::*;
124-
/// // f(x) = 0.2 * x + 0.2
125-
/// let interp = Interpolator::new_1d(
155+
/// // f(x, y) = 0.2 * x + 0.4 * y
156+
/// let interp = Interpolator::new_2d(
126157
/// // x
127158
/// vec![0., 1., 2.], // x0, x1, x2
128-
/// // f(x)
129-
/// vec![0.2, 0.4, 0.6], // f(x0), f(x1), f(x2)
130-
/// Strategy::Linear, // linear interpolation
131-
/// Extrapolate::Enable, // linearly extrapolate when point is out of bounds
159+
/// // y
160+
/// vec![0., 1., 2.], // y0, y1, y2
161+
/// // f(x, y)
162+
/// vec![
163+
/// vec![0.0, 0.4, 0.8], // f(x0, y0), f(x0, y1), f(x0, y2)
164+
/// vec![0.2, 0.6, 1.0], // f(x1, y0), f(x1, y1), f(x1, y2)
165+
/// vec![0.4, 0.8, 1.2], // f(x2, y0), f(x2, y1), f(x2, y2)
166+
/// ],
167+
/// Strategy::Linear,
168+
/// Extrapolate::Clamp, // restrict point within grid bounds
132169
/// )
133-
/// .unwrap(); // handle data validation results
134-
/// assert_eq!(interp.interpolate(&[1.5]).unwrap(), 0.5);
135-
/// assert_eq!(interp.interpolate(&[-1.]).unwrap(), 0.); // extrapolation below grid
136-
/// assert_eq!(interp.interpolate(&[2.2]).unwrap(), 0.64); // extrapolation above grid
170+
/// .unwrap();
171+
/// assert_eq!(interp.interpolate(&[1.5, 1.5]).unwrap(), 0.9);
172+
/// assert_eq!(
173+
/// interp.interpolate(&[-1., 2.5]).unwrap(),
174+
/// interp.interpolate(&[0., 2.]).unwrap()
175+
/// ); // point is restricted to within grid bounds
137176
/// ```
138-
Interp1D(Interp1D),
139-
/// Interpolates in two dimensions.
177+
pub fn new_1d(
178+
x: Vec<f64>,
179+
f_x: Vec<f64>,
180+
strategy: Strategy,
181+
extrapolate: Extrapolate,
182+
) -> Result<Self, ValidationError> {
183+
let interp = Interp1D {
184+
x,
185+
f_x,
186+
strategy,
187+
extrapolate,
188+
};
189+
interp.validate()?;
190+
Ok(Self::Interp1D(interp))
191+
}
192+
193+
/// Instantiate two-dimensional interpolator.
140194
///
141195
/// Applicable interpolation strategies:
142196
/// - [`Strategy::Linear`]
@@ -170,8 +224,25 @@ pub enum Interpolator {
170224
/// interp.interpolate(&[0., 2.]).unwrap()
171225
/// ); // point is restricted to within grid bounds
172226
/// ```
173-
Interp2D(Interp2D),
174-
/// Interpolates in three dimensions.
227+
pub fn new_2d(
228+
x: Vec<f64>,
229+
y: Vec<f64>,
230+
f_xy: Vec<Vec<f64>>,
231+
strategy: Strategy,
232+
extrapolate: Extrapolate,
233+
) -> Result<Self, ValidationError> {
234+
let interp = Interp2D {
235+
x,
236+
y,
237+
f_xy,
238+
strategy,
239+
extrapolate,
240+
};
241+
interp.validate()?;
242+
Ok(Self::Interp2D(interp))
243+
}
244+
245+
/// Instantiate three-dimensional interpolator.
175246
///
176247
/// Applicable interpolation strategies:
177248
/// - [`Strategy::Linear`]
@@ -213,8 +284,27 @@ pub enum Interpolator {
213284
/// ninterp::error::InterpolationError::ExtrapolationError(_)
214285
/// ));
215286
/// ```
216-
Interp3D(Interp3D),
217-
/// Interpolates with any dimensionality.
287+
pub fn new_3d(
288+
x: Vec<f64>,
289+
y: Vec<f64>,
290+
z: Vec<f64>,
291+
f_xyz: Vec<Vec<Vec<f64>>>,
292+
strategy: Strategy,
293+
extrapolate: Extrapolate,
294+
) -> Result<Self, ValidationError> {
295+
let interp = Interp3D {
296+
x,
297+
y,
298+
z,
299+
f_xyz,
300+
strategy,
301+
extrapolate,
302+
};
303+
interp.validate()?;
304+
Ok(Self::Interp3D(interp))
305+
}
306+
307+
/// Instantiate N-dimensional (any dimensionality) interpolator.
218308
///
219309
/// Applicable interpolation strategies:
220310
/// - [`Strategy::Linear`]
@@ -257,64 +347,6 @@ pub enum Interpolator {
257347
/// ninterp::error::InterpolationError::ExtrapolationError(_)
258348
/// ));
259349
/// ```
260-
InterpND(InterpND),
261-
}
262-
263-
impl Interpolator {
264-
pub fn new_1d(
265-
x: Vec<f64>,
266-
f_x: Vec<f64>,
267-
strategy: Strategy,
268-
extrapolate: Extrapolate,
269-
) -> Result<Self, ValidationError> {
270-
let interp = Interp1D {
271-
x,
272-
f_x,
273-
strategy,
274-
extrapolate,
275-
};
276-
interp.validate()?;
277-
Ok(Self::Interp1D(interp))
278-
}
279-
280-
pub fn new_2d(
281-
x: Vec<f64>,
282-
y: Vec<f64>,
283-
f_xy: Vec<Vec<f64>>,
284-
strategy: Strategy,
285-
extrapolate: Extrapolate,
286-
) -> Result<Self, ValidationError> {
287-
let interp = Interp2D {
288-
x,
289-
y,
290-
f_xy,
291-
strategy,
292-
extrapolate,
293-
};
294-
interp.validate()?;
295-
Ok(Self::Interp2D(interp))
296-
}
297-
298-
pub fn new_3d(
299-
x: Vec<f64>,
300-
y: Vec<f64>,
301-
z: Vec<f64>,
302-
f_xyz: Vec<Vec<Vec<f64>>>,
303-
strategy: Strategy,
304-
extrapolate: Extrapolate,
305-
) -> Result<Self, ValidationError> {
306-
let interp = Interp3D {
307-
x,
308-
y,
309-
z,
310-
f_xyz,
311-
strategy,
312-
extrapolate,
313-
};
314-
interp.validate()?;
315-
Ok(Self::Interp3D(interp))
316-
}
317-
318350
pub fn new_nd(
319351
grid: Vec<Vec<f64>>,
320352
values: ndarray::ArrayD<f64>,
@@ -331,7 +363,7 @@ impl Interpolator {
331363
Ok(Self::InterpND(interp))
332364
}
333365

334-
/// Ensure supplied point is valid for the given interpolator
366+
/// Ensure supplied point is valid for the given interpolator.
335367
fn validate_point(&self, point: &[f64]) -> Result<(), InterpolationError> {
336368
let n = self.ndim();
337369
// Check supplied point dimensionality
@@ -347,7 +379,7 @@ impl Interpolator {
347379
Ok(())
348380
}
349381

350-
/// Interpolator dimensionality
382+
/// Retrieve interpolator dimensionality.
351383
pub fn ndim(&self) -> usize {
352384
match self {
353385
Self::Interp0D(_) => 0,

0 commit comments

Comments
 (0)