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
use std::{f64::consts::TAU, ops::MulAssign};

use num::{Complex, complex::ComplexFloat, Float};
use crate::{FFT, FFTUsingAlgorithm};

pub struct SlidingDFT<F, const N: usize>{
    x_f: [Complex<F>; N],
    x: [F; N]
}

impl<F, const N: usize> SlidingDFT<F, N>
where
    Complex<F>: ComplexFloat + MulAssign,
    F: Float
{
    pub fn new<A>(x: [F; N]) -> Self
    where
        [F; N]: FFTUsingAlgorithm<[Complex<F>; N], A>
    {
        Self {
            x_f: x.fft::<A>(),
            x
        }
    }

    pub fn next(&mut self, x: F) -> [Complex<F>; N]
    {
        let xn = self.x[N - 1];
        for n in (0..(N - 1)).rev()
        {
            self.x[n + 1] = self.x[n];
        }
        self.x[0] = x;

        if self.x == [F::zero(); N]
        {
            self.x_f = [Complex::from(F::zero()); N];
        }
        else
        {
            let x_delta = Complex::from(xn - x);
    
            let mut z_n = Complex::from(F::one());
            let z_1 = Complex::cis(F::from(TAU).unwrap()/F::from(N).unwrap());
    
            for x_f in self.x_f.iter_mut()
            {
                *x_f = z_n*(*x_f + x_delta);
    
                z_n *= z_1;
            }
        }

        self.x_f
    }
}