1use crate::ArgminAdd;
9
10macro_rules! make_add {
11 ($t:ty) => {
12 impl ArgminAdd<$t, Vec<$t>> for Vec<$t> {
13 #[inline]
14 fn add(&self, other: &$t) -> Vec<$t> {
15 self.iter().map(|a| a + other).collect()
16 }
17 }
18
19 impl ArgminAdd<Vec<$t>, Vec<$t>> for $t {
20 #[inline]
21 fn add(&self, other: &Vec<$t>) -> Vec<$t> {
22 other.iter().map(|a| a + self).collect()
23 }
24 }
25
26 impl ArgminAdd<Vec<$t>, Vec<$t>> for Vec<$t> {
27 #[inline]
28 fn add(&self, other: &Vec<$t>) -> Vec<$t> {
29 let n1 = self.len();
30 let n2 = other.len();
31 assert!(n1 > 0);
32 assert!(n2 > 0);
33 assert_eq!(n1, n2);
34 self.iter().zip(other.iter()).map(|(a, b)| a + b).collect()
35 }
36 }
37
38 impl ArgminAdd<Vec<Vec<$t>>, Vec<Vec<$t>>> for Vec<Vec<$t>> {
39 #[inline]
40 fn add(&self, other: &Vec<Vec<$t>>) -> Vec<Vec<$t>> {
41 let sr = self.len();
42 let or = other.len();
43 assert!(sr > 0);
44 assert_eq!(sr, or);
46 let sc = self[0].len();
47 self.iter()
48 .zip(other.iter())
49 .map(|(a, b)| {
50 assert_eq!(a.len(), sc);
51 assert_eq!(b.len(), sc);
52 <Vec<$t> as ArgminAdd<Vec<$t>, Vec<$t>>>::add(&a, &b)
53 })
54 .collect()
55 }
56 }
57
58 impl ArgminAdd<$t, Vec<Vec<$t>>> for Vec<Vec<$t>> {
59 #[inline]
60 fn add(&self, other: &$t) -> Vec<Vec<$t>> {
61 let sr = self.len();
62 assert!(sr > 0);
63 let sc = self[0].len();
64 self.iter()
65 .map(|a| {
66 assert_eq!(a.len(), sc);
67 <Vec<$t> as ArgminAdd<$t, Vec<$t>>>::add(&a, &other)
68 })
69 .collect()
70 }
71 }
72 };
73}
74
75make_add!(i8);
76make_add!(i16);
77make_add!(i32);
78make_add!(i64);
79make_add!(u8);
80make_add!(u16);
81make_add!(u32);
82make_add!(u64);
83make_add!(f32);
84make_add!(f64);
85
86#[cfg(test)]
87mod tests {
88 use super::*;
89 use approx::assert_relative_eq;
90 use paste::item;
91
92 macro_rules! make_test {
93 ($t:ty) => {
94 item! {
95 #[test]
96 fn [<test_add_vec_scalar_ $t>]() {
97 let a = vec![1 as $t, 4 as $t, 8 as $t];
98 let b = 34 as $t;
99 let target = vec![35 as $t, 38 as $t, 42 as $t];
100 let res = <Vec<$t> as ArgminAdd<$t, Vec<$t>>>::add(&a, &b);
101 for i in 0..3 {
102 assert_relative_eq!(target[i] as f64, res[i] as f64, epsilon = f64::EPSILON)
103 }
104 }
105 }
106
107 item! {
108 #[test]
109 fn [<test_add_scalar_vec_ $t>]() {
110 let a = vec![1 as $t, 4 as $t, 8 as $t];
111 let b = 34 as $t;
112 let target = vec![35 as $t, 38 as $t, 42 as $t];
113 let res = <$t as ArgminAdd<Vec<$t>, Vec<$t>>>::add(&b, &a);
114 for i in 0..3 {
115 assert_relative_eq!(target[i] as f64, res[i] as f64, epsilon = f64::EPSILON)
116 }
117 }
118 }
119
120 item! {
121 #[test]
122 fn [<test_add_vec_vec_ $t>]() {
123 let a = vec![1 as $t, 4 as $t, 8 as $t];
124 let b = vec![41 as $t, 38 as $t, 34 as $t];
125 let target = vec![42 as $t, 42 as $t, 42 as $t];
126 let res = <Vec<$t> as ArgminAdd<Vec<$t>, Vec<$t>>>::add(&a, &b);
127 for i in 0..3 {
128 assert_relative_eq!(target[i] as f64, res[i] as f64, epsilon = f64::EPSILON);
129 }
130 }
131 }
132
133 item! {
134 #[test]
135 #[should_panic]
136 fn [<test_add_vec_vec_panic_ $t>]() {
137 let a = vec![1 as $t, 4 as $t];
138 let b = vec![41 as $t, 38 as $t, 34 as $t];
139 <Vec<$t> as ArgminAdd<Vec<$t>, Vec<$t>>>::add(&a, &b);
140 }
141 }
142
143 item! {
144 #[test]
145 #[should_panic]
146 fn [<test_add_vec_vec_panic_2_ $t>]() {
147 let a = vec![];
148 let b = vec![41 as $t, 38 as $t, 34 as $t];
149 <Vec<$t> as ArgminAdd<Vec<$t>, Vec<$t>>>::add(&a, &b);
150 }
151 }
152
153 item! {
154 #[test]
155 #[should_panic]
156 fn [<test_add_vec_vec_panic_3_ $t>]() {
157 let a = vec![41 as $t, 38 as $t, 34 as $t];
158 let b = vec![];
159 <Vec<$t> as ArgminAdd<Vec<$t>, Vec<$t>>>::add(&a, &b);
160 }
161 }
162
163 item! {
164 #[test]
165 fn [<test_add_mat_mat_ $t>]() {
166 let a = vec![
167 vec![1 as $t, 4 as $t, 8 as $t],
168 vec![2 as $t, 5 as $t, 9 as $t]
169 ];
170 let b = vec![
171 vec![41 as $t, 38 as $t, 34 as $t],
172 vec![40 as $t, 37 as $t, 33 as $t]
173 ];
174 let target = vec![
175 vec![42 as $t, 42 as $t, 42 as $t],
176 vec![42 as $t, 42 as $t, 42 as $t]
177 ];
178 let res = <Vec<Vec<$t>> as ArgminAdd<Vec<Vec<$t>>, Vec<Vec<$t>>>>::add(&a, &b);
179 for i in 0..3 {
180 for j in 0..2 {
181 assert_relative_eq!(target[j][i] as f64, res[j][i] as f64, epsilon = f64::EPSILON);
182 }
183 }
184 }
185 }
186
187 item! {
188 #[test]
189 fn [<test_add_mat_scalar_ $t>]() {
190 let a = vec![
191 vec![1 as $t, 4 as $t, 8 as $t],
192 vec![2 as $t, 5 as $t, 9 as $t]
193 ];
194 let b = 2 as $t;
195 let target = vec![
196 vec![3 as $t, 6 as $t, 10 as $t],
197 vec![4 as $t, 7 as $t, 11 as $t]
198 ];
199 let res = <Vec<Vec<$t>> as ArgminAdd<$t, Vec<Vec<$t>>>>::add(&a, &b);
200 for i in 0..3 {
201 for j in 0..2 {
202 assert_relative_eq!(target[j][i] as f64, res[j][i] as f64, epsilon = f64::EPSILON);
203 }
204 }
205 }
206 }
207
208 item! {
209 #[test]
210 #[should_panic]
211 fn [<test_add_mat_mat_panic_1_ $t>]() {
212 let a = vec![
213 vec![1 as $t, 4 as $t, 8 as $t],
214 vec![2 as $t, 9 as $t]
215 ];
216 let b = vec![
217 vec![41 as $t, 38 as $t, 34 as $t],
218 vec![40 as $t, 37 as $t, 33 as $t]
219 ];
220 <Vec<Vec<$t>> as ArgminAdd<Vec<Vec<$t>>, Vec<Vec<$t>>>>::add(&a, &b);
221 }
222 }
223
224 item! {
225 #[test]
226 #[should_panic]
227 fn [<test_add_mat_mat_panic_2_ $t>]() {
228 let a = vec![
229 vec![1 as $t, 4 as $t, 8 as $t],
230 vec![2 as $t, 5 as $t, 9 as $t]
231 ];
232 let b = vec![
233 vec![41 as $t, 38 as $t, 34 as $t],
234 ];
235 <Vec<Vec<$t>> as ArgminAdd<Vec<Vec<$t>>, Vec<Vec<$t>>>>::add(&a, &b);
236 }
237 }
238
239 item! {
240 #[test]
241 #[should_panic]
242 fn [<test_add_mat_mat_panic_3_ $t>]() {
243 let a = vec![
244 vec![1 as $t, 4 as $t, 8 as $t],
245 vec![2 as $t, 5 as $t, 9 as $t]
246 ];
247 let b = vec![];
248 <Vec<Vec<$t>> as ArgminAdd<Vec<Vec<$t>>, Vec<Vec<$t>>>>::add(&a, &b);
249 }
250 }
251 };
252 }
253
254 make_test!(i8);
255 make_test!(u8);
256 make_test!(i16);
257 make_test!(u16);
258 make_test!(i32);
259 make_test!(u32);
260 make_test!(i64);
261 make_test!(u64);
262 make_test!(f32);
263 make_test!(f64);
264}