signal_processing 0.3.0

A signal processing library.
Documentation
use num::complex::ComplexFloat;
use option_trait::Maybe;

use crate::{systems::Ar, identification::ar::Levinson, quantities::{List, ListOrSingle, Lists}, System, analysis::{XCorr, XCorrScale}};

pub trait Lpc<X, O>: System + Sized
where
    X: Lists<Self::Set>,
    O: Maybe<usize>
{
    fn lpc(x: X, order: O) -> Self;
}

impl<T, X, XX, const N: usize> Lpc<X, ()> for Ar<T, [T; N], X::RowsMapped<([T; N], T::Real)>>
where
    T: ComplexFloat<Real: Into<T>>,
    X: Lists<T, RowOwned = XX>,
    X::RowsMapped<([T; N], T::Real)>: ListOrSingle<([T; N], T::Real)>,
    XX: XCorr<T, T, (), T> + List<T, RowsMapped<Vec<T>> = Vec<T>>,
    Ar<T, [T; N], ([T; N], T::Real)>: Levinson<Vec<T>, (), [T; N - 1]> + System<Set = T>
{
    fn lpc(x: X, (): ()) -> Self
    {
        Ar::new(x.map_rows_into_owned(|x| {
            let (mut r, _): (Vec<T>, _) = x.xcorr((), XCorrScale::Biased, N);
            let mut r = r.split_off(N);
            if let Some(r) = r.get_mut(0)
            {
                *r = r.re().into()
            }
            let (Ar {av, ..}, _) = Ar::levinson(r, ()); 
            av
        }))
    }
}

impl<T, X, XX> Lpc<X, usize> for Ar<T, Vec<T>, X::RowsMapped<(Vec<T>, T::Real)>>
where
    T: ComplexFloat<Real: Into<T>>,
    X: Lists<T, RowOwned = XX>,
    X::RowsMapped<(Vec<T>, T::Real)>: ListOrSingle<(Vec<T>, T::Real)>,
    XX: XCorr<T, T, (), T> + List<T, RowsMapped<Vec<T>> = Vec<T>>,
    Ar<T, Vec<T>, (Vec<T>, T::Real)>: Levinson<Vec<T>, usize, Vec<T>> + System<Set = T>
{
    fn lpc(x: X, order: usize) -> Self
    {
        Ar::new(x.map_rows_into_owned(|x| {
            let (mut r, _): (Vec<T>, _) = x.xcorr((), XCorrScale::Biased, order + 1);
            let mut r = r.split_off(order + 1);
            if let Some(r) = r.get_mut(0)
            {
                *r = r.re().into()
            }
            let (Ar {av, ..}, _) = Ar::levinson(r, order); 
            av
        }))
    }
}