1extern crate num;
2
3use num::Complex;
4use std::f64::consts::{PI, E};
5
6fn intermediate_filter(input: &Vec<f64>, angular_freq: &f64) -> Vec<f64> {
8 let freq_term = 2.0 * angular_freq.cos();
9
10 let mut intermediate_vec: Vec<f64> =
12 Vec::with_capacity(input.len());
13
14 intermediate_vec.push(input[0]);
16 intermediate_vec.push(input[1] + freq_term * input[0]);
17
18 for (ind, val) in input.iter().enumerate().skip(2) {
19 let filter_term = val + freq_term * intermediate_vec[ind - 1] -
20 intermediate_vec[ind - 2];
21 intermediate_vec.push(filter_term);
22 }
23
24 intermediate_vec
25}
26
27pub fn filter_naive(input: &Vec<f64>,
29 linear_freq: f64) -> Vec<Complex<f64>> {
30 let angular_freq = linear_freq / 2.0 / PI;
31
32 let intermediate_vec = intermediate_filter(&input, &angular_freq);
33
34 let mut output_vec: Vec<Complex<f64>> =
36 Vec::with_capacity(input.len());
37
38 output_vec.push(Complex::from(intermediate_vec[0]));
40
41 let exponential_term = (- Complex::i() * angular_freq).expf(E);
43
44 for (ind, val) in intermediate_vec.iter().enumerate().skip(1) {
45 output_vec.push(val - exponential_term * intermediate_vec[ind - 1]);
46 }
47
48 output_vec
49}
50
51fn bin_freq(linear_freq: f64, signal_length: usize) -> (usize, f64) {
52 let signal_len = signal_length as f64;
53
54 let angular_freq = linear_freq / 2.0 / PI;
55
56 let approx_bin_num = angular_freq * &signal_len / 2.0 / PI;
57 let bin_num: usize = (approx_bin_num) as usize;
58 let bin_freq = bin_num as f64 / &signal_len * 2.0 * PI;
59
60 if approx_bin_num != bin_num as f64 {
61 println!("Warning: aliasing frequency to {} to fit in bin...",
62 &bin_freq * 2.0 * PI);
63 }
64
65 (bin_num, bin_freq)
66}
67
68pub fn dft(input: &Vec<f64>, linear_freq: f64) -> Complex<f64> {
70 let bin_freq = bin_freq(linear_freq, input.len()).1;
72
73 let mut intermediate_vec = intermediate_filter(&input, &bin_freq);
74 intermediate_vec.pop();
75
76 let exponential_term = (Complex::i() * bin_freq).expf(E);
78
79 exponential_term * Complex::from(intermediate_vec.pop().unwrap()) -
80 Complex::from(intermediate_vec.pop().unwrap())
81}
82
83pub fn dft_power(input: &Vec<f64>, linear_freq: f64) -> f64 {
85 let bin_freq = bin_freq(linear_freq, input.len()).1;
87
88 let mut intermediate_vec = intermediate_filter(&input, &bin_freq);
90 intermediate_vec.pop();
91
92 let state_1 = intermediate_vec.pop().unwrap();
94 let state_2 = intermediate_vec.pop().unwrap();
96
97 state_1.powi(2) + state_2.powi(2) - 2.0 * bin_freq.cos() * state_1 * state_2
98}