extern crate basic_dsp; extern crate num; extern crate rand; pub mod tools; mod time_freq_test { use crate::tools::*; use basic_dsp::window_functions::*; use basic_dsp::*; use num::complex::*; use std::f64::consts::PI; #[test] fn complex_plain_fft_plain_ifft_vector32_large() { for iteration in 0..3 { let a = create_data_even(201511212, iteration, 10001, 20000); let points = (a.len() / 2) as f32; let delta = create_delta(3561159, iteration); let mut buffer = SingleBuffer::new(); let mut vector = a.clone().to_complex_time_vec_par(); vector.set_delta(delta); let mut freq = vector.plain_fft(&mut buffer); freq.scale(Complex32::new(1.0 / points, 0.0)); let result = freq.plain_ifft(&mut buffer); assert_vector_eq_with_reason_and_tolerance( &a, result.data(..), 1e-4, "IFFT must invert FFT", ); assert_eq!(result.is_complex(), true); } } #[test] fn window_real_vs_complex_vector64() { let mut vector = new_sinusoid_vector(); let mut complex = vector.clone().to_complex().unwrap(); complex.apply_window(&HammingWindow::default()); let real = complex.to_real(); vector.apply_window(&HammingWindow::default()); assert_eq!(real.data(..), vector.data(..)); } #[test] fn fft_vector64() { let vector = new_sinusoid_vector(); let mut buffer = SingleBuffer::new(); let complex = vector.clone().to_complex().unwrap(); let freq = complex.fft(&mut buffer); let result = freq.magnitude(); // Expected data has been created with GNU Octave let expected: &[f64] = &[ 0.9292870138334854, 0.9306635099648193, 0.9348162621613968, 0.9418153274362542, 0.9517810621190216, 0.9648895430587848, 0.9813809812325847, 1.0015726905449405, 1.0258730936123666, 1.0548108445331859, 1.0890644245480268, 1.1295083134069603, 1.1772879726812928, 1.2339182289598294, 1.301437989279902, 1.3826534754026867, 1.4815340275011206, 1.6038793282853527, 1.7585157812279568, 1.9595783851339075, 2.2312382613655144, 2.6185925930596348, 3.2167138068850805, 4.266740801517487, 6.612395930080317, 16.722094841103452, 23.622177170007486, 6.303697095969605, 3.404295797341746, 2.210968575749469, 1.5819040732615888, 1.246194569535693, 1.1367683431144981, 1.2461951854260518, 1.581903667468762, 2.210968517938972, 3.40429586037563, 6.303698000270388, 23.622176749343343, 16.722094721382852, 6.612395731182459, 4.266740005002631, 3.216713364304185, 2.618592497323997, 2.23123801189946, 1.9595783052844522, 1.7585159098930296, 1.6038802182584422, 1.4815339648659298, 1.3826531545500815, 1.3014374693633786, 1.2339180461884898, 1.177287968900429, 1.1295077116182717, 1.0890636132326164, 1.0548115826822455, 1.0258732601724936, 1.0015721588901556, 0.9813817215431422, 0.9648899510832059, 0.951781283968659, 0.9418152796531379, 0.9348164516683282, 0.9306639008658044, ]; assert_vector_eq(&expected, result.data(..)); } #[test] fn windowed_fft_vector64() { let vector = new_sinusoid_vector(); let mut buffer = SingleBuffer::new(); let complex = vector.clone().to_complex().unwrap(); let freq = complex.windowed_fft(&mut buffer, &HammingWindow::default()); let result = freq.magnitude(); // Expected data has been created with GNU Octave let expected: &[f64] = &[ 0.07411808515197066, 0.07422272322333621, 0.07453841468679659, 0.07506988195440296, 0.07582541343880053, 0.07681696328361777, 0.07806061998281554, 0.07957802869766938, 0.08139483126598358, 0.08354572044699357, 0.0860733404576818, 0.08902894849492062, 0.09248035198400738, 0.09650916590034163, 0.10121825314935218, 0.10673436981991158, 0.11320884208865986, 0.12081079743775351, 0.12968456814874033, 0.13980104112377398, 0.15043320855074566, 0.15812824378762533, 0.14734167412188875, 0.04249205387030338, 1.3969045117052756, 12.846276122172032, 14.9883680193849, 2.9493349550502477, 0.12854704555683252, 0.07502029346769173, 0.08639361740278063, 0.08219267572562121, 0.07964010102931768, 0.0821927994000342, 0.08639332990145131, 0.07502038796334394, 0.12854702502866483, 2.9493345269345794, 14.988367552410944, 12.846276615795297, 1.3969044843995686, 0.04249183333909037, 0.14734154414942854, 0.15812800570779315, 0.1504332002895389, 0.13980122658303065, 0.12968464820669545, 0.12081166709283893, 0.11320883727454012, 0.10673405922210086, 0.10121809170575471, 0.09650909536592596, 0.09248034765427705, 0.08902919211450319, 0.08607303669204663, 0.08354618763280168, 0.08139478829605633, 0.07957758721938324, 0.07806104687040545, 0.07681675159617712, 0.07582540168807066, 0.0750699488332293, 0.07453849632122858, 0.07422306880326296, ]; assert_vector_eq(&expected, result.data(..)); } #[test] fn fft_ifft_vector64() { let vector = new_sinusoid_vector(); let mut buffer = SingleBuffer::new(); let complex = vector.clone().to_complex().unwrap(); let fft = complex.fft(&mut buffer); let ifft = fft.ifft(&mut buffer).to_real(); assert_vector_eq(vector.data(..), ifft.data(..)); } #[test] fn windowed_fft_windowed_ifft_vector64() { let vector = new_sinusoid_vector(); let mut buffer = SingleBuffer::new(); let complex = vector.clone().to_complex().unwrap(); let fft = complex.windowed_fft(&mut buffer, &HammingWindow::default()); let ifft = fft .windowed_ifft(&mut buffer, &HammingWindow::default()) .to_real(); assert_vector_eq(vector.data(..), ifft.data(..)); } fn new_sinusoid_vector() -> RealTimeVec64 { let n: usize = 64; let f = 0.1; let phi = 0.25; let range: Vec<_> = (0..n).map(|v| (v as f64) * f).collect(); let mut vector = range.to_real_time_vec_par(); vector.scale(2.0 * PI); vector.offset(phi); vector.cos(); vector } #[test] fn complex_fft_ifft_vector32_large() { for iteration in 0..3 { let a = create_data_even(201511212, iteration, 10001, 20000); let delta = create_delta(3561159, iteration); let mut vector = a.clone().to_complex_time_vec_par(); vector.set_delta(delta); let mut buffer = SingleBuffer::new(); let freq = vector.fft(&mut buffer); let result = freq.ifft(&mut buffer); assert_vector_eq_with_reason_and_tolerance( &a, result.data(..), 1e-4, "IFFT must invert FFT", ); assert_eq!(result.is_complex(), true); } } }