argmin_math/vec/
eye.rs

1// Copyright 2018-2024 argmin developers
2//
3// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
4// http://apache.org/licenses/LICENSE-2.0> or the MIT license <LICENSE-MIT or
5// http://opensource.org/licenses/MIT>, at your option. This file may not be
6// copied, modified, or distributed except according to those terms.
7
8use 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}