argmin/core/math/
eye_vec.rs

1// Copyright 2018-2020 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::core::math::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);
47make_eye!(isize);
48make_eye!(usize);
49
50#[cfg(test)]
51mod tests {
52    use super::*;
53    use paste::item;
54
55    macro_rules! make_test {
56        ($t:ty) => {
57            item! {
58                #[test]
59                fn [<test_eye_ $t>]() {
60                    let e: Vec<Vec<$t>> = <Vec<Vec<$t>> as ArgminEye>::eye(3);
61                    let res = vec![
62                        vec![1 as $t, 0 as $t, 0 as $t],
63                        vec![0 as $t, 1 as $t, 0 as $t],
64                        vec![0 as $t, 0 as $t, 1 as $t]
65                    ];
66                    for i in 0..3 {
67                        for j in 0..3 {
68                            assert!((((res[i][j] - e[i][j]) as f64).abs()) < std::f64::EPSILON);
69                        }
70                    }
71                }
72            }
73
74            item! {
75                #[test]
76                fn [<test_eye_like_ $t>]() {
77                    let a = vec![
78                        vec![0 as $t, 2 as $t, 6 as $t],
79                        vec![3 as $t, 2 as $t, 7 as $t],
80                        vec![9 as $t, 8 as $t, 1 as $t]
81                    ];
82                    let e: Vec<Vec<$t>> = a.eye_like();
83                    let res = vec![
84                        vec![1 as $t, 0 as $t, 0 as $t],
85                        vec![0 as $t, 1 as $t, 0 as $t],
86                        vec![0 as $t, 0 as $t, 1 as $t]
87                    ];
88                    for i in 0..3 {
89                        for j in 0..3 {
90                            assert!((((res[i][j] - e[i][j]) as f64).abs()) < std::f64::EPSILON);
91                        }
92                    }
93                }
94            }
95        };
96    }
97
98    make_test!(isize);
99    make_test!(usize);
100    make_test!(i8);
101    make_test!(u8);
102    make_test!(i16);
103    make_test!(u16);
104    make_test!(i32);
105    make_test!(u32);
106    make_test!(i64);
107    make_test!(u64);
108    make_test!(f32);
109    make_test!(f64);
110}