1use crate::ArgminMul;
9use num_complex::Complex;
10
11macro_rules! make_mul {
12 ($t:ty) => {
13 impl ArgminMul<$t, Vec<$t>> for Vec<$t> {
14 #[inline]
15 fn mul(&self, other: &$t) -> Vec<$t> {
16 self.iter().map(|a| a * other).collect()
17 }
18 }
19
20 impl ArgminMul<Vec<$t>, Vec<$t>> for $t {
21 #[inline]
22 fn mul(&self, other: &Vec<$t>) -> Vec<$t> {
23 other.iter().map(|a| a * self).collect()
24 }
25 }
26
27 impl ArgminMul<Vec<$t>, Vec<$t>> for Vec<$t> {
28 #[inline]
29 fn mul(&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 ArgminMul<Vec<Vec<$t>>, Vec<Vec<$t>>> for Vec<Vec<$t>> {
40 #[inline]
41 fn mul(&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 ArgminMul<Vec<$t>, Vec<$t>>>::mul(&a, &b)
54 })
55 .collect()
56 }
57 }
58
59 impl ArgminMul<$t, Vec<Vec<$t>>> for Vec<Vec<$t>> {
60 #[inline]
61 fn mul(&self, other: &$t) -> Vec<Vec<$t>> {
62 self.iter().map(|a| a.mul(other)).collect()
63 }
64 }
65
66 impl ArgminMul<Vec<Vec<$t>>, Vec<Vec<$t>>> for $t {
67 #[inline]
68 fn mul(&self, other: &Vec<Vec<$t>>) -> Vec<Vec<$t>> {
69 other.iter().map(|a| a.mul(self)).collect()
70 }
71 }
72 };
73}
74
75make_mul!(i8);
76make_mul!(u8);
77make_mul!(i16);
78make_mul!(u16);
79make_mul!(i32);
80make_mul!(u32);
81make_mul!(i64);
82make_mul!(u64);
83make_mul!(f32);
84make_mul!(f64);
85make_mul!(Complex<i8>);
86make_mul!(Complex<u8>);
87make_mul!(Complex<i16>);
88make_mul!(Complex<u16>);
89make_mul!(Complex<i32>);
90make_mul!(Complex<u32>);
91make_mul!(Complex<i64>);
92make_mul!(Complex<u64>);
93make_mul!(Complex<f32>);
94make_mul!(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_mul_vec_scalar_ $t>]() {
107 let a = vec![1 as $t, 4 as $t, 8 as $t];
108 let b = 2 as $t;
109 let target = vec![2 as $t, 8 as $t, 16 as $t];
110 let res = <Vec<$t> as ArgminMul<$t, Vec<$t>>>::mul(&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_mul_vec_scalar_complex_ $t>]() {
120 let a = vec![
121 Complex::new(5 as $t, 3 as $t),
122 Complex::new(8 as $t, 2 as $t)
123 ];
124 let b = Complex::new(2 as $t, 3 as $t);
125 let target = vec![a[0] * b, a[1] * b];
126 let res = <Vec<Complex<$t>> as ArgminMul<Complex<$t>, Vec<Complex<$t>>>>::mul(&a, &b);
127 for i in 0..2 {
128 assert_relative_eq!(target[i].re as f64, res[i].re as f64, epsilon = f64::EPSILON);
129 assert_relative_eq!(target[i].im as f64, res[i].im as f64, epsilon = f64::EPSILON);
130 }
131 }
132 }
133
134 item! {
135 #[test]
136 fn [<test_mul_scalar_vec_ $t>]() {
137 let a = vec![1 as $t, 4 as $t, 8 as $t];
138 let b = 2 as $t;
139 let target = vec![2 as $t, 8 as $t, 16 as $t];
140 let res = <$t as ArgminMul<Vec<$t>, Vec<$t>>>::mul(&b, &a);
141 for i in 0..3 {
142 assert_relative_eq!(target[i] as f64, res[i] as f64, epsilon = f64::EPSILON);
143 }
144 }
145 }
146
147 item! {
148 #[test]
149 fn [<test_mul_scalar_vec_complex_ $t>]() {
150 let a = vec![
151 Complex::new(5 as $t, 3 as $t),
152 Complex::new(8 as $t, 2 as $t)
153 ];
154 let b = Complex::new(2 as $t, 3 as $t);
155 let target = vec![a[0] * b, a[1] * b];
156 let res = <Complex<$t> as ArgminMul<Vec<Complex<$t>>, Vec<Complex<$t>>>>::mul(&b, &a);
157 for i in 0..2 {
158 assert_relative_eq!(target[i].re as f64, res[i].re as f64, epsilon = f64::EPSILON);
159 assert_relative_eq!(target[i].im as f64, res[i].im as f64, epsilon = f64::EPSILON);
160 }
161 }
162 }
163
164 item! {
165 #[test]
166 fn [<test_mul_vec_vec_ $t>]() {
167 let a = vec![1 as $t, 4 as $t, 8 as $t];
168 let b = vec![2 as $t, 3 as $t, 4 as $t];
169 let target = vec![2 as $t, 12 as $t, 32 as $t];
170 let res = <Vec<$t> as ArgminMul<Vec<$t>, Vec<$t>>>::mul(&a, &b);
171 for i in 0..3 {
172 assert_relative_eq!(target[i] as f64, res[i] as f64, epsilon = f64::EPSILON);
173 }
174 }
175 }
176
177 item! {
178 #[test]
179 fn [<test_mul_vec_vec_complex_ $t>]() {
180 let a = vec![
181 Complex::new(5 as $t, 3 as $t),
182 Complex::new(8 as $t, 2 as $t)
183 ];
184 let b = vec![
185 Complex::new(2 as $t, 3 as $t),
186 Complex::new(1 as $t, 2 as $t)
187 ];
188 let target = vec![a[0]*b[0], a[1]*b[1]];
189 let res = <Vec<Complex<$t>> as ArgminMul<Vec<Complex<$t>>, Vec<Complex<$t>>>>::mul(&a, &b);
190 for i in 0..2 {
191 assert_relative_eq!(target[i].re as f64, res[i].re as f64, epsilon = f64::EPSILON);
192 assert_relative_eq!(target[i].im as f64, res[i].im as f64, epsilon = f64::EPSILON);
193 }
194 }
195 }
196
197 item! {
198 #[test]
199 #[should_panic]
200 fn [<test_mul_vec_vec_panic_ $t>]() {
201 let a = vec![1 as $t, 4 as $t];
202 let b = vec![41 as $t, 38 as $t, 34 as $t];
203 <Vec<$t> as ArgminMul<Vec<$t>, Vec<$t>>>::mul(&a, &b);
204 }
205 }
206
207 item! {
208 #[test]
209 #[should_panic]
210 fn [<test_mul_vec_vec_panic_2_ $t>]() {
211 let a = vec![];
212 let b = vec![41 as $t, 38 as $t, 34 as $t];
213 <Vec<$t> as ArgminMul<Vec<$t>, Vec<$t>>>::mul(&a, &b);
214 }
215 }
216
217 item! {
218 #[test]
219 #[should_panic]
220 fn [<test_mul_vec_vec_panic_3_ $t>]() {
221 let a = vec![41 as $t, 38 as $t, 34 as $t];
222 let b = vec![];
223 <Vec<$t> as ArgminMul<Vec<$t>, Vec<$t>>>::mul(&a, &b);
224 }
225 }
226
227 item! {
228 #[test]
229 fn [<test_mul_mat_mat_ $t>]() {
230 let a = vec![
231 vec![1 as $t, 4 as $t, 8 as $t],
232 vec![2 as $t, 5 as $t, 9 as $t]
233 ];
234 let b = vec![
235 vec![2 as $t, 3 as $t, 4 as $t],
236 vec![3 as $t, 4 as $t, 5 as $t]
237 ];
238 let target = vec![
239 vec![2 as $t, 12 as $t, 32 as $t],
240 vec![6 as $t, 20 as $t, 45 as $t]
241 ];
242 let res = <Vec<Vec<$t>> as ArgminMul<Vec<Vec<$t>>, Vec<Vec<$t>>>>::mul(&a, &b);
243 for i in 0..3 {
244 for j in 0..2 {
245 assert_relative_eq!(target[j][i] as f64, res[j][i] as f64, epsilon = f64::EPSILON);
246 }
247 }
248 }
249 }
250
251 item! {
252 #[test]
253 fn [<test_mul_mat_mat_complex_ $t>]() {
254 let a = vec![
255 vec![Complex::new(5 as $t, 3 as $t), Complex::new(8 as $t, 2 as $t)],
256 vec![Complex::new(4 as $t, 2 as $t), Complex::new(7 as $t, 1 as $t)],
257 vec![Complex::new(3 as $t, 1 as $t), Complex::new(6 as $t, 2 as $t)],
258 ];
259 let b = vec![
260 vec![Complex::new(5 as $t, 3 as $t), Complex::new(8 as $t, 2 as $t)],
261 vec![Complex::new(4 as $t, 2 as $t), Complex::new(7 as $t, 1 as $t)],
262 vec![Complex::new(3 as $t, 1 as $t), Complex::new(6 as $t, 2 as $t)],
263 ];
264 let target = vec![
265 vec![a[0][0] * b[0][0], a[0][1] * b[0][1]],
266 vec![a[1][0] * b[1][0], a[1][1] * b[1][1]],
267 vec![a[2][0] * b[2][0], a[2][1] * b[2][1]],
268 ];
269 let res = <Vec<Vec<Complex<$t>>> as ArgminMul<Vec<Vec<Complex<$t>>>, Vec<Vec<Complex<$t>>>>>::mul(&a, &b);
270 for i in 0..2 {
271 for j in 0..3 {
272 assert_relative_eq!(target[j][i].re as f64, res[j][i].re as f64, epsilon = f64::EPSILON);
273 assert_relative_eq!(target[j][i].im as f64, res[j][i].im as f64, epsilon = f64::EPSILON);
274 }
275 }
276 }
277 }
278
279 item! {
280 #[test]
281 #[should_panic]
282 fn [<test_mul_mat_mat_panic_1_ $t>]() {
283 let a = vec![
284 vec![1 as $t, 4 as $t, 8 as $t],
285 vec![2 as $t, 9 as $t]
286 ];
287 let b = vec![
288 vec![41 as $t, 38 as $t, 34 as $t],
289 vec![40 as $t, 37 as $t, 33 as $t]
290 ];
291 <Vec<Vec<$t>> as ArgminMul<Vec<Vec<$t>>, Vec<Vec<$t>>>>::mul(&a, &b);
292 }
293 }
294
295 item! {
296 #[test]
297 #[should_panic]
298 fn [<test_mul_mat_mat_panic_2_ $t>]() {
299 let a = vec![
300 vec![1 as $t, 4 as $t, 8 as $t],
301 vec![2 as $t, 5 as $t, 9 as $t]
302 ];
303 let b = vec![
304 vec![41 as $t, 38 as $t, 34 as $t],
305 ];
306 <Vec<Vec<$t>> as ArgminMul<Vec<Vec<$t>>, Vec<Vec<$t>>>>::mul(&a, &b);
307 }
308 }
309
310 item! {
311 #[test]
312 #[should_panic]
313 fn [<test_mul_mat_mat_panic_3_ $t>]() {
314 let a = vec![
315 vec![1 as $t, 4 as $t, 8 as $t],
316 vec![2 as $t, 5 as $t, 9 as $t]
317 ];
318 let b = vec![];
319 <Vec<Vec<$t>> as ArgminMul<Vec<Vec<$t>>, Vec<Vec<$t>>>>::mul(&a, &b);
320 }
321 }
322
323 item! {
324 #[test]
325 fn [<test_mul_scalar_mat_1_ $t>]() {
326 let a = vec![
327 vec![1 as $t, 4 as $t, 8 as $t],
328 vec![2 as $t, 5 as $t, 9 as $t]
329 ];
330 let b = 2 as $t;
331 let target = vec![
332 vec![2 as $t, 8 as $t, 16 as $t],
333 vec![4 as $t, 10 as $t, 18 as $t]
334 ];
335 let res = <Vec<Vec<$t>> as ArgminMul<$t, Vec<Vec<$t>>>>::mul(&a, &b);
336 for i in 0..3 {
337 for j in 0..2 {
338 assert_relative_eq!(target[j][i] as f64, res[j][i] as f64, epsilon = f64::EPSILON);
339 }
340 }
341 }
342 }
343
344 item! {
345 #[test]
346 fn [<test_mul_scalar_mat_1_complex_ $t>]() {
347 let a = vec![
348 vec![Complex::new(5 as $t, 3 as $t), Complex::new(8 as $t, 2 as $t)],
349 vec![Complex::new(4 as $t, 2 as $t), Complex::new(7 as $t, 1 as $t)],
350 vec![Complex::new(3 as $t, 1 as $t), Complex::new(6 as $t, 2 as $t)],
351 ];
352 let b = Complex::new(3 as $t, 2 as $t);
353 let target = vec![
354 vec![a[0][0] * b, a[0][1] * b],
355 vec![a[1][0] * b, a[1][1] * b],
356 vec![a[2][0] * b, a[2][1] * b],
357 ];
358 let res = <Vec<Vec<Complex<$t>>> as ArgminMul<Complex<$t>, Vec<Vec<Complex<$t>>>>>::mul(&a, &b);
359 for i in 0..2 {
360 for j in 0..3 {
361 assert_relative_eq!(target[j][i].re as f64, res[j][i].re as f64, epsilon = f64::EPSILON);
362 assert_relative_eq!(target[j][i].im as f64, res[j][i].im as f64, epsilon = f64::EPSILON);
363 }
364 }
365 }
366 }
367
368 item! {
369 #[test]
370 fn [<test_mul_scalar_mat_2_ $t>]() {
371 let b = vec![
372 vec![1 as $t, 4 as $t, 8 as $t],
373 vec![2 as $t, 5 as $t, 9 as $t]
374 ];
375 let a = 2 as $t;
376 let target = vec![
377 vec![2 as $t, 8 as $t, 16 as $t],
378 vec![4 as $t, 10 as $t, 18 as $t]
379 ];
380 let res = <$t as ArgminMul<Vec<Vec<$t>>, Vec<Vec<$t>>>>::mul(&a, &b);
381 for i in 0..3 {
382 for j in 0..2 {
383 assert_relative_eq!(target[j][i] as f64, res[j][i] as f64, epsilon = f64::EPSILON);
384 }
385 }
386 }
387 }
388
389 item! {
390 #[test]
391 fn [<test_mul_scalar_mat_2_complex_ $t>]() {
392 let a = vec![
393 vec![Complex::new(5 as $t, 3 as $t), Complex::new(8 as $t, 2 as $t)],
394 vec![Complex::new(4 as $t, 2 as $t), Complex::new(7 as $t, 1 as $t)],
395 vec![Complex::new(3 as $t, 1 as $t), Complex::new(6 as $t, 2 as $t)],
396 ];
397 let b = Complex::new(3 as $t, 2 as $t);
398 let target = vec![
399 vec![a[0][0] * b, a[0][1] * b],
400 vec![a[1][0] * b, a[1][1] * b],
401 vec![a[2][0] * b, a[2][1] * b],
402 ];
403 let res = <Complex<$t> as ArgminMul<Vec<Vec<Complex<$t>>>, Vec<Vec<Complex<$t>>>>>::mul(&b, &a);
404 for i in 0..2 {
405 for j in 0..3 {
406 assert_relative_eq!(target[j][i].re as f64, res[j][i].re as f64, epsilon = f64::EPSILON);
407 assert_relative_eq!(target[j][i].im as f64, res[j][i].im as f64, epsilon = f64::EPSILON);
408 }
409 }
410 }
411 }
412 };
413 }
414
415 make_test!(i8);
416 make_test!(u8);
417 make_test!(i16);
418 make_test!(u16);
419 make_test!(i32);
420 make_test!(u32);
421 make_test!(i64);
422 make_test!(u64);
423 make_test!(f32);
424 make_test!(f64);
425}