1use crate::core::math::ArgminNorm;
9use num_complex::Complex;
10
11macro_rules! make_norm_unsigned {
12 ($t:ty) => {
13 impl ArgminNorm<$t> for $t {
14 #[inline]
15 fn norm(&self) -> $t {
16 *self
17 }
18 }
19 };
20}
21
22macro_rules! make_norm {
23 ($t:ty) => {
24 impl ArgminNorm<$t> for $t {
25 #[inline]
26 fn norm(&self) -> $t {
27 (*self).abs()
28 }
29 }
30 };
31}
32
33macro_rules! make_norm_complex {
34 ($t:ty) => {
35 impl ArgminNorm<$t> for Complex<$t> {
36 #[inline]
37 fn norm(&self) -> $t {
38 (*self).re.hypot((*self).im)
39 }
40 }
41 };
42}
43
44make_norm!(isize);
45make_norm_unsigned!(usize);
46make_norm!(i8);
47make_norm!(i16);
48make_norm!(i32);
49make_norm!(i64);
50make_norm_unsigned!(u8);
51make_norm_unsigned!(u16);
52make_norm_unsigned!(u32);
53make_norm_unsigned!(u64);
54make_norm!(f32);
55make_norm!(f64);
56
57make_norm_complex!(f32);
58make_norm_complex!(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 = 8 as $t;
71 let res = <$t as ArgminNorm<$t>>::norm(&a);
72 assert!(((a - res) as f64).abs() < std::f64::EPSILON);
73 }
74 }
75 };
76 }
77
78 macro_rules! make_test_signed {
79 ($t:ty) => {
80 item! {
81 #[test]
82 fn [<test_norm_signed_ $t>]() {
83 let a = -8 as $t;
84 let res = <$t as ArgminNorm<$t>>::norm(&a);
85 assert!(((8 as $t - res) as f64).abs() < std::f64::EPSILON);
86 }
87 }
88 };
89 }
90
91 make_test!(isize);
92 make_test!(usize);
93 make_test!(i8);
94 make_test!(u8);
95 make_test!(i16);
96 make_test!(u16);
97 make_test!(i32);
98 make_test!(u32);
99 make_test!(i64);
100 make_test!(u64);
101 make_test!(f32);
102 make_test!(f64);
103
104 make_test_signed!(isize);
105 make_test_signed!(i8);
106 make_test_signed!(i16);
107 make_test_signed!(i32);
108 make_test_signed!(i64);
109 make_test_signed!(f32);
110 make_test_signed!(f64);
111}