argmin/core/math/
norm_vec.rs1use crate::core::math::ArgminNorm;
9use num::integer::Roots;
10use num_complex::Complex;
11
12macro_rules! make_norm_float {
13 ($t:ty) => {
14 impl ArgminNorm<$t> for Vec<$t> {
15 #[inline]
16 fn norm(&self) -> $t {
17 self.iter().map(|a| a.powi(2)).sum::<$t>().sqrt()
18 }
19 }
20 };
21}
22
23macro_rules! make_norm_complex_float {
24 ($t:ty) => {
25 impl ArgminNorm<Complex<$t>> for Vec<Complex<$t>> {
26 #[inline]
27 fn norm(&self) -> Complex<$t> {
28 self.iter().map(|a| a.powf(2.0)).sum::<Complex<$t>>().sqrt()
29 }
30 }
31 };
32}
33
34macro_rules! make_norm_integer {
35 ($t:ty) => {
36 impl ArgminNorm<$t> for Vec<$t> {
37 #[inline]
38 fn norm(&self) -> $t {
39 self.iter().map(|a| a.pow(2)).sum::<$t>().sqrt()
40 }
41 }
42 };
43}
44
45make_norm_integer!(isize);
46make_norm_integer!(usize);
47make_norm_integer!(i8);
48make_norm_integer!(i16);
49make_norm_integer!(i32);
50make_norm_integer!(i64);
51make_norm_integer!(u8);
52make_norm_integer!(u16);
53make_norm_integer!(u32);
54make_norm_integer!(u64);
55make_norm_float!(f32);
56make_norm_float!(f64);
57make_norm_complex_float!(f32);
58make_norm_complex_float!(f64);
59
60#[cfg(test)]
61mod tests {
62 use super::*;
63 use paste::item;
64
65 macro_rules! make_test {
66 ($t:ty) => {
67 item! {
68 #[test]
69 fn [<test_norm_ $t>]() {
70 let a = vec![4 as $t, 3 as $t];
71 let res = <Vec<$t> as ArgminNorm<$t>>::norm(&a);
72 let target = 5 as $t;
73 assert!(((target - res) as f64).abs() < std::f64::EPSILON);
74 }
75 }
76 };
77 }
78
79 macro_rules! make_test_signed {
80 ($t:ty) => {
81 item! {
82 #[test]
83 fn [<test_norm_signed_ $t>]() {
84 let a = vec![-4 as $t, -3 as $t];
85 let res = <Vec<$t> as ArgminNorm<$t>>::norm(&a);
86 let target = 5 as $t;
87 assert!(((target - res) as f64).abs() < std::f64::EPSILON);
88 }
89 }
90 };
91 }
92
93 make_test!(isize);
94 make_test!(usize);
95 make_test!(i8);
96 make_test!(u8);
97 make_test!(i16);
98 make_test!(u16);
99 make_test!(i32);
100 make_test!(u32);
101 make_test!(i64);
102 make_test!(u64);
103 make_test!(f32);
104 make_test!(f64);
105
106 make_test_signed!(isize);
107 make_test_signed!(i8);
108 make_test_signed!(i16);
109 make_test_signed!(i32);
110 make_test_signed!(i64);
111 make_test_signed!(f32);
112 make_test_signed!(f64);
113}