use crate::fractals::Complex;
use crate::transforms::fft::{fft_any, ifft_any, rfft};
#[must_use]
pub fn dft(signal: &[f64]) -> Vec<(f64, f64)> {
let buf: Vec<Complex> = signal.iter().map(|&x| Complex::new(x, 0.0)).collect();
fft_any(&buf).iter().map(|c| (c.re, c.im)).collect()
}
#[must_use]
pub fn inverse_dft(spectrum: &[(f64, f64)]) -> Vec<f64> {
let buf: Vec<Complex> = spectrum.iter().map(|&(re, im)| Complex::new(re, im)).collect();
ifft_any(&buf).iter().map(|c| c.re).collect()
}
#[must_use]
pub fn power_spectrum(signal: &[f64]) -> Vec<f64> {
let n = signal.len();
if n == 0 {
return Vec::new();
}
let half = rfft(signal);
let mut ps = vec![0.0; n];
for (k, c) in half.iter().enumerate() {
ps[k] = c.norm_sq();
if k > 0 && k < n - k {
ps[n - k] = ps[k]; }
}
ps
}
#[must_use]
pub fn dominant_frequency(signal: &[f64], sample_rate: f64) -> f64 {
let ps = power_spectrum(signal);
let n = ps.len();
let half = n / 2;
let k_max = (1..=half)
.max_by(|&a, &b| ps[a].partial_cmp(&ps[b]).unwrap_or(std::cmp::Ordering::Equal))
.unwrap_or(0);
k_max as f64 * sample_rate / n as f64
}