1 // This file is part of Eigen, a lightweight C++ template library
4 // Copyright (C) 2009 Benoit Jacob <jacob.benoit.1@gmail.com>
6 // This Source Code Form is subject to the terms of the Mozilla
7 // Public License v. 2.0. If a copy of the MPL was not distributed
8 // with this file, You can obtain one at http://mozilla.org/MPL/2.0/.
12 template<typename MatrixType
> void diagonalmatrices(const MatrixType
& m
)
14 typedef typename
MatrixType::Index Index
;
15 typedef typename
MatrixType::Scalar Scalar
;
16 enum { Rows
= MatrixType::RowsAtCompileTime
, Cols
= MatrixType::ColsAtCompileTime
};
17 typedef Matrix
<Scalar
, Rows
, 1> VectorType
;
18 typedef Matrix
<Scalar
, 1, Cols
> RowVectorType
;
19 typedef Matrix
<Scalar
, Rows
, Rows
> SquareMatrixType
;
20 typedef DiagonalMatrix
<Scalar
, Rows
> LeftDiagonalMatrix
;
21 typedef DiagonalMatrix
<Scalar
, Cols
> RightDiagonalMatrix
;
22 typedef Matrix
<Scalar
, Rows
==Dynamic
?Dynamic
:2*Rows
, Cols
==Dynamic
?Dynamic
:2*Cols
> BigMatrix
;
23 Index rows
= m
.rows();
24 Index cols
= m
.cols();
26 MatrixType m1
= MatrixType::Random(rows
, cols
),
27 m2
= MatrixType::Random(rows
, cols
);
28 VectorType v1
= VectorType::Random(rows
),
29 v2
= VectorType::Random(rows
);
30 RowVectorType rv1
= RowVectorType::Random(cols
),
31 rv2
= RowVectorType::Random(cols
);
32 LeftDiagonalMatrix
ldm1(v1
), ldm2(v2
);
33 RightDiagonalMatrix
rdm1(rv1
), rdm2(rv2
);
35 Scalar s1
= internal::random
<Scalar
>();
37 SquareMatrixType
sq_m1 (v1
.asDiagonal());
38 VERIFY_IS_APPROX(sq_m1
, v1
.asDiagonal().toDenseMatrix());
39 sq_m1
= v1
.asDiagonal();
40 VERIFY_IS_APPROX(sq_m1
, v1
.asDiagonal().toDenseMatrix());
41 SquareMatrixType sq_m2
= v1
.asDiagonal();
42 VERIFY_IS_APPROX(sq_m1
, sq_m2
);
44 ldm1
= v1
.asDiagonal();
45 LeftDiagonalMatrix
ldm3(v1
);
46 VERIFY_IS_APPROX(ldm1
.diagonal(), ldm3
.diagonal());
47 LeftDiagonalMatrix ldm4
= v1
.asDiagonal();
48 VERIFY_IS_APPROX(ldm1
.diagonal(), ldm4
.diagonal());
50 sq_m1
.block(0,0,rows
,rows
) = ldm1
;
51 VERIFY_IS_APPROX(sq_m1
, ldm1
.toDenseMatrix());
52 sq_m1
.transpose() = ldm1
;
53 VERIFY_IS_APPROX(sq_m1
, ldm1
.toDenseMatrix());
55 Index i
= internal::random
<Index
>(0, rows
-1);
56 Index j
= internal::random
<Index
>(0, cols
-1);
58 VERIFY_IS_APPROX( ((ldm1
* m1
)(i
,j
)) , ldm1
.diagonal()(i
) * m1(i
,j
) );
59 VERIFY_IS_APPROX( ((ldm1
* (m1
+m2
))(i
,j
)) , ldm1
.diagonal()(i
) * (m1
+m2
)(i
,j
) );
60 VERIFY_IS_APPROX( ((m1
* rdm1
)(i
,j
)) , rdm1
.diagonal()(j
) * m1(i
,j
) );
61 VERIFY_IS_APPROX( ((v1
.asDiagonal() * m1
)(i
,j
)) , v1(i
) * m1(i
,j
) );
62 VERIFY_IS_APPROX( ((m1
* rv1
.asDiagonal())(i
,j
)) , rv1(j
) * m1(i
,j
) );
63 VERIFY_IS_APPROX( (((v1
+v2
).asDiagonal() * m1
)(i
,j
)) , (v1
+v2
)(i
) * m1(i
,j
) );
64 VERIFY_IS_APPROX( (((v1
+v2
).asDiagonal() * (m1
+m2
))(i
,j
)) , (v1
+v2
)(i
) * (m1
+m2
)(i
,j
) );
65 VERIFY_IS_APPROX( ((m1
* (rv1
+rv2
).asDiagonal())(i
,j
)) , (rv1
+rv2
)(j
) * m1(i
,j
) );
66 VERIFY_IS_APPROX( (((m1
+m2
) * (rv1
+rv2
).asDiagonal())(i
,j
)) , (rv1
+rv2
)(j
) * (m1
+m2
)(i
,j
) );
69 big
.setZero(2*rows
, 2*cols
);
71 big
.block(i
,j
,rows
,cols
) = m1
;
72 big
.block(i
,j
,rows
,cols
) = v1
.asDiagonal() * big
.block(i
,j
,rows
,cols
);
74 VERIFY_IS_APPROX((big
.block(i
,j
,rows
,cols
)) , v1
.asDiagonal() * m1
);
76 big
.block(i
,j
,rows
,cols
) = m1
;
77 big
.block(i
,j
,rows
,cols
) = big
.block(i
,j
,rows
,cols
) * rv1
.asDiagonal();
78 VERIFY_IS_APPROX((big
.block(i
,j
,rows
,cols
)) , m1
* rv1
.asDiagonal() );
82 VERIFY_IS_APPROX(LeftDiagonalMatrix(ldm1
*s1
).diagonal(), ldm1
.diagonal() * s1
);
83 VERIFY_IS_APPROX(LeftDiagonalMatrix(s1
*ldm1
).diagonal(), s1
* ldm1
.diagonal());
85 VERIFY_IS_APPROX(m1
* (rdm1
* s1
), (m1
* rdm1
) * s1
);
86 VERIFY_IS_APPROX(m1
* (s1
* rdm1
), (m1
* rdm1
) * s1
);
89 void test_diagonalmatrices()
91 for(int i
= 0; i
< g_repeat
; i
++) {
92 CALL_SUBTEST_1( diagonalmatrices(Matrix
<float, 1, 1>()) );
93 CALL_SUBTEST_2( diagonalmatrices(Matrix3f()) );
94 CALL_SUBTEST_3( diagonalmatrices(Matrix
<double,3,3,RowMajor
>()) );
95 CALL_SUBTEST_4( diagonalmatrices(Matrix4d()) );
96 CALL_SUBTEST_5( diagonalmatrices(Matrix
<float,4,4,RowMajor
>()) );
97 CALL_SUBTEST_6( diagonalmatrices(MatrixXcf(internal::random
<int>(1,EIGEN_TEST_MAX_SIZE
), internal::random
<int>(1,EIGEN_TEST_MAX_SIZE
))) );
98 CALL_SUBTEST_7( diagonalmatrices(MatrixXi(internal::random
<int>(1,EIGEN_TEST_MAX_SIZE
), internal::random
<int>(1,EIGEN_TEST_MAX_SIZE
))) );
99 CALL_SUBTEST_8( diagonalmatrices(Matrix
<double,Dynamic
,Dynamic
,RowMajor
>(internal::random
<int>(1,EIGEN_TEST_MAX_SIZE
), internal::random
<int>(1,EIGEN_TEST_MAX_SIZE
))) );
100 CALL_SUBTEST_9( diagonalmatrices(MatrixXf(internal::random
<int>(1,EIGEN_TEST_MAX_SIZE
), internal::random
<int>(1,EIGEN_TEST_MAX_SIZE
))) );