fourier_algorithms/
fft.rs1use num_complex::Complex;
2
3#[derive(Copy, Clone, PartialEq, Eq)]
5pub enum Transform {
6    Fft,
8    Ifft,
10    UnscaledIfft,
12    SqrtScaledFft,
14    SqrtScaledIfft,
16}
17
18impl Transform {
19    pub fn is_forward(&self) -> bool {
21        match self {
22            Self::Fft | Self::SqrtScaledFft => true,
23            Self::Ifft | Self::UnscaledIfft | Self::SqrtScaledIfft => false,
24        }
25    }
26
27    pub fn inverse(&self) -> Option<Self> {
29        match self {
30            Self::Fft => Some(Self::Ifft),
31            Self::Ifft => Some(Self::Fft),
32            Self::SqrtScaledFft => Some(Self::SqrtScaledIfft),
33            Self::SqrtScaledIfft => Some(Self::SqrtScaledFft),
34            Self::UnscaledIfft => None,
35        }
36    }
37}
38
39pub trait Fft {
41    type Real: Copy;
43
44    fn size(&self) -> usize;
46
47    fn transform_in_place(&self, input: &mut [Complex<Self::Real>], transform: Transform);
49
50    fn transform(
52        &self,
53        input: &[Complex<Self::Real>],
54        output: &mut [Complex<Self::Real>],
55        transform: Transform,
56    ) {
57        assert_eq!(input.len(), self.size());
58        assert_eq!(output.len(), self.size());
59        output.copy_from_slice(input);
60        self.transform_in_place(output, transform);
61    }
62
63    fn fft_in_place(&self, input: &mut [Complex<Self::Real>]) {
65        self.transform_in_place(input, Transform::Fft);
66    }
67
68    fn ifft_in_place(&self, input: &mut [Complex<Self::Real>]) {
70        self.transform_in_place(input, Transform::Ifft);
71    }
72
73    fn fft(&self, input: &[Complex<Self::Real>], output: &mut [Complex<Self::Real>]) {
75        self.transform(input, output, Transform::Fft);
76    }
77
78    fn ifft(&self, input: &[Complex<Self::Real>], output: &mut [Complex<Self::Real>]) {
80        self.transform(input, output, Transform::Ifft);
81    }
82}