1use crate::ArgminDiv;
9use num_complex::Complex;
10
11macro_rules! make_div {
12 ($t:ty) => {
13 impl ArgminDiv<$t, Vec<$t>> for Vec<$t> {
14 #[inline]
15 fn div(&self, other: &$t) -> Vec<$t> {
16 self.iter().map(|a| a / other).collect()
17 }
18 }
19
20 impl ArgminDiv<Vec<$t>, Vec<$t>> for $t {
21 #[inline]
22 fn div(&self, other: &Vec<$t>) -> Vec<$t> {
23 other.iter().map(|a| self / a).collect()
24 }
25 }
26
27 impl ArgminDiv<Vec<$t>, Vec<$t>> for Vec<$t> {
28 #[inline]
29 fn div(&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 ArgminDiv<Vec<Vec<$t>>, Vec<Vec<$t>>> for Vec<Vec<$t>> {
39 #[inline]
40 fn div(&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 ArgminDiv<Vec<$t>, Vec<$t>>>::div(&a, &b)
53 })
54 .collect()
55 }
56 }
57 };
58}
59
60make_div!(i8);
61make_div!(u8);
62make_div!(i16);
63make_div!(u16);
64make_div!(i32);
65make_div!(u32);
66make_div!(i64);
67make_div!(u64);
68make_div!(f32);
69make_div!(f64);
70make_div!(Complex<i8>);
71make_div!(Complex<u8>);
72make_div!(Complex<i16>);
73make_div!(Complex<u16>);
74make_div!(Complex<i32>);
75make_div!(Complex<u32>);
76make_div!(Complex<i64>);
77make_div!(Complex<u64>);
78make_div!(Complex<f32>);
79make_div!(Complex<f64>);
80
81#[cfg(test)]
82mod tests {
83 use super::*;
84 use approx::assert_relative_eq;
85 use paste::item;
86
87 macro_rules! make_test {
88 ($t:ty) => {
89 item! {
90 #[test]
91 fn [<test_div_vec_scalar_ $t>]() {
92 let a = vec![2 as $t, 4 as $t, 8 as $t];
93 let b = 2 as $t;
94 let target = vec![1 as $t, 2 as $t, 4 as $t];
95 let res = <Vec<$t> as ArgminDiv<$t, Vec<$t>>>::div(&a, &b);
96 for i in 0..3 {
97 assert_relative_eq!(target[i] as f64, res[i] as f64, epsilon = f64::EPSILON);
98 }
99 }
100 }
101
102 item! {
103 #[test]
104 fn [<test_div_vec_scalar_complex_ $t>]() {
105 let a = vec![
106 Complex::new(2 as $t, 4 as $t),
107 Complex::new(4 as $t, 8 as $t),
108 Complex::new(3 as $t, 9 as $t),
109 ];
110 let b = Complex::new(2 as $t, 4 as $t);
111 let target = vec![a[0]/b, a[1]/b, a[2]/b];
112 let res = <Vec<Complex<$t>> as ArgminDiv<Complex<$t>, Vec<Complex<$t>>>>::div(&a, &b);
113 for i in 0..3 {
114 assert_relative_eq!(target[i].re as f64, res[i].re as f64, epsilon = f64::EPSILON);
115 assert_relative_eq!(target[i].im as f64, res[i].im as f64, epsilon = f64::EPSILON);
116 }
117 }
118 }
119
120 item! {
121 #[test]
122 fn [<test_div_scalar_vec_ $t>]() {
123 let a = vec![2 as $t, 4 as $t, 8 as $t];
124 let b = 64 as $t;
125 let target = vec![32 as $t, 16 as $t, 8 as $t];
126 let res = <$t as ArgminDiv<Vec<$t>, Vec<$t>>>::div(&b, &a);
127 for i in 0..3 {
128 assert_relative_eq!(target[i] as f64, res[i] as f64, epsilon = f64::EPSILON);
129 }
130 }
131 }
132
133 item! {
134 #[test]
135 fn [<test_div_scalar_vec_complex_ $t>]() {
136 let a = vec![
137 Complex::new(2 as $t, 1 as $t),
138 Complex::new(2 as $t, 2 as $t),
139 Complex::new(3 as $t, 2 as $t),
140 ];
141 let b = Complex::new(10 as $t, 12 as $t);
142 let target = vec![b/a[0], b/a[1], b/a[2]];
143 let res = <Complex<$t> as ArgminDiv<Vec<Complex<$t>>, Vec<Complex<$t>>>>::div(&b, &a);
144 for i in 0..3 {
145 assert_relative_eq!(target[i].re as f64, res[i].re as f64, epsilon = f64::EPSILON);
146 assert_relative_eq!(target[i].im as f64, res[i].im as f64, epsilon = f64::EPSILON);
147 }
148 }
149 }
150
151 item! {
152 #[test]
153 fn [<test_div_vec_vec_ $t>]() {
154 let a = vec![4 as $t, 9 as $t, 8 as $t];
155 let b = vec![2 as $t, 3 as $t, 4 as $t];
156 let target = vec![2 as $t, 3 as $t, 2 as $t];
157 let res = <Vec<$t> as ArgminDiv<Vec<$t>, Vec<$t>>>::div(&a, &b);
158 for i in 0..3 {
159 assert_relative_eq!(target[i] as f64, res[i] as f64, epsilon = f64::EPSILON);
160 }
161 }
162 }
163
164 item! {
165 #[test]
166 fn [<test_div_vec_vec_complex_ $t>]() {
167 let a = vec![
168 Complex::new(8 as $t, 7 as $t),
169 Complex::new(7 as $t, 6 as $t),
170 Complex::new(6 as $t, 5 as $t),
171 ];
172 let b = vec![
173 Complex::new(4 as $t, 2 as $t),
174 Complex::new(4 as $t, 3 as $t),
175 Complex::new(3 as $t, 2 as $t),
176 ];
177 let target = vec![a[0]/b[0], a[1]/b[1], a[2]/b[2]];
178 let res = <Vec<Complex<$t>> as ArgminDiv<Vec<Complex<$t>>, Vec<Complex<$t>>>>::div(&a, &b);
179 for i in 0..3 {
180 assert_relative_eq!(target[i].re as f64, res[i].re as f64, epsilon = f64::EPSILON);
181 assert_relative_eq!(target[i].im as f64, res[i].im as f64, epsilon = f64::EPSILON);
182 }
183 }
184 }
185
186 item! {
187 #[test]
188 #[should_panic]
189 fn [<test_div_vec_vec_panic_ $t>]() {
190 let a = vec![1 as $t, 4 as $t];
191 let b = vec![41 as $t, 38 as $t, 34 as $t];
192 <Vec<$t> as ArgminDiv<Vec<$t>, Vec<$t>>>::div(&a, &b);
193 }
194 }
195
196 item! {
197 #[test]
198 #[should_panic]
199 fn [<test_div_vec_vec_panic_2_ $t>]() {
200 let a = vec![];
201 let b = vec![41 as $t, 38 as $t, 34 as $t];
202 <Vec<$t> as ArgminDiv<Vec<$t>, Vec<$t>>>::div(&a, &b);
203 }
204 }
205
206 item! {
207 #[test]
208 #[should_panic]
209 fn [<test_div_vec_vec_panic_3_ $t>]() {
210 let a = vec![41 as $t, 38 as $t, 34 as $t];
211 let b = vec![];
212 <Vec<$t> as ArgminDiv<Vec<$t>, Vec<$t>>>::div(&a, &b);
213 }
214 }
215
216 item! {
217 #[test]
218 fn [<test_div_mat_mat_ $t>]() {
219 let a = vec![
220 vec![4 as $t, 12 as $t, 8 as $t],
221 vec![9 as $t, 20 as $t, 45 as $t]
222 ];
223 let b = vec![
224 vec![2 as $t, 3 as $t, 4 as $t],
225 vec![3 as $t, 4 as $t, 5 as $t]
226 ];
227 let target = vec![
228 vec![2 as $t, 4 as $t, 2 as $t],
229 vec![3 as $t, 5 as $t, 9 as $t]
230 ];
231 let res = <Vec<Vec<$t>> as ArgminDiv<Vec<Vec<$t>>, Vec<Vec<$t>>>>::div(&a, &b);
232 for i in 0..3 {
233 for j in 0..2 {
234 assert_relative_eq!(target[j][i] as f64, res[j][i] as f64, epsilon = f64::EPSILON);
235 }
236 }
237 }
238 }
239
240 item! {
241 #[test]
242 fn [<test_div_mat_mat_complex_ $t>]() {
243 let a = vec![
244 vec![
245 Complex::new(8 as $t, 7 as $t),
246 Complex::new(7 as $t, 6 as $t),
247 Complex::new(6 as $t, 5 as $t)
248 ],
249 vec![
250 Complex::new(9 as $t, 6 as $t),
251 Complex::new(7 as $t, 6 as $t),
252 Complex::new(6 as $t, 4 as $t)
253 ],
254 ];
255 let b = vec![
256 vec![
257 Complex::new(4 as $t, 2 as $t),
258 Complex::new(4 as $t, 3 as $t),
259 Complex::new(3 as $t, 2 as $t),
260 ],
261 vec![
262 Complex::new(3 as $t, 2 as $t),
263 Complex::new(4 as $t, 3 as $t),
264 Complex::new(3 as $t, 1 as $t),
265 ],
266 ];
267 let target = vec![
268 vec![a[0][0]/b[0][0], a[0][1]/b[0][1], a[0][2]/b[0][2]],
269 vec![a[1][0]/b[1][0], a[1][1]/b[1][1], a[1][2]/b[1][2]]
270 ];
271 let res = <Vec<Vec<Complex<$t>>> as ArgminDiv<Vec<Vec<Complex<$t>>>, Vec<Vec<Complex<$t>>>>>::div(&a, &b);
272 for i in 0..3 {
273 for j in 0..2 {
274 assert_relative_eq!(target[j][i].re as f64, res[j][i].re as f64, epsilon = f64::EPSILON);
275 assert_relative_eq!(target[j][i].im as f64, res[j][i].im as f64, epsilon = f64::EPSILON);
276 }
277 }
278 }
279 }
280
281 item! {
282 #[test]
283 #[should_panic]
284 fn [<test_div_mat_mat_panic_1_ $t>]() {
285 let a = vec![
286 vec![1 as $t, 4 as $t, 8 as $t],
287 vec![2 as $t, 9 as $t]
288 ];
289 let b = vec![
290 vec![41 as $t, 38 as $t, 34 as $t],
291 vec![40 as $t, 37 as $t, 33 as $t]
292 ];
293 <Vec<Vec<$t>> as ArgminDiv<Vec<Vec<$t>>, Vec<Vec<$t>>>>::div(&a, &b);
294 }
295 }
296
297 item! {
298 #[test]
299 #[should_panic]
300 fn [<test_div_mat_mat_panic_2_ $t>]() {
301 let a = vec![
302 vec![1 as $t, 4 as $t, 8 as $t],
303 vec![2 as $t, 5 as $t, 9 as $t]
304 ];
305 let b = vec![
306 vec![41 as $t, 38 as $t, 34 as $t],
307 ];
308 <Vec<Vec<$t>> as ArgminDiv<Vec<Vec<$t>>, Vec<Vec<$t>>>>::div(&a, &b);
309 }
310 }
311
312 item! {
313 #[test]
314 #[should_panic]
315 fn [<test_div_mat_mat_panic_3_ $t>]() {
316 let a = vec![
317 vec![1 as $t, 4 as $t, 8 as $t],
318 vec![2 as $t, 5 as $t, 9 as $t]
319 ];
320 let b = vec![];
321 <Vec<Vec<$t>> as ArgminDiv<Vec<Vec<$t>>, Vec<Vec<$t>>>>::div(&a, &b);
322 }
323 }
324 };
325 }
326
327 make_test!(i8);
328 make_test!(u8);
329 make_test!(i16);
330 make_test!(u16);
331 make_test!(i32);
332 make_test!(u32);
333 make_test!(i64);
334 make_test!(u64);
335 make_test!(f32);
336 make_test!(f64);
337}