1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
use num::complex::ComplexFloat;
use option_trait::Maybe;

use crate::{systems::Ar, identification::ar::ArYule, quantities::{List, Lists}, analysis::{Psd, PsdMethod, PsdRange}, System};

pub trait PYuleAr<X, P, F, O, N, FF, R, M>: Lists<X>
where
    X: ComplexFloat,
    P: Lists<X::Real>,
    F: List<X::Real>,
    O: Maybe<usize>,
    N: Maybe<usize>,
    FF: Maybe<F>,
    M: Maybe<PsdMethod>,
    R: Maybe<PsdRange>
{
    fn pyulear<FS>(self, order: O, numtaps: N, frequencies: FF, sampling_frequency: FS, range: R, method: M) -> (P, F)
    where
        FS: Maybe<X::Real>;
}

impl<X, XX, P, F, O, N, FF, R, M> PYuleAr<X, P, F, O, N, FF, R, M> for XX
where
    X: ComplexFloat,
    XX: Lists<X>,
    P: Lists<X::Real>,
    F: List<X::Real>,
    O: Maybe<usize>,
    N: Maybe<usize>,
    FF: Maybe<F>,
    M: Maybe<PsdMethod>,
    R: Maybe<PsdRange>,
    Ar<X, Vec<X>, XX::RowsMapped<(Vec<X>, X::Real)>>: ArYule<XX, O, XX::RowsMapped<Vec<X>>> + for<'a> Psd<'a, P, F, N, FF, R, M> + System<Set = X>,
    XX::RowsMapped<Vec<X>>: Lists<X>
{
    fn pyulear<FS>(self, order: O, numtaps: N, frequencies: FF, sampling_frequency: FS, range: R, method: M) -> (P, F)
    where
        FS: Maybe<<X as ComplexFloat>::Real>
    {
        let (ar, _) = Ar::aryule(self, order);
        ar.psd(numtaps, frequencies, sampling_frequency, range, method)
    }
}

#[cfg(test)]
mod test
{
    use array_math::ArrayOps;

    use crate::{plot, analysis::PYuleAr};

    #[test]
    fn test()
    {
        let x = [1.0, 2.0, 3.0, 4.0, 5.0];

        const N: usize = 1024;
        let (psd, f): ([_; N], _) = x.pyulear(2, (), (), (), (), ());

        plot::plot_curves("P(e^jw)", "plots/p_z_pyulear.png", [&f.zip(psd)])
            .unwrap();
    }
}