summaryrefslogtreecommitdiff
path: root/src/retain.rs
blob: bc3934a97499131cfe00d110ee3c0a2531e99f62 (plain)
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
use hashbrown::HashSet;
use num_complex::Complex;

#[inline(always)]
pub fn retain_top_n_magnitudes(fft_real_signal: &mut [Complex<f32>], n: usize) {
    // you'd be keeping the entire signal
    if n >= fft_real_signal.len() {
        return;
    }

    let mut indexed = fft_real_signal
        .iter()
        .copied()
        .enumerate()
        .collect::<Vec<(usize, Complex<f32>)>>();

    let target = fft_real_signal.len() - n;
    indexed.select_nth_unstable_by(target, |(_, c0), (_, c1)| c0.norm().total_cmp(&c1.norm()));

    let top_indices = indexed[target..]
        .iter()
        .map(|&(i, _)| i)
        .collect::<HashSet<usize>>();

    for (i, val) in fft_real_signal.iter_mut().enumerate() {
        if !top_indices.contains(&i) {
            *val = Complex::ZERO;
        }
    }
}