signal_processing 0.3.0

A signal processing library.
Documentation
use ndarray::Array2;
use num::{traits::FloatConst, Float, Zero};
use option_trait::Maybe;

use crate::quantities::{List, Matrix, OwnedList, OwnedListOrSingle};

pub trait ConvMatrix<T, M, N>: List<T>
where
    T: Float + FloatConst,
    M: Matrix<T> + Sized,
    N: Maybe<usize>
{
    fn conv_matrix(self, n: N) -> M;
}

impl<T, A, const N: usize> ConvMatrix<T, [A::ResizedList<{A::LENGTH + N - 1}>; N], ()> for A
where
    T: Float + FloatConst,
    A: List<T, Length = usize>,
    A::ResizedList<{A::LENGTH + N - 1}>: OwnedList<T> + Clone,
    [A::ResizedList<{A::LENGTH + N - 1}>; N]: Matrix<T>
{
    fn conv_matrix(self: A, (): ()) -> [A::ResizedList<{A::LENGTH + N - 1}>; N]
    {
        let len = self.length();
        let mut a = self.static_resize_list((len + N).saturating_sub(1), Zero::zero);
        core::array::from_fn(|_| {
            let r = a.clone();
            a.as_mut_slice()
                .rotate_right(1);
            r
        })
    }
}

impl<T, A> ConvMatrix<T, Array2<T>, usize> for A
where
    T: Float + FloatConst,
    A: List<T>
{
    fn conv_matrix(self, n: usize) -> Array2<T>
    {
        let mut a = self.into_vec();
        let len = a.len();
        let m = (len + n).saturating_sub(1);
        a.resize(m, Zero::zero());
        Array2::from_shape_fn((n, m), |(i, j)| a[(j + m - i) % m])
    }
}

#[cfg(test)]
mod test
{
    use crate::gen::matrix::ConvMatrix;

    #[test]
    fn test()
    {
        let a = [3.0, 4.0, 5.0];

        const N: usize = 3;
        let m: [_; N] = a.conv_matrix(());

        println!("{:?}", m);

        let m = a.conv_matrix(N);

        println!("{:?}", m);
    }
}