interp2d: add map_*_axis methods

This commit is contained in:
Thomas Kramer
2023-06-06 17:43:41 +02:00
parent 0323138af3
commit 335fdc763e

View File

@@ -133,6 +133,21 @@ where
interpolate2d_bilinear(v00, v10, v01, v11, alpha, beta)
}
fn is_monotonic<T: PartialOrd, I: IntoIterator<Item = T>>(i: I) -> bool {
let mut it = i.into_iter();
if let Some(prev) = it.next() {
let mut prev = prev;
for n in it {
if prev <= n {
} else {
return false;
}
prev = n;
}
}
true
}
impl<C1, C2, Z, S> Interp2D<C1, C2, Z, S>
where
S: Data<Elem = Z>,
@@ -161,21 +176,6 @@ where
assert!(!x.is_empty());
assert!(!y.is_empty());
fn is_monotonic<T: PartialOrd, I: IntoIterator<Item = T>>(i: I) -> bool {
let mut it = i.into_iter();
if let Some(prev) = it.next() {
let mut prev = prev;
for n in it {
if prev <= n {
} else {
return false;
}
prev = n;
}
}
true
}
assert!(is_monotonic(&x), "x values must be monotonic.");
assert!(is_monotonic(&y), "x values must be monotonic.");
@@ -227,6 +227,35 @@ where
{
Interp2D::new(self.x.clone(), self.y.clone(), self.z.map(f))
}
/// Apply the function `f` to each x coordinate. Panics if the ordering of the coordinates
/// is not monotonic after applyint `f`.
pub fn map_x_axis<Xnew>(self, f: impl Fn(C1) -> Xnew) -> Interp2D<Xnew, C2, Z, S>
where
Xnew: PartialOrd,
{
let xnew = self.x.into_iter().map(f).collect();
assert!(is_monotonic(&xnew));
Interp2D {
x: xnew,
y: self.y,
z: self.z,
}
}
/// Apply the function `f` to each y coordinate. Panics if the ordering of the coordinates
/// is not monotonic after applyint `f`.
pub fn map_y_axis<Ynew>(self, f: impl Fn(C2) -> Ynew) -> Interp2D<C1, Ynew, Z, S>
where
Ynew: PartialOrd,
{
let ynew = self.y.into_iter().map(f).collect();
assert!(is_monotonic(&ynew));
Interp2D {
x: self.x,
y: ynew,
z: self.z,
}
}
}
impl<C1, C2, Z, S> Interp2D<C1, C2, Z, S>