argmin_math/vec/
minmax.rs1use crate::ArgminMinMax;
9
10macro_rules! make_minmax {
11 ($t:ty) => {
12 impl ArgminMinMax for Vec<$t> {
13 fn min(x: &Self, y: &Self) -> Self {
14 assert!(!x.is_empty());
15 assert_eq!(x.len(), y.len());
16
17 x.iter()
18 .zip(y.iter())
19 .map(|(a, b)| if a < b { a.clone() } else { b.clone() })
20 .collect()
21 }
22
23 fn max(x: &Self, y: &Self) -> Self {
24 assert!(!x.is_empty());
25 assert_eq!(x.len(), y.len());
26
27 x.iter()
28 .zip(y.iter())
29 .map(|(a, b)| if a > b { a.clone() } else { b.clone() })
30 .collect()
31 }
32 }
33
34 impl ArgminMinMax for Vec<Vec<$t>> {
35 fn min(x: &Self, y: &Self) -> Self {
36 assert!(!x.is_empty());
37 assert_eq!(x.len(), y.len());
38
39 x.iter()
40 .zip(y.iter())
41 .map(|(a, b)| <Vec<$t> as ArgminMinMax>::min(&a, &b))
42 .collect()
43 }
44
45 fn max(x: &Self, y: &Self) -> Self {
46 assert!(!x.is_empty());
47 assert_eq!(x.len(), y.len());
48
49 x.iter()
50 .zip(y.iter())
51 .map(|(a, b)| <Vec<$t> as ArgminMinMax>::max(&a, &b))
52 .collect()
53 }
54 }
55 };
56}
57
58make_minmax!(i8);
59make_minmax!(u8);
60make_minmax!(i16);
61make_minmax!(u16);
62make_minmax!(i32);
63make_minmax!(u32);
64make_minmax!(i64);
65make_minmax!(u64);
66make_minmax!(f32);
67make_minmax!(f64);
68
69#[cfg(test)]
70mod tests {
71 use super::*;
72 use approx::assert_relative_eq;
73 use paste::item;
74
75 macro_rules! make_test {
76 ($t:ty) => {
77 item! {
78 #[test]
79 fn [<test_minmax_vec_vec_ $t>]() {
80 let a = vec![1 as $t, 4 as $t, 8 as $t];
81 let b = vec![2 as $t, 3 as $t, 4 as $t];
82 let target_max = vec![2 as $t, 4 as $t, 8 as $t];
83 let target_min = vec![1 as $t, 3 as $t, 4 as $t];
84 let res_max = <Vec<$t> as ArgminMinMax>::max(&a, &b);
85 let res_min = <Vec<$t> as ArgminMinMax>::min(&a, &b);
86 for i in 0..3 {
87 assert_relative_eq!(target_max[i] as f64, res_max[i] as f64, epsilon = f64::EPSILON);
88 assert_relative_eq!(target_min[i] as f64, res_min[i] as f64, epsilon = f64::EPSILON);
89 }
90 }
91 }
92
93 item! {
94 #[test]
95 fn [<test_minmax_mat_mat_ $t>]() {
96 let a = vec![
97 vec![1 as $t, 4 as $t, 8 as $t],
98 vec![2 as $t, 5 as $t, 9 as $t]
99 ];
100 let b = vec![
101 vec![2 as $t, 3 as $t, 4 as $t],
102 vec![3 as $t, 4 as $t, 5 as $t]
103 ];
104 let target_max = vec![
105 vec![2 as $t, 4 as $t, 8 as $t],
106 vec![3 as $t, 5 as $t, 9 as $t]
107 ];
108 let target_min = vec![
109 vec![1 as $t, 3 as $t, 4 as $t],
110 vec![2 as $t, 4 as $t, 5 as $t]
111 ];
112 let res_max = <Vec<Vec<$t>> as ArgminMinMax>::max(&a, &b);
113 let res_min = <Vec<Vec<$t>> as ArgminMinMax>::min(&a, &b);
114 for i in 0..3 {
115 for j in 0..2 {
116 assert_relative_eq!(target_max[j][i] as f64, res_max[j][i] as f64, epsilon = f64::EPSILON);
117 assert_relative_eq!(target_min[j][i] as f64, res_min[j][i] as f64, epsilon = f64::EPSILON);
118 }
119 }
120 }
121 }
122 };
123 }
124
125 make_test!(i8);
126 make_test!(u8);
127 make_test!(i16);
128 make_test!(u16);
129 make_test!(i32);
130 make_test!(u32);
131 make_test!(i64);
132 make_test!(u64);
133 make_test!(f32);
134 make_test!(f64);
135}