1use crate::ArgminSub;
9use num_complex::Complex;
10
11macro_rules! make_sub {
12 ($t:ty) => {
13 impl ArgminSub<$t, Vec<$t>> for Vec<$t> {
14 #[inline]
15 fn sub(&self, other: &$t) -> Vec<$t> {
16 self.iter().map(|a| a - other).collect()
17 }
18 }
19
20 impl ArgminSub<Vec<$t>, Vec<$t>> for $t {
21 #[inline]
22 fn sub(&self, other: &Vec<$t>) -> Vec<$t> {
23 other.iter().map(|a| self - a).collect()
24 }
25 }
26
27 impl ArgminSub<Vec<$t>, Vec<$t>> for Vec<$t> {
28 #[inline]
29 fn sub(&self, other: &Vec<$t>) -> Vec<$t> {
30 let n1 = self.len();
31 let n2 = other.len();
32 assert!(n1 > 0);
33 assert_eq!(n1, n2);
34 self.iter().zip(other.iter()).map(|(a, b)| a - b).collect()
35 }
36 }
37
38 impl ArgminSub<Vec<Vec<$t>>, Vec<Vec<$t>>> for Vec<Vec<$t>> {
39 #[inline]
40 fn sub(&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 ArgminSub<Vec<$t>, Vec<$t>>>::sub(&a, &b)
53 })
54 .collect()
55 }
56 }
57
58 impl ArgminSub<$t, Vec<Vec<$t>>> for Vec<Vec<$t>> {
59 #[inline]
60 fn sub(&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 ArgminSub<$t, Vec<$t>>>::sub(&a, &other)
68 })
69 .collect()
70 }
71 }
72 };
73}
74
75make_sub!(i8);
76make_sub!(i16);
77make_sub!(i32);
78make_sub!(i64);
79make_sub!(u8);
80make_sub!(u16);
81make_sub!(u32);
82make_sub!(u64);
83make_sub!(f32);
84make_sub!(f64);
85make_sub!(Complex<i8>);
86make_sub!(Complex<i16>);
87make_sub!(Complex<i32>);
88make_sub!(Complex<i64>);
89make_sub!(Complex<u8>);
90make_sub!(Complex<u16>);
91make_sub!(Complex<u32>);
92make_sub!(Complex<u64>);
93make_sub!(Complex<f32>);
94make_sub!(Complex<f64>);
95
96#[cfg(test)]
97mod tests {
98 use super::*;
99 use approx::assert_relative_eq;
100 use paste::item;
101
102 macro_rules! make_test {
103 ($t:ty) => {
104 item! {
105 #[test]
106 fn [<test_sub_vec_scalar_ $t>]() {
107 let a = vec![100 as $t, 40 as $t, 76 as $t];
108 let b = 34 as $t;
109 let target = vec![66 as $t, 6 as $t, 42 as $t];
110 let res = <Vec<$t> as ArgminSub<$t, Vec<$t>>>::sub(&a, &b);
111 for i in 0..3 {
112 assert_relative_eq!(target[i] as f64, res[i] as f64, epsilon = f64::EPSILON);
113 }
114 }
115 }
116
117 item! {
118 #[test]
119 fn [<test_sub_vec_scalar_complex_ $t>]() {
120 let a = vec![
121 Complex::new(100 as $t, 40 as $t),
122 Complex::new(76 as $t, 42 as $t),
123 Complex::new(44 as $t, 35 as $t),
124 ];
125 let b = Complex::new(34 as $t, 12 as $t);
126 let target = vec![a[0] - b, a[1] - b, a[2] - b];
127 let res = <Vec<Complex<$t>> as ArgminSub<Complex<$t>, Vec<Complex<$t>>>>::sub(&a, &b);
128 for i in 0..3 {
129 assert_relative_eq!(target[i].re as f64, res[i].re as f64, epsilon = f64::EPSILON);
130 assert_relative_eq!(target[i].im as f64, res[i].im as f64, epsilon = f64::EPSILON);
131 }
132 }
133 }
134
135 item! {
136 #[test]
137 fn [<test_sub_scalar_vec_ $t>]() {
138 let a = vec![1 as $t, 4 as $t, 58 as $t];
139 let b = 100 as $t;
140 let target = vec![99 as $t, 96 as $t, 42 as $t];
141 let res = <$t as ArgminSub<Vec<$t>, Vec<$t>>>::sub(&b, &a);
142 for i in 0..3 {
143 assert_relative_eq!(target[i] as f64, res[i] as f64, epsilon = f64::EPSILON);
144 }
145 }
146 }
147
148 item! {
149 #[test]
150 fn [<test_sub_scalar_vec_complex_ $t>]() {
151 let a = vec![
152 Complex::new(1 as $t, 4 as $t),
153 Complex::new(12 as $t, 21 as $t),
154 Complex::new(6 as $t, 10 as $t)
155 ];
156 let b = Complex::new(100 as $t, 50 as $t);
157 let target = vec![b - a[0], b - a[1], b - a[2]];
158 let res = <Complex<$t> as ArgminSub<Vec<Complex<$t>>, Vec<Complex<$t>>>>::sub(&b, &a);
159 for i in 0..3 {
160 assert_relative_eq!(target[i].re as f64, res[i].re as f64, epsilon = f64::EPSILON);
161 assert_relative_eq!(target[i].im as f64, res[i].im as f64, epsilon = f64::EPSILON);
162 }
163 }
164 }
165
166 item! {
167 #[test]
168 fn [<test_sub_vec_vec_ $t>]() {
169 let a = vec![43 as $t, 46 as $t, 50 as $t];
170 let b = vec![1 as $t, 4 as $t, 8 as $t];
171 let target = vec![42 as $t, 42 as $t, 42 as $t];
172 let res = <Vec<$t> as ArgminSub<Vec<$t>, Vec<$t>>>::sub(&a, &b);
173 for i in 0..3 {
174 assert_relative_eq!(target[i] as f64, res[i] as f64, epsilon = f64::EPSILON);
175 }
176 }
177 }
178
179 item! {
180 #[test]
181 fn [<test_sub_vec_vec_complex_ $t>]() {
182 let a = vec![
183 Complex::new(100 as $t, 40 as $t),
184 Complex::new(76 as $t, 42 as $t),
185 Complex::new(44 as $t, 35 as $t),
186 ];
187 let b = vec![
188 Complex::new(1 as $t, 4 as $t),
189 Complex::new(12 as $t, 21 as $t),
190 Complex::new(6 as $t, 10 as $t)
191 ];
192 let target = vec![a[0] - b[0], a[1] - b[1], a[2] - b[2]];
193 let res = <Vec<Complex<$t>> as ArgminSub<Vec<Complex<$t>>, Vec<Complex<$t>>>>::sub(&a, &b);
194 for i in 0..3 {
195 assert_relative_eq!(target[i].re as f64, res[i].re as f64, epsilon = f64::EPSILON);
196 assert_relative_eq!(target[i].im as f64, res[i].im as f64, epsilon = f64::EPSILON);
197 }
198 }
199 }
200
201 item! {
202 #[test]
203 #[should_panic]
204 fn [<test_sub_vec_vec_panic_ $t>]() {
205 let a = vec![41 as $t, 38 as $t, 34 as $t];
206 let b = vec![1 as $t, 4 as $t];
207 <Vec<$t> as ArgminSub<Vec<$t>, Vec<$t>>>::sub(&a, &b);
208 }
209 }
210
211 item! {
212 #[test]
213 #[should_panic]
214 fn [<test_sub_vec_vec_panic_2_ $t>]() {
215 let a = vec![];
216 let b = vec![41 as $t, 38 as $t, 34 as $t];
217 <Vec<$t> as ArgminSub<Vec<$t>, Vec<$t>>>::sub(&a, &b);
218 }
219 }
220
221 item! {
222 #[test]
223 #[should_panic]
224 fn [<test_sub_vec_vec_panic_3_ $t>]() {
225 let a = vec![41 as $t, 38 as $t, 34 as $t];
226 let b = vec![];
227 <Vec<$t> as ArgminSub<Vec<$t>, Vec<$t>>>::sub(&a, &b);
228 }
229 }
230
231 item! {
232 #[test]
233 fn [<test_sub_mat_mat_ $t>]() {
234 let a = vec![
235 vec![43 as $t, 46 as $t, 50 as $t],
236 vec![44 as $t, 47 as $t, 51 as $t]
237 ];
238 let b = vec![
239 vec![1 as $t, 4 as $t, 8 as $t],
240 vec![2 as $t, 5 as $t, 9 as $t]
241 ];
242 let target = vec![
243 vec![42 as $t, 42 as $t, 42 as $t],
244 vec![42 as $t, 42 as $t, 42 as $t]
245 ];
246 let res = <Vec<Vec<$t>> as ArgminSub<Vec<Vec<$t>>, Vec<Vec<$t>>>>::sub(&a, &b);
247 for i in 0..3 {
248 for j in 0..2 {
249 assert_relative_eq!(target[j][i] as f64, res[j][i] as f64, epsilon = f64::EPSILON);
250 }
251 }
252 }
253 }
254
255 item! {
256 #[test]
257 fn [<test_sub_mat_mat_complex_ $t>]() {
258 let a = vec![
259 vec![Complex::new(100 as $t, 40 as $t), Complex::new(76 as $t, 42 as $t)],
260 vec![Complex::new(44 as $t, 30 as $t), Complex::new(56 as $t, 52 as $t)],
261 vec![Complex::new(64 as $t, 40 as $t), Complex::new(86 as $t, 72 as $t)],
262 ];
263 let b = vec![
264 vec![Complex::new(10 as $t, 4 as $t), Complex::new(7 as $t, 4 as $t)],
265 vec![Complex::new(4 as $t, 3 as $t), Complex::new(6 as $t, 5 as $t)],
266 vec![Complex::new(6 as $t, 4 as $t), Complex::new(8 as $t, 2 as $t)],
267 ];
268 let target = vec![
269 vec![a[0][0] - b[0][0], a[0][1] - b[0][1]],
270 vec![a[1][0] - b[1][0], a[1][1] - b[1][1]],
271 vec![a[2][0] - b[2][0], a[2][1] - b[2][1]],
272 ];
273 let res = <Vec<Vec<Complex<$t>>> as ArgminSub<Vec<Vec<Complex<$t>>>, Vec<Vec<Complex<$t>>>>>::sub(&a, &b);
274 for i in 0..2 {
275 for j in 0..3 {
276 assert_relative_eq!(target[j][i].re as f64, res[j][i].re as f64, epsilon = f64::EPSILON);
277 assert_relative_eq!(target[j][i].im as f64, res[j][i].im as f64, epsilon = f64::EPSILON);
278 }
279 }
280 }
281 }
282
283 item! {
284 #[test]
285 fn [<test_sub_mat_scalar_ $t>]() {
286 let a = vec![
287 vec![43 as $t, 46 as $t, 50 as $t],
288 vec![44 as $t, 47 as $t, 51 as $t]
289 ];
290 let b = 2 as $t;
291 let target = vec![
292 vec![41 as $t, 44 as $t, 48 as $t],
293 vec![42 as $t, 45 as $t, 49 as $t]
294 ];
295 let res = <Vec<Vec<$t>> as ArgminSub<$t, Vec<Vec<$t>>>>::sub(&a, &b);
296 for i in 0..3 {
297 for j in 0..2 {
298 assert_relative_eq!(target[j][i] as f64, res[j][i] as f64, epsilon = f64::EPSILON);
299 }
300 }
301 }
302 }
303
304 item! {
305 #[test]
306 fn [<test_sub_mat_scalar_complex_ $t>]() {
307 let a = vec![
308 vec![Complex::new(100 as $t, 40 as $t), Complex::new(76 as $t, 42 as $t)],
309 vec![Complex::new(44 as $t, 30 as $t), Complex::new(56 as $t, 52 as $t)],
310 vec![Complex::new(64 as $t, 40 as $t), Complex::new(86 as $t, 72 as $t)],
311 ];
312 let b = Complex::new(2 as $t, 14 as $t);
313 let target = vec![
314 vec![a[0][0] - b, a[0][1] - b],
315 vec![a[1][0] - b, a[1][1] - b],
316 vec![a[2][0] - b, a[2][1] - b],
317 ];
318 let res = <Vec<Vec<Complex<$t>>> as ArgminSub<Complex<$t>, Vec<Vec<Complex<$t>>>>>::sub(&a, &b);
319 for i in 0..2 {
320 for j in 0..3 {
321 assert_relative_eq!(target[j][i].re as f64, res[j][i].re as f64, epsilon = f64::EPSILON);
322 assert_relative_eq!(target[j][i].im as f64, res[j][i].im as f64, epsilon = f64::EPSILON);
323 }
324 }
325 }
326 }
327
328 item! {
329 #[test]
330 #[should_panic]
331 fn [<test_sub_mat_mat_panic_1_ $t>]() {
332 let a = vec![
333 vec![41 as $t, 38 as $t, 34 as $t],
334 vec![40 as $t, 37 as $t, 33 as $t]
335 ];
336 let b = vec![
337 vec![1 as $t, 4 as $t, 8 as $t],
338 vec![2 as $t, 9 as $t]
339 ];
340 <Vec<Vec<$t>> as ArgminSub<Vec<Vec<$t>>, Vec<Vec<$t>>>>::sub(&a, &b);
341 }
342 }
343
344 item! {
345 #[test]
346 #[should_panic]
347 fn [<test_sub_mat_mat_panic_2_ $t>]() {
348 let a = vec![
349 vec![41 as $t, 38 as $t, 34 as $t],
350 ];
351 let b = vec![
352 vec![1 as $t, 4 as $t, 8 as $t],
353 vec![2 as $t, 5 as $t, 9 as $t]
354 ];
355 <Vec<Vec<$t>> as ArgminSub<Vec<Vec<$t>>, Vec<Vec<$t>>>>::sub(&a, &b);
356 }
357 }
358
359 item! {
360 #[test]
361 #[should_panic]
362 fn [<test_sub_mat_mat_panic_3_ $t>]() {
363 let a = vec![
364 vec![1 as $t, 4 as $t, 8 as $t],
365 vec![2 as $t, 5 as $t, 9 as $t]
366 ];
367 let b = vec![];
368 <Vec<Vec<$t>> as ArgminSub<Vec<Vec<$t>>, Vec<Vec<$t>>>>::sub(&a, &b);
369 }
370 }
371 };
372 }
373
374 make_test!(i8);
375 make_test!(u8);
376 make_test!(i16);
377 make_test!(u16);
378 make_test!(i32);
379 make_test!(u32);
380 make_test!(i64);
381 make_test!(u64);
382 make_test!(f32);
383 make_test!(f64);
384}