conspire/math/interpolate/
mod.rs

1#[cfg(test)]
2mod test;
3
4use super::{Tensor, TensorRank0, TensorVec, Vector, integrate::IntegrationError};
5use std::ops::{Mul, Sub};
6
7/// Linear interpolation schemes.
8pub struct LinearInterpolation {}
9
10/// One-dimensional interpolation schemes.
11pub trait Interpolate1D<F, T>
12where
13    F: TensorVec<Item = T>,
14    T: Tensor,
15{
16    /// One-dimensional interpolation.
17    fn interpolate_1d(x: &Vector, xp: &Vector, fp: &F) -> F;
18}
19
20/// Solution interpolation schemes.
21pub trait InterpolateSolution<Y, U>
22where
23    Y: Tensor,
24    for<'a> &'a Y: Mul<TensorRank0, Output = Y> + Sub<&'a Y, Output = Y>,
25    U: TensorVec<Item = Y>,
26{
27    /// Solution interpolation.
28    fn interpolate(
29        &self,
30        time: &Vector,
31        tp: &Vector,
32        yp: &U,
33        function: impl Fn(TensorRank0, &Y) -> Result<Y, IntegrationError>,
34    ) -> Result<(U, U), IntegrationError>;
35}
36
37impl<F, T> Interpolate1D<F, T> for LinearInterpolation
38where
39    F: TensorVec<Item = T>,
40    T: Tensor,
41{
42    fn interpolate_1d(x: &Vector, xp: &Vector, fp: &F) -> F {
43        let mut i = 0;
44        x.iter()
45            .map(|x_k| {
46                i = xp.iter().position(|xp_i| xp_i > x_k).unwrap();
47                (fp[i].clone() - &fp[i - 1]) / (xp[i] - xp[i - 1]) * (x_k - xp[i - 1]) + &fp[i - 1]
48            })
49            .collect()
50    }
51}