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}