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
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
extern crate num_complex;
#[allow(non_camel_case_types)]
pub type cf32 = num_complex::Complex32;
#[macro_export]
macro_rules! assert_evm {
($actual:expr, $ref:expr) => {
assert_evm!($actual,$ref,-80.0)
};
($actual:expr, $ref:expr, $evm_limit_db:expr) => {
assert_eq!($actual.len(),$ref.len(), "Input slices/vectors must be same length");
for (idx, (act, re)) in $actual.iter().zip($ref).enumerate() {
let evm = (act - re).norm();
let limit = re.norm() * ($evm_limit_db / 10f32).powi(10);
if evm > limit {
let evm_db = evm.log10()*10f32;
panic!(
"EVM limit exceeded: Got {}({}dB) > limit {}({}dB) for element {}. Actual {}, Expected {}",
evm,evm_db,limit, $evm_limit_db, idx, act, re
);
}
}
};
}
#[macro_export]
macro_rules! vec_align {
[$init:expr; $len:expr] => {
unimplemented!()
}
}
pub mod vecops;
pub mod fft;
pub mod sampling;
pub mod sequence;
#[cfg(test)]
mod test {
use super::cf32;
#[test]
fn evm_correct() {
let refr = vec![
cf32::new(1f32, 0f32),
cf32::new(1f32, 0f32),
cf32::new(1f32, 0f32),
cf32::new(1f32, 0f32),
];
let act = vec![
cf32::new(1f32, 0f32),
cf32::new(1f32, 0f32),
cf32::new(1f32, 0f32),
cf32::new(0.9f32, 0f32),
];
assert_evm!(act, refr, (-10.0));
}
#[test]
#[should_panic]
fn evm_fail() {
let refr = vec![
cf32::new(1f32, 0f32),
cf32::new(1f32, 0f32),
cf32::new(1f32, 0f32),
cf32::new(1f32, 0f32),
];
let act = vec![
cf32::new(1f32, 0f32),
cf32::new(1f32, 0f32),
cf32::new(1f32, 0f32),
cf32::new(0.9f32, 0f32),
];
assert_evm!(act, refr, (0.0));
}
#[test]
fn vec_align() {
let _v = vec_align![cf32::default(); 2048];
}
}