argmin_math/vec/
sub.rs

1// Copyright 2018-2024 argmin developers
2//
3// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
4// http://apache.org/licenses/LICENSE-2.0> or the MIT license <LICENSE-MIT or
5// http://opensource.org/licenses/MIT>, at your option. This file may not be
6// copied, modified, or distributed except according to those terms.
7
8use 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                // implicitly, or > 0
45                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}