rsl_interpolation/types/
dynamic2d.rs

1use std::ops::Deref;
2
3use crate::Interp2dType;
4use crate::Interpolation2d;
5use crate::InterpolationError;
6
7/// Representation of a 2d Interpolation Type that is not known in compile-time.
8pub struct DynInterp2dType<T> {
9    #[allow(clippy::type_complexity)]
10    build: Box<
11        dyn Fn(
12                &[T],
13                &[T],
14                &[T],
15            )
16                -> Result<Box<dyn Interpolation2d<T> + Send + Sync + 'static>, InterpolationError>
17            + Send
18            + Sync
19            + 'static,
20    >,
21    name: Box<str>,
22    min_size: usize,
23}
24
25impl<T> DynInterp2dType<T> {
26    pub fn new<I>(interp: I) -> Self
27    where
28        I: Interp2dType<T> + Send + Sync + 'static,
29        I::Interpolation2d: Send + Sync + 'static,
30    {
31        Self {
32            name: interp.name().into(),
33            min_size: interp.min_size(),
34            build: Box::new(move |xa, ya, za| match interp.build(xa, ya, za) {
35                Ok(interp) => Ok(Box::new(interp)),
36                Err(err) => Err(err),
37            }),
38        }
39    }
40}
41
42impl<T> Interp2dType<T> for DynInterp2dType<T> {
43    type Interpolation2d = Box<dyn Interpolation2d<T> + Send + Sync + 'static>;
44
45    fn build(
46        &self,
47        xa: &[T],
48        ya: &[T],
49        za: &[T],
50    ) -> Result<Self::Interpolation2d, InterpolationError> {
51        (self.build)(xa, ya, za)
52    }
53
54    fn name(&self) -> &str {
55        &self.name
56    }
57
58    fn min_size(&self) -> usize {
59        self.min_size
60    }
61}
62
63impl<T> Interpolation2d<T> for Box<dyn Interpolation2d<T> + Send + Sync + 'static> {
64    fn eval_extrap(
65        &self,
66        xa: &[T],
67        ya: &[T],
68        za: &[T],
69        x: T,
70        y: T,
71        xacc: &mut crate::Accelerator,
72        yacc: &mut crate::Accelerator,
73    ) -> Result<T, crate::DomainError> {
74        self.deref().eval_extrap(xa, ya, za, x, y, xacc, yacc)
75    }
76
77    fn eval_deriv_x(
78        &self,
79        xa: &[T],
80        ya: &[T],
81        za: &[T],
82        x: T,
83        y: T,
84        xacc: &mut crate::Accelerator,
85        yacc: &mut crate::Accelerator,
86    ) -> Result<T, crate::DomainError> {
87        self.deref().eval_deriv_x(xa, ya, za, x, y, xacc, yacc)
88    }
89
90    fn eval_deriv_y(
91        &self,
92        xa: &[T],
93        ya: &[T],
94        za: &[T],
95        x: T,
96        y: T,
97        xacc: &mut crate::Accelerator,
98        yacc: &mut crate::Accelerator,
99    ) -> Result<T, crate::DomainError> {
100        self.deref().eval_deriv_y(xa, ya, za, x, y, xacc, yacc)
101    }
102
103    fn eval_deriv_xx(
104        &self,
105        xa: &[T],
106        ya: &[T],
107        za: &[T],
108        x: T,
109        y: T,
110        xacc: &mut crate::Accelerator,
111        yacc: &mut crate::Accelerator,
112    ) -> Result<T, crate::DomainError> {
113        self.deref().eval_deriv_xx(xa, ya, za, x, y, xacc, yacc)
114    }
115
116    fn eval_deriv_yy(
117        &self,
118        xa: &[T],
119        ya: &[T],
120        za: &[T],
121        x: T,
122        y: T,
123        xacc: &mut crate::Accelerator,
124        yacc: &mut crate::Accelerator,
125    ) -> Result<T, crate::DomainError> {
126        self.deref().eval_deriv_yy(xa, ya, za, x, y, xacc, yacc)
127    }
128
129    fn eval_deriv_xy(
130        &self,
131        xa: &[T],
132        ya: &[T],
133        za: &[T],
134        x: T,
135        y: T,
136        xacc: &mut crate::Accelerator,
137        yacc: &mut crate::Accelerator,
138    ) -> Result<T, crate::DomainError> {
139        self.deref().eval_deriv_xy(xa, ya, za, x, y, xacc, yacc)
140    }
141}
142
143#[cfg(test)]
144mod test {
145    use crate::*;
146
147    #[test]
148    fn test_dyn_interp2d_type() {
149        let xa = [0.0, 1.0, 2.0, 3.0];
150        let ya = [0.0, 1.0, 2.0, 3.0];
151        #[rustfmt::skip]
152        let za = [
153            1.0, 1.1, 1.2, 1.3,
154            1.1, 1.2, 1.3, 1.4,
155            1.2, 1.3, 1.4, 1.5,
156            1.3, 1.4, 1.5, 1.6,
157        ];
158
159        let mut xacc = Accelerator::new();
160        let mut yacc = Accelerator::new();
161        let interp: Box<dyn Interpolation2d<_>> =
162            DynInterp2dType::new(Bicubic).build(&xa, &ya, &za).unwrap();
163
164        let _ = interp
165            .eval(&xa, &ya, &za, 1.0, 1.0, &mut xacc, &mut yacc)
166            .unwrap();
167    }
168}