signal_processing 0.3.0

A signal processing library.
Documentation
use num::{complex::ComplexFloat, Complex, Float, One};
use option_trait::Maybe;

use crate::{quantities::{ListOrSingle, MaybeOwnedList, MaybeList, MaybeLists, Polynomial}, System, systems::{Sos, Tf, Zpk}, transforms::system::ToZpk};

pub trait IsMaxPhase<'a>: System
{
    type Output: ListOrSingle<bool>;

    fn is_maxphase<TOL>(&'a self, tol: TOL) -> Self::Output
    where
        TOL: Maybe<<Self::Set as ComplexFloat>::Real>;
}

impl<'a, T, B, A> IsMaxPhase<'a> for Tf<T, B, A>
where
    T: ComplexFloat + 'a,
    B: MaybeLists<T> + 'a,
    A: MaybeList<T> + 'a,
    A::View<'a>: MaybeList<T> + Clone,
    Tf<T, B::RowView<'a>, A::View<'a>>: ToZpk<Complex<T::Real>, Vec<Complex<T::Real>>, Vec<Complex<T::Real>>, T, (), ()>,
    Zpk<Complex<T::Real>, Vec<Complex<T::Real>>, Vec<Complex<T::Real>>, T>: for<'b> IsMaxPhase<'b, Output = bool> + System<Set = T>
{
    type Output = B::RowsMapped<bool>;

    fn is_maxphase<TOL>(&'a self, tol: TOL) -> Self::Output
    where
        TOL: Maybe<T::Real>
    {
        let tol = tol.into_option();

        let a = self.a.as_view();

        self.b.map_rows_to_owned(|b| {
            let tf = Tf {
                b: Polynomial::new(b),
                a: a.clone()
            };

            tf.to_zpk((), ())
                .is_maxphase(tol)
        })
    }
}

impl<'a, T, B, A, S> IsMaxPhase<'a> for Sos<T, B, A, S>
where
    T: ComplexFloat,
    B: Maybe<[T; 3]> + MaybeOwnedList<T>,
    A: Maybe<[T; 3]> + MaybeOwnedList<T>,
    S: MaybeList<Tf<T, B, A>> + 'a,
    S::View<'a>: MaybeList<Tf<T, B, A>>,
    Sos<T, B, A, S::View<'a>>: ToZpk<Complex<T::Real>, Vec<Complex<T::Real>>, Vec<Complex<T::Real>>, T, (), ()>,
    Zpk<Complex<T::Real>, Vec<Complex<T::Real>>, Vec<Complex<T::Real>>, T>: for<'b> IsMaxPhase<'b, Output = bool> + System<Set = T>
{
    type Output = bool;

    fn is_maxphase<TOL>(&'a self, tol: TOL) -> Self::Output
    where
        TOL: Maybe<T::Real>
    {
        self.as_view()
            .to_zpk((), ())
            .is_maxphase(tol)
    }
}

impl<'a, T, Z, P, K> IsMaxPhase<'a> for  Zpk<T, Z, P, K>
where
    T: ComplexFloat,
    Z: MaybeList<T>,
    P: MaybeList<T>,
    K: ComplexFloat<Real = T::Real>
{
    type Output = bool;

    fn is_maxphase<TOL>(&'a self, tol: TOL) -> Self::Output
    where
        TOL: Maybe<T::Real>
    {
        let tol = tol.into_option()
            .map(|tol| Float::abs(tol))
            .unwrap_or_else(T::Real::epsilon);

        let z = self.z.to_vec_option()
            .unwrap_or_else(|| vec![]);
        let p = self.p.to_vec_option()
            .unwrap_or_else(|| vec![]);

        let one = T::Real::one();

        (
            z.len() == 0 || z.into_iter()
                .all(|z| z.abs() > one + tol)
        ) && (
            p.len() == 0 || p.into_iter()
                .all(|p| p.abs() < one - tol)
        )
    }
}