1use crate::core::math::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!(n2 > 0);
34 assert_eq!(n1, n2);
35 self.iter().zip(other.iter()).map(|(a, b)| a - b).collect()
36 }
37 }
38
39 impl ArgminSub<Vec<Vec<$t>>, Vec<Vec<$t>>> for Vec<Vec<$t>> {
40 #[inline]
41 fn sub(&self, other: &Vec<Vec<$t>>) -> Vec<Vec<$t>> {
42 let sr = self.len();
43 let or = other.len();
44 assert!(sr > 0);
45 assert_eq!(sr, or);
47 let sc = self[0].len();
48 self.iter()
49 .zip(other.iter())
50 .map(|(a, b)| {
51 assert_eq!(a.len(), sc);
52 assert_eq!(b.len(), sc);
53 <Vec<$t> as ArgminSub<Vec<$t>, Vec<$t>>>::sub(&a, &b)
54 })
55 .collect()
56 }
57 }
58
59 impl ArgminSub<$t, Vec<Vec<$t>>> for Vec<Vec<$t>> {
60 #[inline]
61 fn sub(&self, other: &$t) -> Vec<Vec<$t>> {
62 let sr = self.len();
63 assert!(sr > 0);
64 let sc = self[0].len();
65 self.iter()
66 .map(|a| {
67 assert_eq!(a.len(), sc);
68 <Vec<$t> as ArgminSub<$t, Vec<$t>>>::sub(&a, &other)
69 })
70 .collect()
71 }
72 }
73 };
74}
75
76make_sub!(isize);
77make_sub!(usize);
78make_sub!(i8);
79make_sub!(i16);
80make_sub!(i32);
81make_sub!(i64);
82make_sub!(u8);
83make_sub!(u16);
84make_sub!(u32);
85make_sub!(u64);
86make_sub!(f32);
87make_sub!(f64);
88make_sub!(Complex<isize>);
89make_sub!(Complex<usize>);
90make_sub!(Complex<i8>);
91make_sub!(Complex<i16>);
92make_sub!(Complex<i32>);
93make_sub!(Complex<i64>);
94make_sub!(Complex<u8>);
95make_sub!(Complex<u16>);
96make_sub!(Complex<u32>);
97make_sub!(Complex<u64>);
98make_sub!(Complex<f32>);
99make_sub!(Complex<f64>);
100
101#[cfg(test)]
102mod tests {
103 use super::*;
104 use paste::item;
105
106 macro_rules! make_test {
107 ($t:ty) => {
108 item! {
109 #[test]
110 fn [<test_sub_vec_scalar_ $t>]() {
111 let a = vec![100 as $t, 40 as $t, 76 as $t];
112 let b = 34 as $t;
113 let target = vec![66 as $t, 6 as $t, 42 as $t];
114 let res = <Vec<$t> as ArgminSub<$t, Vec<$t>>>::sub(&a, &b);
115 for i in 0..3 {
116 assert!(((target[i] - res[i]) as f64).abs() < std::f64::EPSILON);
117 }
118 }
119 }
120
121 item! {
122 #[test]
123 fn [<test_sub_scalar_vec_ $t>]() {
124 let a = vec![1 as $t, 4 as $t, 58 as $t];
125 let b = 100 as $t;
126 let target = vec![99 as $t, 96 as $t, 42 as $t];
127 let res = <$t as ArgminSub<Vec<$t>, Vec<$t>>>::sub(&b, &a);
128 for i in 0..3 {
129 assert!(((target[i] - res[i]) as f64).abs() < std::f64::EPSILON);
130 }
131 }
132 }
133
134 item! {
135 #[test]
136 fn [<test_sub_vec_vec_ $t>]() {
137 let a = vec![43 as $t, 46 as $t, 50 as $t];
138 let b = vec![1 as $t, 4 as $t, 8 as $t];
139 let target = vec![42 as $t, 42 as $t, 42 as $t];
140 let res = <Vec<$t> as ArgminSub<Vec<$t>, Vec<$t>>>::sub(&a, &b);
141 for i in 0..3 {
142 assert!(((target[i] - res[i]) as f64).abs() < std::f64::EPSILON);
143 }
144 }
145 }
146
147 item! {
148 #[test]
149 #[should_panic]
150 fn [<test_sub_vec_vec_panic_ $t>]() {
151 let a = vec![41 as $t, 38 as $t, 34 as $t];
152 let b = vec![1 as $t, 4 as $t];
153 <Vec<$t> as ArgminSub<Vec<$t>, Vec<$t>>>::sub(&a, &b);
154 }
155 }
156
157 item! {
158 #[test]
159 #[should_panic]
160 fn [<test_sub_vec_vec_panic_2_ $t>]() {
161 let a = vec![];
162 let b = vec![41 as $t, 38 as $t, 34 as $t];
163 <Vec<$t> as ArgminSub<Vec<$t>, Vec<$t>>>::sub(&a, &b);
164 }
165 }
166
167 item! {
168 #[test]
169 #[should_panic]
170 fn [<test_sub_vec_vec_panic_3_ $t>]() {
171 let a = vec![41 as $t, 38 as $t, 34 as $t];
172 let b = vec![];
173 <Vec<$t> as ArgminSub<Vec<$t>, Vec<$t>>>::sub(&a, &b);
174 }
175 }
176
177 item! {
178 #[test]
179 fn [<test_sub_mat_mat_ $t>]() {
180 let a = vec![
181 vec![43 as $t, 46 as $t, 50 as $t],
182 vec![44 as $t, 47 as $t, 51 as $t]
183 ];
184 let b = vec![
185 vec![1 as $t, 4 as $t, 8 as $t],
186 vec![2 as $t, 5 as $t, 9 as $t]
187 ];
188 let target = vec![
189 vec![42 as $t, 42 as $t, 42 as $t],
190 vec![42 as $t, 42 as $t, 42 as $t]
191 ];
192 let res = <Vec<Vec<$t>> as ArgminSub<Vec<Vec<$t>>, Vec<Vec<$t>>>>::sub(&a, &b);
193 for i in 0..3 {
194 for j in 0..2 {
195 assert!(((target[j][i] - res[j][i]) as f64).abs() < std::f64::EPSILON);
196 }
197 }
198 }
199 }
200
201 item! {
202 #[test]
203 fn [<test_sub_mat_scalar_ $t>]() {
204 let a = vec![
205 vec![43 as $t, 46 as $t, 50 as $t],
206 vec![44 as $t, 47 as $t, 51 as $t]
207 ];
208 let b = 2 as $t;
209 let target = vec![
210 vec![41 as $t, 44 as $t, 48 as $t],
211 vec![42 as $t, 45 as $t, 49 as $t]
212 ];
213 let res = <Vec<Vec<$t>> as ArgminSub<$t, Vec<Vec<$t>>>>::sub(&a, &b);
214 for i in 0..3 {
215 for j in 0..2 {
216 assert!(((target[j][i] - res[j][i]) as f64).abs() < std::f64::EPSILON);
217 }
218 }
219 }
220 }
221
222 item! {
223 #[test]
224 #[should_panic]
225 fn [<test_sub_mat_mat_panic_1_ $t>]() {
226 let a = vec![
227 vec![41 as $t, 38 as $t, 34 as $t],
228 vec![40 as $t, 37 as $t, 33 as $t]
229 ];
230 let b = vec![
231 vec![1 as $t, 4 as $t, 8 as $t],
232 vec![2 as $t, 9 as $t]
233 ];
234 <Vec<Vec<$t>> as ArgminSub<Vec<Vec<$t>>, Vec<Vec<$t>>>>::sub(&a, &b);
235 }
236 }
237
238 item! {
239 #[test]
240 #[should_panic]
241 fn [<test_sub_mat_mat_panic_2_ $t>]() {
242 let a = vec![
243 vec![41 as $t, 38 as $t, 34 as $t],
244 ];
245 let b = vec![
246 vec![1 as $t, 4 as $t, 8 as $t],
247 vec![2 as $t, 5 as $t, 9 as $t]
248 ];
249 <Vec<Vec<$t>> as ArgminSub<Vec<Vec<$t>>, Vec<Vec<$t>>>>::sub(&a, &b);
250 }
251 }
252
253 item! {
254 #[test]
255 #[should_panic]
256 fn [<test_sub_mat_mat_panic_3_ $t>]() {
257 let a = vec![
258 vec![1 as $t, 4 as $t, 8 as $t],
259 vec![2 as $t, 5 as $t, 9 as $t]
260 ];
261 let b = vec![];
262 <Vec<Vec<$t>> as ArgminSub<Vec<Vec<$t>>, Vec<Vec<$t>>>>::sub(&a, &b);
263 }
264 }
265 };
266 }
267
268 make_test!(isize);
269 make_test!(usize);
270 make_test!(i8);
271 make_test!(u8);
272 make_test!(i16);
273 make_test!(u16);
274 make_test!(i32);
275 make_test!(u32);
276 make_test!(i64);
277 make_test!(u64);
278 make_test!(f32);
279 make_test!(f64);
280}