rsl_interpolation/types/
dynamic1d.rs1use std::ops::Deref;
2
3use crate::InterpType;
4use crate::Interpolation;
5use crate::InterpolationError;
6
7pub struct DynInterpType<T> {
9 #[allow(clippy::type_complexity)]
10 build: Box<
11 dyn Fn(
12 &[T],
13 &[T],
14 )
15 -> Result<Box<dyn Interpolation<T> + Send + Sync + 'static>, InterpolationError>
16 + Send
17 + Sync
18 + 'static,
19 >,
20 name: Box<str>,
21 min_size: usize,
22}
23
24impl<T> DynInterpType<T> {
25 pub fn new<I>(interp: I) -> Self
26 where
27 I: InterpType<T> + Send + Sync + 'static,
28 I::Interpolation: Send + Sync + 'static,
29 {
30 Self {
31 name: interp.name().into(),
32 min_size: interp.min_size(),
33 build: Box::new(move |xa, ya| match interp.build(xa, ya) {
34 Ok(interp) => Ok(Box::new(interp)),
35 Err(err) => Err(err),
36 }),
37 }
38 }
39}
40
41impl<T> InterpType<T> for DynInterpType<T> {
42 type Interpolation = Box<dyn Interpolation<T> + Send + Sync>;
43
44 fn build(&self, xa: &[T], ya: &[T]) -> Result<Self::Interpolation, InterpolationError> {
45 (self.build)(xa, ya)
46 }
47
48 fn name(&self) -> &str {
49 &self.name
50 }
51
52 fn min_size(&self) -> usize {
53 self.min_size
54 }
55}
56
57impl<T> Interpolation<T> for Box<dyn Interpolation<T> + Send + Sync + 'static> {
58 fn eval(
59 &self,
60 xa: &[T],
61 ya: &[T],
62 x: T,
63 acc: &mut crate::Accelerator,
64 ) -> Result<T, crate::DomainError> {
65 self.deref().eval(xa, ya, x, acc)
66 }
67
68 fn eval_deriv(
69 &self,
70 xa: &[T],
71 ya: &[T],
72 x: T,
73 acc: &mut crate::Accelerator,
74 ) -> Result<T, crate::DomainError> {
75 self.deref().eval_deriv(xa, ya, x, acc)
76 }
77
78 fn eval_deriv2(
79 &self,
80 xa: &[T],
81 ya: &[T],
82 x: T,
83 acc: &mut crate::Accelerator,
84 ) -> Result<T, crate::DomainError> {
85 self.deref().eval_deriv2(xa, ya, x, acc)
86 }
87
88 fn eval_integ(
89 &self,
90 xa: &[T],
91 ya: &[T],
92 a: T,
93 b: T,
94 acc: &mut crate::Accelerator,
95 ) -> Result<T, crate::DomainError> {
96 self.deref().eval_integ(xa, ya, a, b, acc)
97 }
98}
99
100#[cfg(test)]
101mod test {
102 use crate::*;
103
104 #[test]
105 fn test_dyn_interp_type() {
106 let xa = [1.0, 2.0, 3.0];
107 let ya = [1.0, 2.0, 3.0];
108
109 let mut acc = Accelerator::new();
110 let interp: Box<dyn Interpolation<_>> = DynInterpType::new(Cubic).build(&xa, &ya).unwrap();
111
112 let _ = interp.eval(&xa, &ya, 1.5, &mut acc).unwrap();
113 }
114}