argmin_math/primitives/
l2norm.rs1use crate::ArgminL2Norm;
9use num_complex::Complex;
10
11macro_rules! make_norm_unsigned {
12 ($t:ty) => {
13 impl ArgminL2Norm<$t> for $t {
14 #[inline]
15 fn l2_norm(&self) -> $t {
16 *self
17 }
18 }
19 };
20}
21
22macro_rules! make_norm {
23 ($t:ty) => {
24 impl ArgminL2Norm<$t> for $t {
25 #[inline]
26 fn l2_norm(&self) -> $t {
27 (*self).abs()
28 }
29 }
30 };
31}
32
33macro_rules! make_norm_complex {
34 ($t:ty) => {
35 impl ArgminL2Norm<$t> for Complex<$t> {
36 #[inline]
37 fn l2_norm(&self) -> $t {
38 (*self).re.hypot((*self).im)
39 }
40 }
41 };
42}
43
44make_norm!(i8);
45make_norm!(i16);
46make_norm!(i32);
47make_norm!(i64);
48make_norm_unsigned!(u8);
49make_norm_unsigned!(u16);
50make_norm_unsigned!(u32);
51make_norm_unsigned!(u64);
52make_norm!(f32);
53make_norm!(f64);
54
55make_norm_complex!(f32);
56make_norm_complex!(f64);
57
58#[cfg(test)]
59mod tests {
60 use super::*;
61 use approx::assert_relative_eq;
62 use paste::item;
63
64 macro_rules! make_test {
65 ($t:ty) => {
66 item! {
67 #[test]
68 fn [<test_norm_ $t>]() {
69 let a = 8 as $t;
70 let res = <$t as ArgminL2Norm<$t>>::l2_norm(&a);
71 assert_relative_eq!(a as f64, res as f64, epsilon = f64::EPSILON);
72 }
73 }
74 };
75 }
76
77 macro_rules! make_test_signed {
78 ($t:ty) => {
79 item! {
80 #[test]
81 fn [<test_norm_signed_ $t>]() {
82 let a = -8 as $t;
83 let res = <$t as ArgminL2Norm<$t>>::l2_norm(&a);
84 assert_relative_eq!(8 as f64, res as f64, epsilon = f64::EPSILON);
85 }
86 }
87 };
88 }
89
90 macro_rules! make_test_complex {
91 ($t:ty) => {
92 item! {
93 #[test]
94 fn [<test_norm_complex_ $t>]() {
95 let a = Complex::new(8 as $t, 4 as $t);
96 let res = <Complex<$t> as ArgminL2Norm<$t>>::l2_norm(&a);
97 assert_relative_eq!((a.re.powi(2) + a.im.powi(2)).sqrt() as f64, res as f64, epsilon = f64::EPSILON);
98 }
99 }
100 };
101 }
102
103 macro_rules! make_test_complex_signed {
104 ($t:ty) => {
105 item! {
106 #[test]
107 fn [<test_norm_complex_signed_ $t>]() {
108 let a = Complex::new(-8 as $t, -4 as $t);
109 let res = <Complex<$t> as ArgminL2Norm<$t>>::l2_norm(&a);
110 assert_relative_eq!((a.re.powi(2)+a.im.powi(2)).sqrt() as f64, res as f64, epsilon = f64::EPSILON);
111 }
112 }
113 };
114 }
115
116 make_test!(i8);
117 make_test!(u8);
118 make_test!(i16);
119 make_test!(u16);
120 make_test!(i32);
121 make_test!(u32);
122 make_test!(i64);
123 make_test!(u64);
124 make_test!(f32);
125 make_test!(f64);
126
127 make_test_signed!(i8);
128 make_test_signed!(i16);
129 make_test_signed!(i32);
130 make_test_signed!(i64);
131 make_test_signed!(f32);
132 make_test_signed!(f64);
133
134 make_test_complex!(f32);
135 make_test_complex!(f64);
136
137 make_test_complex_signed!(f32);
138 make_test_complex_signed!(f64);
139}