1use crate::ArgminEye;
9
10macro_rules! make_eye {
11 ($t:ty) => {
12 impl ArgminEye for Vec<Vec<$t>> {
13 #[allow(clippy::cast_lossless)]
14 #[inline]
15 fn eye_like(&self) -> Vec<Vec<$t>> {
16 let n = self.len();
17 let mut out = vec![vec![0 as $t; n]; n];
18 for i in 0..n {
19 out[i][i] = 1 as $t;
20 }
21 out
22 }
23
24 #[allow(clippy::cast_lossless)]
25 #[inline]
26 fn eye(n: usize) -> Vec<Vec<$t>> {
27 let mut out = vec![vec![0 as $t; n]; n];
28 for i in 0..n {
29 out[i][i] = 1 as $t;
30 }
31 out
32 }
33 }
34 };
35}
36
37make_eye!(f32);
38make_eye!(f64);
39make_eye!(i8);
40make_eye!(i16);
41make_eye!(i32);
42make_eye!(i64);
43make_eye!(u8);
44make_eye!(u16);
45make_eye!(u32);
46make_eye!(u64);
47
48#[cfg(test)]
49mod tests {
50 use super::*;
51 use approx::assert_relative_eq;
52 use paste::item;
53
54 macro_rules! make_test {
55 ($t:ty) => {
56 item! {
57 #[test]
58 fn [<test_eye_ $t>]() {
59 let e: Vec<Vec<$t>> = <Vec<Vec<$t>> as ArgminEye>::eye(3);
60 let res = vec![
61 vec![1 as $t, 0 as $t, 0 as $t],
62 vec![0 as $t, 1 as $t, 0 as $t],
63 vec![0 as $t, 0 as $t, 1 as $t]
64 ];
65 for i in 0..3 {
66 for j in 0..3 {
67 assert_relative_eq!(res[i][j] as f64, e[i][j] as f64, epsilon = f64::EPSILON);
68 }
69 }
70 }
71 }
72
73 item! {
74 #[test]
75 fn [<test_eye_like_ $t>]() {
76 let a = vec![
77 vec![0 as $t, 2 as $t, 6 as $t],
78 vec![3 as $t, 2 as $t, 7 as $t],
79 vec![9 as $t, 8 as $t, 1 as $t]
80 ];
81 let e: Vec<Vec<$t>> = a.eye_like();
82 let res = vec![
83 vec![1 as $t, 0 as $t, 0 as $t],
84 vec![0 as $t, 1 as $t, 0 as $t],
85 vec![0 as $t, 0 as $t, 1 as $t]
86 ];
87 for i in 0..3 {
88 for j in 0..3 {
89 assert_relative_eq!(res[i][j] as f64, e[i][j] as f64, epsilon = f64::EPSILON);
90 }
91 }
92 }
93 }
94 };
95 }
96
97 make_test!(i8);
98 make_test!(u8);
99 make_test!(i16);
100 make_test!(u16);
101 make_test!(i32);
102 make_test!(u32);
103 make_test!(i64);
104 make_test!(u64);
105 make_test!(f32);
106 make_test!(f64);
107}