Skip to content

Commit

Permalink
improve ExtrapolationError messages
Browse files Browse the repository at this point in the history
  • Loading branch information
kylecarow committed Jan 24, 2025
1 parent bc4e5dd commit 70df920
Show file tree
Hide file tree
Showing 2 changed files with 72 additions and 64 deletions.
88 changes: 48 additions & 40 deletions src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -22,15 +22,15 @@ mod error;
mod n;
mod one;
mod three;
mod two;
mod traits;
mod two;

pub use error::*;
pub(crate) use n::*;
pub(crate) use one::*;
pub(crate) use three::*;
pub(crate) use two::*;
pub use traits::*;
pub(crate) use two::*;

#[cfg(feature = "serde")]
use serde::{Deserialize, Serialize};
Expand Down Expand Up @@ -80,9 +80,9 @@ fn find_nearest_index(arr: &[f64], target: f64) -> usize {
/// - An [`Extrapolate`] setting must be specified.
/// This controls what happens when a point is beyond the range of supplied coordinates.
/// If you are unsure which variant to choose, [`Extrapolate::Error`] is likely what you want.
///
///
/// For 0D (constant-value) interpolators, instantiate directly, e.g. `Interpolator::Interp0D(0.5)`
///
///
#[derive(Clone, Debug, PartialEq)]
#[cfg_attr(feature = "serde", derive(Deserialize, Serialize))]
pub enum Interpolator {
Expand Down Expand Up @@ -619,8 +619,8 @@ impl InterpMethods for Interpolator {
Extrapolate::Error => {
if !(interp.x[0] <= point[0] && &point[0] <= interp.x.last().unwrap()) {
return Err(InterpolationError::ExtrapolationError(format!(
"point = {point:?}, grid = {:?}",
interp.x
"\n point[0] = {:?} is out of bounds for x-grid = {:?}",
point[0], interp.x
)));
}
}
Expand All @@ -638,17 +638,21 @@ impl InterpMethods for Interpolator {
return interp.interpolate(clamped_point);
}
Extrapolate::Error => {
if !(interp.x[0] <= point[0] && &point[0] <= interp.x.last().unwrap()) {
return Err(InterpolationError::ExtrapolationError(format!(
"point = {point:?}, x grid = {:?}",
interp.x
)));
let grid = [&interp.x, &interp.y];
let grid_names = ["x", "y"];
let mut errors = Vec::new();
for dim in 0..2 {
if !(grid[dim][0] <= point[dim]
&& &point[dim] <= grid[dim].last().unwrap())
{
errors.push(format!(
"\n point[{dim}] = {:?} is out of bounds for {}-grid = {:?}",
point[dim], grid_names[dim], grid[dim],
));
}
}
if !(interp.y[0] <= point[1] && &point[1] <= interp.y.last().unwrap()) {
return Err(InterpolationError::ExtrapolationError(format!(
"point = {point:?}, y grid = {:?}",
interp.y
)));
if !errors.is_empty() {
return Err(InterpolationError::ExtrapolationError(errors.join("")));
}
}
_ => {}
Expand All @@ -666,23 +670,21 @@ impl InterpMethods for Interpolator {
return interp.interpolate(clamped_point);
}
Extrapolate::Error => {
if !(interp.x[0] <= point[0] && &point[0] <= interp.x.last().unwrap()) {
return Err(InterpolationError::ExtrapolationError(format!(
"point = {point:?}, x grid = {:?}",
interp.x
)));
let grid = [&interp.x, &interp.y, &interp.z];
let grid_names = ["x", "y", "z"];
let mut errors = Vec::new();
for dim in 0..3 {
if !(grid[dim][0] <= point[dim]
&& &point[dim] <= grid[dim].last().unwrap())
{
errors.push(format!(
"\n point[{dim}] = {:?} is out of bounds for {}-grid = {:?}",
point[dim], grid_names[dim], grid[dim],
));
}
}
if !(interp.y[0] <= point[1] && &point[1] <= interp.y.last().unwrap()) {
return Err(InterpolationError::ExtrapolationError(format!(
"point = {point:?}, y grid = {:?}",
interp.y
)));
}
if !(interp.z[0] <= point[2] && &point[2] <= interp.z.last().unwrap()) {
return Err(InterpolationError::ExtrapolationError(format!(
"point = {point:?}, z grid = {:?}",
interp.z
)));
if !errors.is_empty() {
return Err(InterpolationError::ExtrapolationError(errors.join("")));
}
}
_ => {}
Expand All @@ -702,14 +704,20 @@ impl InterpMethods for Interpolator {
return interp.interpolate(&clamped_point);
}
Extrapolate::Error => {
if !point.iter().enumerate().all(|(dim, pt_dim)| {
&interp.grid[dim][0] <= pt_dim
&& pt_dim <= interp.grid[dim].last().unwrap()
}) {
return Err(InterpolationError::ExtrapolationError(format!(
"point = {point:?}, grid: {:?}",
interp.grid,
)));
let mut errors = Vec::new();
for dim in 0..interp.ndim() {
if !(interp.grid[dim][0] <= point[dim]
&& &point[dim] <= interp.grid[dim].last().unwrap())
{
errors.push(format!(
"\n point[{dim}] = {:?} is out of bounds for grid[{dim}] = {:?}",
point[dim],
interp.grid[dim],
));
}
}
if !errors.is_empty() {
return Err(InterpolationError::ExtrapolationError(errors.join("")));
}
}
_ => {}
Expand Down
48 changes: 24 additions & 24 deletions src/n.rs
Original file line number Diff line number Diff line change
Expand Up @@ -208,12 +208,12 @@ mod tests {
]
.into_dyn();
let interp = Interpolator::new_nd(
grid.clone(),
f_xyz.clone(),
Strategy::Linear,
Extrapolate::Error,
)
.unwrap();
grid.clone(),
f_xyz.clone(),
Strategy::Linear,
Extrapolate::Error,
)
.unwrap();
// Check that interpolating at grid points just retrieves the value
for i in 0..grid[0].len() {
for j in 0..grid[1].len() {
Expand Down Expand Up @@ -258,12 +258,12 @@ mod tests {
#[test]
fn test_linear_offset() {
let interp = Interpolator::new_nd(
vec![vec![0., 1.], vec![0., 1.], vec![0., 1.]],
ndarray::array![[[0., 1.], [2., 3.]], [[4., 5.], [6., 7.]],].into_dyn(),
Strategy::Linear,
Extrapolate::Error,
)
.unwrap();
vec![vec![0., 1.], vec![0., 1.], vec![0., 1.]],
ndarray::array![[[0., 1.], [2., 3.]], [[4., 5.], [6., 7.]],].into_dyn(),
Strategy::Linear,
Extrapolate::Error,
)
.unwrap();
assert_eq!(
interp.interpolate(&[0.25, 0.65, 0.9]).unwrap(),
3.1999999999999997
Expand All @@ -286,12 +286,12 @@ mod tests {
));
// Extrapolate::Error
let interp = Interpolator::new_nd(
vec![vec![0., 1.], vec![0., 1.], vec![0., 1.]],
ndarray::array![[[0., 1.], [2., 3.]], [[4., 5.], [6., 7.]],].into_dyn(),
Strategy::Linear,
Extrapolate::Error,
)
.unwrap();
vec![vec![0., 1.], vec![0., 1.], vec![0., 1.]],
ndarray::array![[[0., 1.], [2., 3.]], [[4., 5.], [6., 7.]],].into_dyn(),
Strategy::Linear,
Extrapolate::Error,
)
.unwrap();
assert!(matches!(
interp.interpolate(&[-1., -1., -1.]).unwrap_err(),
InterpolationError::ExtrapolationError(_)
Expand All @@ -305,12 +305,12 @@ mod tests {
#[test]
fn test_extrapolate_clamp() {
let interp = Interpolator::new_nd(
vec![vec![0., 1.], vec![0., 1.], vec![0., 1.]],
ndarray::array![[[0., 1.], [2., 3.]], [[4., 5.], [6., 7.]],].into_dyn(),
Strategy::Linear,
Extrapolate::Clamp,
)
.unwrap();
vec![vec![0., 1.], vec![0., 1.], vec![0., 1.]],
ndarray::array![[[0., 1.], [2., 3.]], [[4., 5.], [6., 7.]],].into_dyn(),
Strategy::Linear,
Extrapolate::Clamp,
)
.unwrap();
assert_eq!(interp.interpolate(&[-1., -1., -1.]).unwrap(), 0.);
assert_eq!(interp.interpolate(&[2., 2., 2.]).unwrap(), 7.);
}
Expand Down

0 comments on commit 70df920

Please sign in to comment.