rsl_interpolation/interp.rs
1//! InterpType and Interpolation definitions
2
3use crate::Accelerator;
4use crate::{DomainError, InterpolationError};
5
6/// Representation of an Interpolation Type.
7pub trait InterpType<T> {
8 /// The returned Interpolator, containing the calculated coefficients and providing the
9 /// evaluation methods.
10 type Interpolation: Interpolation<T> + Send + Sync;
11
12 /// Creates an Interpolator from the data arrays `xa` and `ya`.
13 ///
14 /// # Example
15 ///
16 /// ```
17 /// # use rsl_interpolation::*;
18 ///
19 /// # fn main() -> Result<(), InterpolationError>{
20 /// let xa = [0.0, 1.0, 2.0];
21 /// let ya = [0.0, 2.0, 4.0];
22 /// let interp = Cubic.build(&xa, &ya)?;
23 /// # Ok(())
24 /// # }
25 /// ```
26 fn build(&self, xa: &[T], ya: &[T]) -> Result<Self::Interpolation, InterpolationError>;
27
28 /// Returns the name of the Interpolator.
29 #[doc(alias = "gsl_interp_name")]
30 fn name(&self) -> &str;
31
32 /// Returns the minimum number of points required by the Interpolator.
33 #[doc(alias = "gsl_interp_min_size")]
34 fn min_size(&self) -> usize;
35}
36
37/// Defines the required evaluation methods.
38pub trait Interpolation<T> {
39 /// Returns the interpolated value `y` for a given point `x`, using the data arrays `xa` and `ya` and
40 /// the [`Accelerator`] `acc`.
41 ///
42 /// # Example
43 ///
44 /// ```
45 /// # use rsl_interpolation::*;
46 /// #
47 /// # fn main() -> Result<(), InterpolationError>{
48 /// let xa = [0.0, 1.0, 2.0];
49 /// let ya = [0.0, 2.0, 4.0];
50 /// let interp = Cubic.build(&xa, &ya)?;
51 /// let mut acc = Accelerator::new();
52 ///
53 /// let y = interp.eval(&xa, &ya, 1.5, &mut acc)?;
54 ///
55 /// assert_eq!(y, 3.0);
56 /// # Ok(())
57 /// # }
58 /// ```
59 ///
60 /// # Errors
61 ///
62 /// Returns a [`DomainError`] if `x` is outside the range of `xa`.
63 #[doc(alias = "gsl_interp_eval")]
64 #[doc(alias = "gsl_interp_eval_e")]
65 fn eval(&self, xa: &[T], ya: &[T], x: T, acc: &mut Accelerator) -> Result<T, DomainError>;
66
67 /// Returns the derivative `dy/dx` of an interpolated function for a given point `x`, using the
68 /// data arrays `xa` and `ya` and the [`Accelerator`] `acc`.
69 ///
70 /// # Example
71 ///
72 /// ```
73 /// # use rsl_interpolation::*;
74 /// #
75 /// # fn main() -> Result<(), InterpolationError>{
76 /// let xa = [0.0, 1.0, 2.0];
77 /// let ya = [0.0, 2.0, 4.0];
78 /// let interp = Cubic.build(&xa, &ya)?;
79 /// let mut acc = Accelerator::new();
80 ///
81 /// let dydx = interp.eval_deriv(&xa, &ya, 1.5, &mut acc)?;
82 ///
83 /// assert_eq!(dydx, 2.0);
84 /// # Ok(())
85 /// # }
86 /// ```
87 ///
88 /// # Errors
89 ///
90 /// Returns a [`DomainError`] if `x` is outside the range of `xa`.
91 #[doc(alias = "gsl_interp_eval_deriv")]
92 #[doc(alias = "gsl_interp_eval_deriv_e")]
93 fn eval_deriv(&self, xa: &[T], ya: &[T], x: T, acc: &mut Accelerator)
94 -> Result<T, DomainError>;
95
96 /// Returns the second derivative `d²y/dx²` of an interpolated function for a given point `x`, using the
97 /// data arrays `xa` and `ya` and the [`Accelerator`] `acc`.
98 ///
99 /// # Example
100 ///
101 /// ```
102 /// # use rsl_interpolation::*;
103 /// #
104 /// # fn main() -> Result<(), InterpolationError>{
105 /// let xa = [0.0, 1.0, 2.0];
106 /// let ya = [0.0, 2.0, 4.0];
107 /// let interp = Cubic.build(&xa, &ya)?;
108 /// let mut acc = Accelerator::new();
109 ///
110 /// let dydx2 = interp.eval_deriv2(&xa, &ya, 1.5, &mut acc)?;
111 ///
112 /// assert_eq!(dydx2, 0.0);
113 /// # Ok(())
114 /// # }
115 /// ```
116 ///
117 /// # Errors
118 ///
119 /// Returns a [`DomainError`] if `x` is outside the range of `xa`.
120 #[doc(alias = "gsl_interp_eval_deriv2")]
121 #[doc(alias = "gsl_interp_eval_deriv2_e")]
122 fn eval_deriv2(
123 &self,
124 xa: &[T],
125 ya: &[T],
126 x: T,
127 acc: &mut Accelerator,
128 ) -> Result<T, DomainError>;
129
130 #[allow(rustdoc::broken_intra_doc_links)]
131 /// Returns the numerical integral of an interpolated function over the range [`a` ,`b`], using the
132 /// data arrays `xa` and `ya` and the [`Accelerator`] `acc`.
133 ///
134 /// # Example
135 ///
136 /// ```
137 /// # use rsl_interpolation::*;
138 /// #
139 /// # fn main() -> Result<(), InterpolationError>{
140 /// let xa = [0.0, 1.0, 2.0];
141 /// let ya = [0.0, 2.0, 4.0];
142 /// let interp = Cubic.build(&xa, &ya)?;
143 /// let mut acc = Accelerator::new();
144 ///
145 /// let int = interp.eval_integ(&xa, &ya, 0.0, 2.0, &mut acc)?;
146 ///
147 /// assert_eq!(int, 4.0);
148 /// # Ok(())
149 /// # }
150 /// ```
151 ///
152 /// # Errors
153 ///
154 /// Returns a [`DomainError`] if `a` or `b` is outside the range of xa.
155 #[doc(alias = "gsl_interp_eval_integ")]
156 #[doc(alias = "gsl_interp_eval_integ_e")]
157 fn eval_integ(
158 &self,
159 xa: &[T],
160 ya: &[T],
161 a: T,
162 b: T,
163 acc: &mut Accelerator,
164 ) -> Result<T, DomainError>;
165}