conspire/math/interpolate/
mod.rs1#[cfg(test)]
2mod test;
3
4use super::{Scalar, Tensor, TensorVec, Vector, integrate::IntegrationError};
5use std::ops::{Mul, Sub};
6
7pub struct LinearInterpolation {}
9
10pub trait Interpolate1D<F, T>
12where
13 F: TensorVec<Item = T>,
14 T: Tensor,
15{
16 fn interpolate_1d(x: &Vector, xp: &Vector, fp: &F) -> F;
18}
19
20pub trait InterpolateSolution<Y, U>
22where
23 Y: Tensor,
24 for<'a> &'a Y: Mul<Scalar, Output = Y> + Sub<&'a Y, Output = Y>,
25 U: TensorVec<Item = Y>,
26{
27 fn interpolate(
29 &self,
30 time: &Vector,
31 tp: &Vector,
32 yp: &U,
33 function: impl FnMut(Scalar, &Y) -> Result<Y, String>,
34 ) -> Result<(U, U), IntegrationError>;
35}
36
37pub trait InterpolateSolutionIV<Y, Z, U, V>
39where
40 Y: Tensor,
41 Z: Tensor,
42 for<'a> &'a Y: Mul<Scalar, Output = Y> + Sub<&'a Y, Output = Y>,
43 U: TensorVec<Item = Y>,
44 V: TensorVec<Item = Z>,
45{
46 fn interpolate(
48 &self,
49 time: &Vector,
50 tp: &Vector,
51 yp: &U,
52 zp: &V,
53 function: impl FnMut(Scalar, &Y, &Z) -> Result<Y, String>,
54 evaluate: impl FnMut(Scalar, &Y, &Z) -> Result<Z, String>,
55 ) -> Result<(U, U, V), IntegrationError>;
56}
57
58impl<F, T> Interpolate1D<F, T> for LinearInterpolation
59where
60 F: TensorVec<Item = T>,
61 T: Tensor,
62{
63 fn interpolate_1d(x: &Vector, xp: &Vector, fp: &F) -> F {
64 let mut i = 0;
65 x.iter()
66 .map(|x_k| {
67 i = xp.iter().position(|xp_i| xp_i > x_k).unwrap();
68 (fp[i].clone() - &fp[i - 1]) / (xp[i] - xp[i - 1]) * (x_k - xp[i - 1]) + &fp[i - 1]
69 })
70 .collect()
71 }
72}