signal_processing 0.3.0

A signal processing library.
Documentation
use core::ops::{AddAssign, MulAssign};

use array_math::SliceMath;
use num::{complex::ComplexFloat, Complex, One};
use option_trait::Maybe;

use crate::{quantities::{Lists, MaybeList, MaybeOwnedList}, systems::{Sos, Tf, Zpk}, System, transforms::system::ToSos};

pub trait FreqS<'a, S, SS>: System
where
    S: ComplexFloat,
    SS: Lists<S> + 'a
{
    fn freqs(&'a self, s: SS) -> SS::Mapped<Complex<<Self::Set as ComplexFloat>::Real>>;
}

impl<'a, T, S, SS, B, A> FreqS<'a, S, SS> for Tf<T, B, A>
where
    S: ComplexFloat<Real = T::Real> + 'a,
    SS: Lists<S> + 'a,
    T: ComplexFloat + Into<Complex<T::Real>>,
    Complex<T::Real>: MulAssign<S> + AddAssign,
    B: MaybeList<T>,
    A: MaybeList<T>,
    Self: 'a
{
    fn freqs(&'a self, s: SS) -> SS::Mapped<Complex<T::Real>>
    {
        s.map_into_owned(|s| self.b.as_view_slice_option()

                .map(|b: &[T]| b.iter()

                    .map(|b| (*b).into())
                    .collect::<Vec<_>>()
                    .rpolynomial(s)
                ).unwrap_or_else(One::one)
            /self.a.as_view_slice_option()
                .map(|a: &[T]| a.iter()

                    .map(|a| (*a).into())
                    .collect::<Vec<_>>()
                    .rpolynomial(s)
                ).unwrap_or_else(One::one)
        )
    }
}

impl<'a, T, B, A, S, SS, SSS> FreqS<'a, SS, SSS> 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>>,
    SS: ComplexFloat<Real = T::Real> + 'a,
    SSS: Lists<SS> + 'a,
    Tf<T, B, A>: FreqS<'a, SS, [SS; 1]> + System<Set = T>
{
    fn freqs(&'a self, s: SSS) -> SSS::Mapped<Complex<T::Real>>
    {
        s.map_into_owned(|s| self.sos.as_view_slice_option()

            .map(|sos: &[Tf<T, B, A>]| sos.iter()

                .map(|tf| tf.freqs([s]))
                .map(|[s]| s)
                .reduce(|a, b| a*b)
                .unwrap_or_else(One::one)
            ).unwrap_or_else(One::one)
        )
    }
}

impl<'a, T, Z, P, K, S, SS> FreqS<'a, S, SS> for Zpk<T, Z, P, K>
where
    T: ComplexFloat,
    Z: MaybeList<T> + 'a,
    P: MaybeList<T> + 'a,
    K: ComplexFloat<Real = T::Real>,
    S: ComplexFloat<Real = T::Real>,
    SS: Lists<S> + 'a,
    Z::View<'a>: MaybeList<T>,
    P::View<'a>: MaybeList<T>,
    Zpk<T, Z::View<'a>, P::View<'a>, K>: ToSos<K, [K; 3], [K; 3], Vec<Tf<K, [K; 3], [K; 3]>>, (), ()> + 'a + System<Set = K>,
    Sos<K, [K; 3], [K; 3], Vec<Tf<K, [K; 3], [K; 3]>>>: for<'b> FreqS<'b, S, SS> + System<Set = K>
{
    fn freqs(&'a self, s: SS) -> SS::Mapped<Complex<<Self::Set as ComplexFloat>::Real>>
    {
        self.as_view()
            .to_sos((), ())
            .freqs(s)
    }
}