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