#[cfg(test)]
mod test;
use super::{Scalar, Tensor, TensorVec, Vector, integrate::IntegrationError};
use std::ops::{Mul, Sub};
pub struct LinearInterpolation {}
pub trait Interpolate1D<F, T>
where
F: TensorVec<Item = T>,
T: Tensor,
{
fn interpolate_1d(x: &Vector, xp: &Vector, fp: &F) -> F;
}
pub trait InterpolateSolution<Y, U>
where
Y: Tensor,
for<'a> &'a Y: Mul<Scalar, Output = Y> + Sub<&'a Y, Output = Y>,
U: TensorVec<Item = Y>,
{
fn interpolate(
&self,
time: &Vector,
tp: &Vector,
yp: &U,
function: impl FnMut(Scalar, &Y) -> Result<Y, String>,
) -> Result<(U, U), IntegrationError>;
}
impl<F, T> Interpolate1D<F, T> for LinearInterpolation
where
F: TensorVec<Item = T>,
T: Tensor,
{
fn interpolate_1d(x: &Vector, xp: &Vector, fp: &F) -> F {
let mut i = 0;
x.iter()
.map(|x_k| {
i = xp.iter().position(|xp_i| xp_i > x_k).unwrap();
(fp[i].clone() - &fp[i - 1]) / (xp[i] - xp[i - 1]) * (x_k - xp[i - 1]) + &fp[i - 1]
})
.collect()
}
}