argmin_math/nalgebra_m/
minmax.rs1use crate::{Allocator, ArgminMinMax};
9
10use crate::ClosedMul;
11use nalgebra::{
12 base::{dimension::Dim, Scalar},
13 DefaultAllocator, OMatrix,
14};
15
16impl<N, R, C> ArgminMinMax for OMatrix<N, R, C>
17where
18 N: Scalar + Copy + ClosedMul + PartialOrd,
19 R: Dim,
20 C: Dim,
21 DefaultAllocator: Allocator<N, R, C>,
22{
23 #[inline]
24 fn max(a: &OMatrix<N, R, C>, b: &OMatrix<N, R, C>) -> OMatrix<N, R, C> {
25 a.zip_map(b, |aa, bb| if aa > bb { aa } else { bb })
26 }
27
28 #[inline]
29 fn min(a: &OMatrix<N, R, C>, b: &OMatrix<N, R, C>) -> OMatrix<N, R, C> {
30 a.zip_map(b, |aa, bb| if aa < bb { aa } else { bb })
31 }
32}
33
34#[cfg(test)]
35mod tests {
36 use super::*;
37 use approx::assert_relative_eq;
38 use nalgebra::{Matrix2x3, Vector3};
39 use paste::item;
40
41 macro_rules! make_test {
42 ($t:ty) => {
43 item! {
44 #[test]
45 fn [<test_minmax_vec_vec_ $t>]() {
46 let a = Vector3::new(1 as $t, 4 as $t, 8 as $t);
47 let b = Vector3::new(2 as $t, 3 as $t, 4 as $t);
48 let target_max = Vector3::new(2 as $t, 4 as $t, 8 as $t);
49 let target_min = Vector3::new(1 as $t, 3 as $t, 4 as $t);
50 let res_max = <Vector3<$t> as ArgminMinMax>::max(&a, &b);
51 let res_min = <Vector3<$t> as ArgminMinMax>::min(&a, &b);
52 for i in 0..3 {
53 assert_relative_eq!(target_max[i] as f64, res_max[i] as f64, epsilon = f64::EPSILON);
54 assert_relative_eq!(target_min[i] as f64, res_min[i] as f64, epsilon = f64::EPSILON);
55 }
56 }
57 }
58
59 item! {
60 #[test]
61 fn [<test_minmax_mat_mat_ $t>]() {
62 let a = Matrix2x3::new(
63 1 as $t, 4 as $t, 8 as $t,
64 2 as $t, 5 as $t, 9 as $t
65 );
66 let b = Matrix2x3::new(
67 2 as $t, 3 as $t, 4 as $t,
68 3 as $t, 4 as $t, 5 as $t
69 );
70 let target_max = Matrix2x3::new(
71 2 as $t, 4 as $t, 8 as $t,
72 3 as $t, 5 as $t, 9 as $t
73 );
74 let target_min = Matrix2x3::new(
75 1 as $t, 3 as $t, 4 as $t,
76 2 as $t, 4 as $t, 5 as $t
77 );
78 let res_max = <Matrix2x3<$t> as ArgminMinMax>::max(&a, &b);
79 let res_min = <Matrix2x3<$t> as ArgminMinMax>::min(&a, &b);
80 for i in 0..3 {
81 for j in 0..2 {
82 assert_relative_eq!(target_max[(j, i)] as f64, res_max[(j, i)] as f64, epsilon = f64::EPSILON);
83 assert_relative_eq!(target_min[(j, i)] as f64, res_min[(j, i)] as f64, epsilon = f64::EPSILON);
84 }
85 }
86 }
87 }
88 };
89 }
90
91 make_test!(i8);
92 make_test!(u8);
93 make_test!(i16);
94 make_test!(u16);
95 make_test!(i32);
96 make_test!(u32);
97 make_test!(i64);
98 make_test!(u64);
99 make_test!(f32);
100 make_test!(f64);
101}