argmin_math/nalgebra_m/
transpose.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
8// Note: This is not really the preferred way I think. Maybe this should also be implemented for
9// ArrayViews, which would probably make it more efficient.
10
11use crate::{Allocator, ArgminTranspose};
12
13use nalgebra::{
14    base::{dimension::Dim, storage::Storage, Scalar},
15    DefaultAllocator, Matrix, OMatrix,
16};
17
18impl<N, R, C, S> ArgminTranspose<OMatrix<N, C, R>> for Matrix<N, R, C, S>
19where
20    N: Scalar,
21    R: Dim,
22    C: Dim,
23    S: Storage<N, R, C>,
24    DefaultAllocator: Allocator<N, C, R>,
25{
26    #[inline]
27    fn t(self) -> OMatrix<N, C, R> {
28        self.transpose()
29    }
30}
31
32#[cfg(test)]
33mod tests {
34    use super::*;
35    use approx::assert_relative_eq;
36    use nalgebra::{Matrix2, Matrix2x3, Matrix3x2, RowVector2, Vector2};
37    use paste::item;
38
39    macro_rules! make_test {
40        ($t:ty) => {
41            item! {
42                #[test]
43                fn [<test_transpose_ $t>]() {
44                    let a = Vector2::new(1 as $t, 4 as $t);
45                    let target = RowVector2::new(1 as $t, 4 as $t);
46                    let res = <Vector2<$t> as ArgminTranspose<RowVector2<$t>>>::t(a);
47                    for i in 0..2 {
48                        assert_relative_eq!(target[i] as f64, res[i] as f64, epsilon = f64::EPSILON);
49                    }
50                }
51            }
52
53            item! {
54                #[test]
55                fn [<test_transpose_2d_1_ $t>]() {
56                    let a = Matrix2::new(
57                        1 as $t, 4 as $t,
58                        8 as $t, 7 as $t
59                    );
60                    let target = Matrix2::new(
61                        1 as $t, 8 as $t,
62                        4 as $t, 7 as $t
63                    );
64                    let res = <Matrix2<$t> as ArgminTranspose<Matrix2<$t>>>::t(a);
65                    for i in 0..2 {
66                        for j in 0..2 {
67                            assert_relative_eq!(target[(i, j)] as f64, res[(i, j)] as f64, epsilon = f64::EPSILON);
68                        }
69                    }
70                }
71            }
72
73            item! {
74                #[test]
75                fn [<test_transpose_2d_2_ $t>]() {
76                    let a = Matrix3x2::new(
77                        1 as $t, 4 as $t,
78                        8 as $t, 7 as $t,
79                        3 as $t, 6 as $t
80                    );
81                    let target = Matrix2x3::new(
82                        1 as $t, 8 as $t, 3 as $t,
83                        4 as $t, 7 as $t, 6 as $t
84                    );
85                    let res = <Matrix3x2<$t> as ArgminTranspose<Matrix2x3<$t>>>::t(a);
86                    for i in 0..2 {
87                        for j in 0..3 {
88                            assert_relative_eq!(target[(i, j)] as f64, res[(i, j)] as f64, epsilon = f64::EPSILON);
89                        }
90                    }
91                }
92            }
93        };
94    }
95
96    make_test!(i8);
97    make_test!(u8);
98    make_test!(i16);
99    make_test!(u16);
100    make_test!(i32);
101    make_test!(u32);
102    make_test!(i64);
103    make_test!(u64);
104    make_test!(f32);
105    make_test!(f64);
106}