1use crate::core::math::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!(n2 > 0);
34 assert_eq!(n1, n2);
35 self.iter().zip(other.iter()).map(|(a, b)| a / b).collect()
36 }
37 }
38
39 impl ArgminDiv<Vec<Vec<$t>>, Vec<Vec<$t>>> for Vec<Vec<$t>> {
40 #[inline]
41 fn div(&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 ArgminDiv<Vec<$t>, Vec<$t>>>::div(&a, &b)
54 })
55 .collect()
56 }
57 }
58 };
59}
60
61make_div!(isize);
62make_div!(usize);
63make_div!(i8);
64make_div!(u8);
65make_div!(i16);
66make_div!(u16);
67make_div!(i32);
68make_div!(u32);
69make_div!(i64);
70make_div!(u64);
71make_div!(f32);
72make_div!(f64);
73make_div!(Complex<isize>);
74make_div!(Complex<usize>);
75make_div!(Complex<i8>);
76make_div!(Complex<u8>);
77make_div!(Complex<i16>);
78make_div!(Complex<u16>);
79make_div!(Complex<i32>);
80make_div!(Complex<u32>);
81make_div!(Complex<i64>);
82make_div!(Complex<u64>);
83make_div!(Complex<f32>);
84make_div!(Complex<f64>);
85
86#[cfg(test)]
87mod tests {
88 use super::*;
89 use paste::item;
90
91 macro_rules! make_test {
92 ($t:ty) => {
93 item! {
94 #[test]
95 fn [<test_div_vec_scalar_ $t>]() {
96 let a = vec![2 as $t, 4 as $t, 8 as $t];
97 let b = 2 as $t;
98 let target = vec![1 as $t, 2 as $t, 4 as $t];
99 let res = <Vec<$t> as ArgminDiv<$t, Vec<$t>>>::div(&a, &b);
100 for i in 0..3 {
101 assert!(((target[i] - res[i]) as f64).abs() < std::f64::EPSILON);
102 }
103 }
104 }
105
106 item! {
107 #[test]
108 fn [<test_div_scalar_vec_ $t>]() {
109 let a = vec![2 as $t, 4 as $t, 8 as $t];
110 let b = 64 as $t;
111 let target = vec![32 as $t, 16 as $t, 8 as $t];
112 let res = <$t as ArgminDiv<Vec<$t>, Vec<$t>>>::div(&b, &a);
113 for i in 0..3 {
114 assert!(((target[i] - res[i]) as f64).abs() < std::f64::EPSILON);
115 }
116 }
117 }
118
119 item! {
120 #[test]
121 fn [<test_div_vec_vec_ $t>]() {
122 let a = vec![4 as $t, 9 as $t, 8 as $t];
123 let b = vec![2 as $t, 3 as $t, 4 as $t];
124 let target = vec![2 as $t, 3 as $t, 2 as $t];
125 let res = <Vec<$t> as ArgminDiv<Vec<$t>, Vec<$t>>>::div(&a, &b);
126 for i in 0..3 {
127 assert!(((target[i] - res[i]) as f64).abs() < std::f64::EPSILON);
128 }
129 }
130 }
131
132 item! {
133 #[test]
134 #[should_panic]
135 fn [<test_div_vec_vec_panic_ $t>]() {
136 let a = vec![1 as $t, 4 as $t];
137 let b = vec![41 as $t, 38 as $t, 34 as $t];
138 <Vec<$t> as ArgminDiv<Vec<$t>, Vec<$t>>>::div(&a, &b);
139 }
140 }
141
142 item! {
143 #[test]
144 #[should_panic]
145 fn [<test_div_vec_vec_panic_2_ $t>]() {
146 let a = vec![];
147 let b = vec![41 as $t, 38 as $t, 34 as $t];
148 <Vec<$t> as ArgminDiv<Vec<$t>, Vec<$t>>>::div(&a, &b);
149 }
150 }
151
152 item! {
153 #[test]
154 #[should_panic]
155 fn [<test_div_vec_vec_panic_3_ $t>]() {
156 let a = vec![41 as $t, 38 as $t, 34 as $t];
157 let b = vec![];
158 <Vec<$t> as ArgminDiv<Vec<$t>, Vec<$t>>>::div(&a, &b);
159 }
160 }
161
162 item! {
163 #[test]
164 fn [<test_div_mat_mat_ $t>]() {
165 let a = vec![
166 vec![4 as $t, 12 as $t, 8 as $t],
167 vec![9 as $t, 20 as $t, 45 as $t]
168 ];
169 let b = vec![
170 vec![2 as $t, 3 as $t, 4 as $t],
171 vec![3 as $t, 4 as $t, 5 as $t]
172 ];
173 let target = vec![
174 vec![2 as $t, 4 as $t, 2 as $t],
175 vec![3 as $t, 5 as $t, 9 as $t]
176 ];
177 let res = <Vec<Vec<$t>> as ArgminDiv<Vec<Vec<$t>>, Vec<Vec<$t>>>>::div(&a, &b);
178 for i in 0..3 {
179 for j in 0..2 {
180 assert!(((target[j][i] - res[j][i]) as f64).abs() < std::f64::EPSILON);
181 }
182 }
183 }
184 }
185
186 item! {
187 #[test]
188 #[should_panic]
189 fn [<test_div_mat_mat_panic_1_ $t>]() {
190 let a = vec![
191 vec![1 as $t, 4 as $t, 8 as $t],
192 vec![2 as $t, 9 as $t]
193 ];
194 let b = vec![
195 vec![41 as $t, 38 as $t, 34 as $t],
196 vec![40 as $t, 37 as $t, 33 as $t]
197 ];
198 <Vec<Vec<$t>> as ArgminDiv<Vec<Vec<$t>>, Vec<Vec<$t>>>>::div(&a, &b);
199 }
200 }
201
202 item! {
203 #[test]
204 #[should_panic]
205 fn [<test_div_mat_mat_panic_2_ $t>]() {
206 let a = vec![
207 vec![1 as $t, 4 as $t, 8 as $t],
208 vec![2 as $t, 5 as $t, 9 as $t]
209 ];
210 let b = vec![
211 vec![41 as $t, 38 as $t, 34 as $t],
212 ];
213 <Vec<Vec<$t>> as ArgminDiv<Vec<Vec<$t>>, Vec<Vec<$t>>>>::div(&a, &b);
214 }
215 }
216
217 item! {
218 #[test]
219 #[should_panic]
220 fn [<test_div_mat_mat_panic_3_ $t>]() {
221 let a = vec![
222 vec![1 as $t, 4 as $t, 8 as $t],
223 vec![2 as $t, 5 as $t, 9 as $t]
224 ];
225 let b = vec![];
226 <Vec<Vec<$t>> as ArgminDiv<Vec<Vec<$t>>, Vec<Vec<$t>>>>::div(&a, &b);
227 }
228 }
229 };
230 }
231
232 make_test!(isize);
233 make_test!(usize);
234 make_test!(i8);
235 make_test!(u8);
236 make_test!(i16);
237 make_test!(u16);
238 make_test!(i32);
239 make_test!(u32);
240 make_test!(i64);
241 make_test!(u64);
242 make_test!(f32);
243 make_test!(f64);
244}