use crate::{Continuous, TransferFunction};
use num_traits::Float;
use std::ops::AddAssign;
#[derive(Clone, Debug)]
pub struct DelayedRational<T> {
pub delay: T,
pub rational: TransferFunction<T, Continuous>,
}
#[derive(Clone, Debug)]
pub struct DelayedRationalSum<T> {
pub terms: Vec<DelayedRational<T>>,
}
impl<T> DelayedRationalSum<T> {
pub fn new() -> Self {
Self { terms: Vec::new() }
}
pub fn push(&mut self, delay: T, rational: TransferFunction<T, Continuous>) -> &mut Self {
self.terms.push(DelayedRational { delay, rational });
self
}
}
impl<T> Default for DelayedRationalSum<T> {
fn default() -> Self {
Self::new()
}
}
impl<T: Float + AddAssign> DelayedRationalSum<T> {
pub fn inverse_laplace(&self) -> impl Fn(T) -> T + use<T>
where
T: 'static,
{
let parts: Vec<_> = self
.terms
.iter()
.map(|c| (c.delay, c.rational.partial_fraction()))
.collect();
move |t| {
parts
.iter()
.fold(T::zero(), |acc, (delay, pf)| acc + pf.time_response(t - *delay))
}
}
}