gpu_fft/psd.rs
1/// Computes the Power Spectral Density (PSD) from the real and imaginary components of a DFT.
2///
3/// Each bin's power is `(real² + imag²) / n`, where `n` is the number of bins.
4///
5/// For a real-valued input signal the DFT is conjugate-symmetric, so the upper half of the
6/// spectrum is a mirror of the lower half. Pass only the first `n/2 + 1` bins to obtain the
7/// **one-sided** PSD (recommended); pass all `n` bins for the full two-sided PSD.
8///
9/// # Parameters
10///
11/// - `real`: Real parts of the DFT output.
12/// - `imag`: Imaginary parts of the DFT output.
13///
14/// # Returns
15///
16/// A vector of PSD values with the same length as the inputs.
17///
18/// # Example
19///
20/// ```
21/// # use gpu_fft::psd::psd;
22/// let real = vec![1.0f32, 0.0, 0.0, 0.0];
23/// let imag = vec![0.0f32, 0.0, 0.0, 0.0];
24/// let psd_values = psd(&real, &imag);
25/// assert_eq!(psd_values.len(), 4);
26/// ```
27#[must_use]
28pub fn psd(real: &[f32], imag: &[f32]) -> Vec<f32> {
29 assert_eq!(real.len(), imag.len(), "real and imag must have the same length");
30 let n = real.len() as f32;
31 real.iter()
32 .zip(imag)
33 // power = real² + imag² (sqrt then square is a no-op, removed)
34 .map(|(&r, &im)| (r * r + im * im) / n)
35 .collect()
36}