1use crate::core::math::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!(isize);
76make_mul!(usize);
77make_mul!(i8);
78make_mul!(u8);
79make_mul!(i16);
80make_mul!(u16);
81make_mul!(i32);
82make_mul!(u32);
83make_mul!(i64);
84make_mul!(u64);
85make_mul!(f32);
86make_mul!(f64);
87make_mul!(Complex<isize>);
88make_mul!(Complex<usize>);
89make_mul!(Complex<i8>);
90make_mul!(Complex<u8>);
91make_mul!(Complex<i16>);
92make_mul!(Complex<u16>);
93make_mul!(Complex<i32>);
94make_mul!(Complex<u32>);
95make_mul!(Complex<i64>);
96make_mul!(Complex<u64>);
97make_mul!(Complex<f32>);
98make_mul!(Complex<f64>);
99
100#[cfg(test)]
101mod tests {
102 use super::*;
103 use paste::item;
104
105 macro_rules! make_test {
106 ($t:ty) => {
107 item! {
108 #[test]
109 fn [<test_mul_vec_scalar_ $t>]() {
110 let a = vec![1 as $t, 4 as $t, 8 as $t];
111 let b = 2 as $t;
112 let target = vec![2 as $t, 8 as $t, 16 as $t];
113 let res = <Vec<$t> as ArgminMul<$t, Vec<$t>>>::mul(&a, &b);
114 for i in 0..3 {
115 assert!(((target[i] - res[i]) as f64).abs() < std::f64::EPSILON);
116 }
117 }
118 }
119
120 item! {
121 #[test]
122 fn [<test_mul_scalar_vec_ $t>]() {
123 let a = vec![1 as $t, 4 as $t, 8 as $t];
124 let b = 2 as $t;
125 let target = vec![2 as $t, 8 as $t, 16 as $t];
126 let res = <$t as ArgminMul<Vec<$t>, Vec<$t>>>::mul(&b, &a);
127 for i in 0..3 {
128 assert!(((target[i] - res[i]) as f64).abs() < std::f64::EPSILON);
129 }
130 }
131 }
132
133 item! {
134 #[test]
135 fn [<test_mul_vec_vec_ $t>]() {
136 let a = vec![1 as $t, 4 as $t, 8 as $t];
137 let b = vec![2 as $t, 3 as $t, 4 as $t];
138 let target = vec![2 as $t, 12 as $t, 32 as $t];
139 let res = <Vec<$t> as ArgminMul<Vec<$t>, Vec<$t>>>::mul(&a, &b);
140 for i in 0..3 {
141 assert!(((target[i] - res[i]) as f64).abs() < std::f64::EPSILON);
142 }
143 }
144 }
145
146 item! {
147 #[test]
148 #[should_panic]
149 fn [<test_mul_vec_vec_panic_ $t>]() {
150 let a = vec![1 as $t, 4 as $t];
151 let b = vec![41 as $t, 38 as $t, 34 as $t];
152 <Vec<$t> as ArgminMul<Vec<$t>, Vec<$t>>>::mul(&a, &b);
153 }
154 }
155
156 item! {
157 #[test]
158 #[should_panic]
159 fn [<test_mul_vec_vec_panic_2_ $t>]() {
160 let a = vec![];
161 let b = vec![41 as $t, 38 as $t, 34 as $t];
162 <Vec<$t> as ArgminMul<Vec<$t>, Vec<$t>>>::mul(&a, &b);
163 }
164 }
165
166 item! {
167 #[test]
168 #[should_panic]
169 fn [<test_mul_vec_vec_panic_3_ $t>]() {
170 let a = vec![41 as $t, 38 as $t, 34 as $t];
171 let b = vec![];
172 <Vec<$t> as ArgminMul<Vec<$t>, Vec<$t>>>::mul(&a, &b);
173 }
174 }
175
176 item! {
177 #[test]
178 fn [<test_mul_mat_mat_ $t>]() {
179 let a = vec![
180 vec![1 as $t, 4 as $t, 8 as $t],
181 vec![2 as $t, 5 as $t, 9 as $t]
182 ];
183 let b = vec![
184 vec![2 as $t, 3 as $t, 4 as $t],
185 vec![3 as $t, 4 as $t, 5 as $t]
186 ];
187 let target = vec![
188 vec![2 as $t, 12 as $t, 32 as $t],
189 vec![6 as $t, 20 as $t, 45 as $t]
190 ];
191 let res = <Vec<Vec<$t>> as ArgminMul<Vec<Vec<$t>>, Vec<Vec<$t>>>>::mul(&a, &b);
192 for i in 0..3 {
193 for j in 0..2 {
194 assert!(((target[j][i] - res[j][i]) as f64).abs() < std::f64::EPSILON);
195 }
196 }
197 }
198 }
199
200 item! {
201 #[test]
202 #[should_panic]
203 fn [<test_mul_mat_mat_panic_1_ $t>]() {
204 let a = vec![
205 vec![1 as $t, 4 as $t, 8 as $t],
206 vec![2 as $t, 9 as $t]
207 ];
208 let b = vec![
209 vec![41 as $t, 38 as $t, 34 as $t],
210 vec![40 as $t, 37 as $t, 33 as $t]
211 ];
212 <Vec<Vec<$t>> as ArgminMul<Vec<Vec<$t>>, Vec<Vec<$t>>>>::mul(&a, &b);
213 }
214 }
215
216 item! {
217 #[test]
218 #[should_panic]
219 fn [<test_mul_mat_mat_panic_2_ $t>]() {
220 let a = vec![
221 vec![1 as $t, 4 as $t, 8 as $t],
222 vec![2 as $t, 5 as $t, 9 as $t]
223 ];
224 let b = vec![
225 vec![41 as $t, 38 as $t, 34 as $t],
226 ];
227 <Vec<Vec<$t>> as ArgminMul<Vec<Vec<$t>>, Vec<Vec<$t>>>>::mul(&a, &b);
228 }
229 }
230
231 item! {
232 #[test]
233 #[should_panic]
234 fn [<test_mul_mat_mat_panic_3_ $t>]() {
235 let a = vec![
236 vec![1 as $t, 4 as $t, 8 as $t],
237 vec![2 as $t, 5 as $t, 9 as $t]
238 ];
239 let b = vec![];
240 <Vec<Vec<$t>> as ArgminMul<Vec<Vec<$t>>, Vec<Vec<$t>>>>::mul(&a, &b);
241 }
242 }
243
244 item! {
245 #[test]
246 fn [<test_mul_scalar_mat_1_ $t>]() {
247 let a = vec![
248 vec![1 as $t, 4 as $t, 8 as $t],
249 vec![2 as $t, 5 as $t, 9 as $t]
250 ];
251 let b = 2 as $t;
252 let target = vec![
253 vec![2 as $t, 8 as $t, 16 as $t],
254 vec![4 as $t, 10 as $t, 18 as $t]
255 ];
256 let res = <Vec<Vec<$t>> as ArgminMul<$t, Vec<Vec<$t>>>>::mul(&a, &b);
257 for i in 0..3 {
258 for j in 0..2 {
259 assert!(((target[j][i] - res[j][i]) as f64).abs() < std::f64::EPSILON);
260 }
261 }
262 }
263 }
264
265 item! {
266 #[test]
267 fn [<test_mul_scalar_mat_2_ $t>]() {
268 let b = vec![
269 vec![1 as $t, 4 as $t, 8 as $t],
270 vec![2 as $t, 5 as $t, 9 as $t]
271 ];
272 let a = 2 as $t;
273 let target = vec![
274 vec![2 as $t, 8 as $t, 16 as $t],
275 vec![4 as $t, 10 as $t, 18 as $t]
276 ];
277 let res = <$t as ArgminMul<Vec<Vec<$t>>, Vec<Vec<$t>>>>::mul(&a, &b);
278 for i in 0..3 {
279 for j in 0..2 {
280 assert!(((target[j][i] - res[j][i]) as f64).abs() < std::f64::EPSILON);
281 }
282 }
283 }
284 }
285 };
286 }
287
288 make_test!(isize);
289 make_test!(usize);
290 make_test!(i8);
291 make_test!(u8);
292 make_test!(i16);
293 make_test!(u16);
294 make_test!(i32);
295 make_test!(u32);
296 make_test!(i64);
297 make_test!(u64);
298 make_test!(f32);
299 make_test!(f64);
300}