use super::*;
use strategy::enums::*;
#[allow(missing_docs)]
#[derive(Debug, Clone)]
#[cfg_attr(feature = "serde", derive(Deserialize, Serialize))]
#[cfg_attr(feature = "serde", serde(untagged))]
#[cfg_attr(
feature = "serde",
serde(bound(
serialize = "D::Elem: Serialize",
deserialize = "
D: DataOwned,
D::Elem: Deserialize<'de>,
"
))
)]
pub enum InterpolatorEnum<D>
where
D: Data + RawDataClone + Clone,
D::Elem: Num + PartialOrd + Copy + Debug,
{
Interp0D(Interp0D<D::Elem>),
Interp1D(Interp1D<D, Strategy1DEnum>),
Interp2D(Interp2D<D, Strategy2DEnum>),
Interp3D(Interp3D<D, Strategy3DEnum>),
InterpND(InterpND<D, StrategyNDEnum>),
}
pub type InterpolatorEnumViewed<T> = InterpolatorEnum<ViewRepr<T>>;
pub type InterpolatorEnumOwned<T> = InterpolatorEnum<OwnedRepr<T>>;
impl<D> PartialEq for InterpolatorEnum<D>
where
D: Data + RawDataClone + Clone,
D::Elem: Num + PartialOrd + Copy + Debug,
ArrayBase<D, Ix1>: PartialEq,
{
fn eq(&self, other: &Self) -> bool {
match (self, other) {
(Self::Interp0D(l), Self::Interp0D(r)) => l == r,
(Self::Interp1D(l), Self::Interp1D(r)) => l == r,
(Self::Interp2D(l), Self::Interp2D(r)) => l == r,
(Self::Interp3D(l), Self::Interp3D(r)) => l == r,
(Self::InterpND(l), Self::InterpND(r)) => l == r,
_ => false,
}
}
}
impl<D> InterpolatorEnum<D>
where
D: Data + RawDataClone + Clone,
D::Elem: Num + PartialOrd + Copy + Debug,
{
#[inline]
pub fn new_0d(value: D::Elem) -> Self {
Self::Interp0D(Interp0D::new(value))
}
#[inline]
pub fn new_1d(
x: ArrayBase<D, Ix1>,
f_x: ArrayBase<D, Ix1>,
strategy: impl Into<Strategy1DEnum>,
extrapolate: Extrapolate<D::Elem>,
) -> Result<Self, ValidateError> {
Ok(Self::Interp1D(Interp1D::new(
x,
f_x,
strategy.into(),
extrapolate,
)?))
}
#[inline]
pub fn new_2d(
x: ArrayBase<D, Ix1>,
y: ArrayBase<D, Ix1>,
f_xy: ArrayBase<D, Ix2>,
strategy: impl Into<Strategy2DEnum>,
extrapolate: Extrapolate<D::Elem>,
) -> Result<Self, ValidateError> {
Ok(Self::Interp2D(Interp2D::new(
x,
y,
f_xy,
strategy.into(),
extrapolate,
)?))
}
#[inline]
pub fn new_3d(
x: ArrayBase<D, Ix1>,
y: ArrayBase<D, Ix1>,
z: ArrayBase<D, Ix1>,
f_xyz: ArrayBase<D, Ix3>,
strategy: impl Into<Strategy3DEnum>,
extrapolate: Extrapolate<D::Elem>,
) -> Result<Self, ValidateError> {
Ok(Self::Interp3D(Interp3D::new(
x,
y,
z,
f_xyz,
strategy.into(),
extrapolate,
)?))
}
#[inline]
pub fn new_nd(
grid: Vec<ArrayBase<D, Ix1>>,
values: ArrayBase<D, IxDyn>,
strategy: impl Into<StrategyNDEnum>,
extrapolate: Extrapolate<D::Elem>,
) -> Result<Self, ValidateError> {
Ok(Self::InterpND(InterpND::new(
grid,
values,
strategy.into(),
extrapolate,
)?))
}
pub fn view(&self) -> InterpolatorEnumViewed<&D::Elem> {
match self {
InterpolatorEnum::Interp0D(interp) => InterpolatorEnum::Interp0D(interp.clone()),
InterpolatorEnum::Interp1D(interp) => InterpolatorEnum::Interp1D(interp.view()),
InterpolatorEnum::Interp2D(interp) => InterpolatorEnum::Interp2D(interp.view()),
InterpolatorEnum::Interp3D(interp) => InterpolatorEnum::Interp3D(interp.view()),
InterpolatorEnum::InterpND(interp) => InterpolatorEnum::InterpND(interp.view()),
}
}
pub fn into_owned(self) -> InterpolatorEnumOwned<D::Elem>
where
D::Elem: Clone,
{
match self {
InterpolatorEnum::Interp0D(interp) => InterpolatorEnum::Interp0D(interp.clone()),
InterpolatorEnum::Interp1D(interp) => InterpolatorEnum::Interp1D(interp.into_owned()),
InterpolatorEnum::Interp2D(interp) => InterpolatorEnum::Interp2D(interp.into_owned()),
InterpolatorEnum::Interp3D(interp) => InterpolatorEnum::Interp3D(interp.into_owned()),
InterpolatorEnum::InterpND(interp) => InterpolatorEnum::InterpND(interp.into_owned()),
}
}
}
impl<D> Interpolator<D::Elem> for InterpolatorEnum<D>
where
D: Data + RawDataClone + Clone,
D::Elem: Num + Euclid + PartialOrd + Copy + Debug,
{
#[inline]
fn ndim(&self) -> usize {
match self {
InterpolatorEnum::Interp0D(_) => 0,
InterpolatorEnum::Interp1D(_) => 1,
InterpolatorEnum::Interp2D(_) => 2,
InterpolatorEnum::Interp3D(_) => 3,
InterpolatorEnum::InterpND(interp) => interp.ndim(),
}
}
#[inline]
fn validate(&mut self) -> Result<(), ValidateError> {
match self {
InterpolatorEnum::Interp0D(_) => Ok(()),
InterpolatorEnum::Interp1D(interp) => interp.validate(),
InterpolatorEnum::Interp2D(interp) => interp.validate(),
InterpolatorEnum::Interp3D(interp) => interp.validate(),
InterpolatorEnum::InterpND(interp) => interp.validate(),
}
}
#[inline]
fn interpolate(&self, point: &[D::Elem]) -> Result<D::Elem, InterpolateError> {
match self {
InterpolatorEnum::Interp0D(interp) => interp.interpolate(point),
InterpolatorEnum::Interp1D(interp) => interp.interpolate(point),
InterpolatorEnum::Interp2D(interp) => interp.interpolate(point),
InterpolatorEnum::Interp3D(interp) => interp.interpolate(point),
InterpolatorEnum::InterpND(interp) => interp.interpolate(point),
}
}
#[inline]
fn set_extrapolate(&mut self, extrapolate: Extrapolate<D::Elem>) -> Result<(), ValidateError> {
match self {
InterpolatorEnum::Interp0D(_) => Ok(()),
InterpolatorEnum::Interp1D(interp) => interp.set_extrapolate(extrapolate),
InterpolatorEnum::Interp2D(interp) => interp.set_extrapolate(extrapolate),
InterpolatorEnum::Interp3D(interp) => interp.set_extrapolate(extrapolate),
InterpolatorEnum::InterpND(interp) => interp.set_extrapolate(extrapolate),
}
}
}
impl<D> From<Interp0D<D::Elem>> for InterpolatorEnum<D>
where
D: Data + RawDataClone + Clone,
D::Elem: Num + PartialOrd + Copy + Debug,
{
#[inline]
fn from(interpolator: Interp0D<D::Elem>) -> Self {
InterpolatorEnum::Interp0D(interpolator)
}
}
impl<D> From<Interp1D<D, Strategy1DEnum>> for InterpolatorEnum<D>
where
D: Data + RawDataClone + Clone,
D::Elem: Num + PartialOrd + Copy + Debug,
{
#[inline]
fn from(interpolator: Interp1D<D, Strategy1DEnum>) -> Self {
InterpolatorEnum::Interp1D(interpolator)
}
}
impl<D> From<Interp2D<D, Strategy2DEnum>> for InterpolatorEnum<D>
where
D: Data + RawDataClone + Clone,
D::Elem: Num + PartialOrd + Copy + Debug,
{
#[inline]
fn from(interpolator: Interp2D<D, Strategy2DEnum>) -> Self {
InterpolatorEnum::Interp2D(interpolator)
}
}
impl<D> From<Interp3D<D, Strategy3DEnum>> for InterpolatorEnum<D>
where
D: Data + RawDataClone + Clone,
D::Elem: Num + PartialOrd + Copy + Debug,
{
#[inline]
fn from(interpolator: Interp3D<D, Strategy3DEnum>) -> Self {
InterpolatorEnum::Interp3D(interpolator)
}
}
impl<D> From<InterpND<D, StrategyNDEnum>> for InterpolatorEnum<D>
where
D: Data + RawDataClone + Clone,
D::Elem: Num + PartialOrd + Copy + Debug,
{
#[inline]
fn from(interpolator: InterpND<D, StrategyNDEnum>) -> Self {
InterpolatorEnum::InterpND(interpolator)
}
}
mod tests {
#[allow(unused_imports)]
use super::*;
#[test]
fn test_partialeq() {
#[derive(PartialEq)]
#[allow(unused)]
struct MyStruct(InterpolatorEnumOwned<f64>);
}
#[test]
#[cfg(feature = "serde")]
fn test_serde() {
let x = array![0.05, 0.10, 0.15];
let y = array![0.10, 0.20, 0.30];
let f_xy = array![[0., 1., 2.], [3., 4., 5.], [6., 7., 8.]];
let f_xy_dyn = f_xy.clone().into_dyn();
let interp0: Interp2D<_, strategy::enums::Strategy2DEnum> = Interp2D::new(
x.view(),
y.view(),
f_xy.view(),
strategy::Nearest.into(),
Extrapolate::Error,
)
.unwrap();
let interp1 = InterpolatorEnum::from(interp0.clone());
let interp2: InterpND<_, strategy::enums::StrategyNDEnum> = InterpND::new(
vec![x.view(), y.view()],
f_xy_dyn.view(),
strategy::Nearest.into(),
Extrapolate::Error,
)
.unwrap();
let interp3 = InterpolatorEnum::from(interp2.view());
assert_eq!(
serde_json::to_string(&interp0).unwrap(),
serde_json::to_string(&interp1).unwrap(),
);
assert_eq!(
serde_json::to_string(&interp1).unwrap(),
serde_json::to_string(&interp2).unwrap(),
);
assert_eq!(
serde_json::to_string(&interp2).unwrap(),
serde_json::to_string(&interp3).unwrap(),
);
}
}