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 Matrix
<Scalar
, Dynamic
, Dynamic
> DynMatrixType
;
21 typedef DiagonalMatrix
<Scalar
, Rows
> LeftDiagonalMatrix
;
22 typedef DiagonalMatrix
<Scalar
, Cols
> RightDiagonalMatrix
;
23 typedef Matrix
<Scalar
, Rows
==Dynamic
?Dynamic
:2*Rows
, Cols
==Dynamic
?Dynamic
:2*Cols
> BigMatrix
;
24 Index rows
= m
.rows();
25 Index cols
= m
.cols();
27 MatrixType m1
= MatrixType::Random(rows
, cols
),
28 m2
= MatrixType::Random(rows
, cols
);
29 VectorType v1
= VectorType::Random(rows
),
30 v2
= VectorType::Random(rows
);
31 RowVectorType rv1
= RowVectorType::Random(cols
),
32 rv2
= RowVectorType::Random(cols
);
33 LeftDiagonalMatrix
ldm1(v1
), ldm2(v2
);
34 RightDiagonalMatrix
rdm1(rv1
), rdm2(rv2
);
36 Scalar s1
= internal::random
<Scalar
>();
38 SquareMatrixType
sq_m1 (v1
.asDiagonal());
39 VERIFY_IS_APPROX(sq_m1
, v1
.asDiagonal().toDenseMatrix());
40 sq_m1
= v1
.asDiagonal();
41 VERIFY_IS_APPROX(sq_m1
, v1
.asDiagonal().toDenseMatrix());
42 SquareMatrixType sq_m2
= v1
.asDiagonal();
43 VERIFY_IS_APPROX(sq_m1
, sq_m2
);
45 ldm1
= v1
.asDiagonal();
46 LeftDiagonalMatrix
ldm3(v1
);
47 VERIFY_IS_APPROX(ldm1
.diagonal(), ldm3
.diagonal());
48 LeftDiagonalMatrix ldm4
= v1
.asDiagonal();
49 VERIFY_IS_APPROX(ldm1
.diagonal(), ldm4
.diagonal());
51 sq_m1
.block(0,0,rows
,rows
) = ldm1
;
52 VERIFY_IS_APPROX(sq_m1
, ldm1
.toDenseMatrix());
53 sq_m1
.transpose() = ldm1
;
54 VERIFY_IS_APPROX(sq_m1
, ldm1
.toDenseMatrix());
56 Index i
= internal::random
<Index
>(0, rows
-1);
57 Index j
= internal::random
<Index
>(0, cols
-1);
59 VERIFY_IS_APPROX( ((ldm1
* m1
)(i
,j
)) , ldm1
.diagonal()(i
) * m1(i
,j
) );
60 VERIFY_IS_APPROX( ((ldm1
* (m1
+m2
))(i
,j
)) , ldm1
.diagonal()(i
) * (m1
+m2
)(i
,j
) );
61 VERIFY_IS_APPROX( ((m1
* rdm1
)(i
,j
)) , rdm1
.diagonal()(j
) * m1(i
,j
) );
62 VERIFY_IS_APPROX( ((v1
.asDiagonal() * m1
)(i
,j
)) , v1(i
) * m1(i
,j
) );
63 VERIFY_IS_APPROX( ((m1
* rv1
.asDiagonal())(i
,j
)) , rv1(j
) * m1(i
,j
) );
64 VERIFY_IS_APPROX( (((v1
+v2
).asDiagonal() * m1
)(i
,j
)) , (v1
+v2
)(i
) * m1(i
,j
) );
65 VERIFY_IS_APPROX( (((v1
+v2
).asDiagonal() * (m1
+m2
))(i
,j
)) , (v1
+v2
)(i
) * (m1
+m2
)(i
,j
) );
66 VERIFY_IS_APPROX( ((m1
* (rv1
+rv2
).asDiagonal())(i
,j
)) , (rv1
+rv2
)(j
) * m1(i
,j
) );
67 VERIFY_IS_APPROX( (((m1
+m2
) * (rv1
+rv2
).asDiagonal())(i
,j
)) , (rv1
+rv2
)(j
) * (m1
+m2
)(i
,j
) );
71 DynMatrixType tmp
= m1
.topRows(rows
/2), res
;
72 VERIFY_IS_APPROX( (res
= m1
.topRows(rows
/2) * rv1
.asDiagonal()), tmp
* rv1
.asDiagonal() );
73 VERIFY_IS_APPROX( (res
= v1
.head(rows
/2).asDiagonal()*m1
.topRows(rows
/2)), v1
.head(rows
/2).asDiagonal()*tmp
);
77 big
.setZero(2*rows
, 2*cols
);
79 big
.block(i
,j
,rows
,cols
) = m1
;
80 big
.block(i
,j
,rows
,cols
) = v1
.asDiagonal() * big
.block(i
,j
,rows
,cols
);
82 VERIFY_IS_APPROX((big
.block(i
,j
,rows
,cols
)) , v1
.asDiagonal() * m1
);
84 big
.block(i
,j
,rows
,cols
) = m1
;
85 big
.block(i
,j
,rows
,cols
) = big
.block(i
,j
,rows
,cols
) * rv1
.asDiagonal();
86 VERIFY_IS_APPROX((big
.block(i
,j
,rows
,cols
)) , m1
* rv1
.asDiagonal() );
90 VERIFY_IS_APPROX(LeftDiagonalMatrix(ldm1
*s1
).diagonal(), ldm1
.diagonal() * s1
);
91 VERIFY_IS_APPROX(LeftDiagonalMatrix(s1
*ldm1
).diagonal(), s1
* ldm1
.diagonal());
93 VERIFY_IS_APPROX(m1
* (rdm1
* s1
), (m1
* rdm1
) * s1
);
94 VERIFY_IS_APPROX(m1
* (s1
* rdm1
), (m1
* rdm1
) * s1
);
99 VERIFY_IS_APPROX( (sq_m1
+= (s1
*v1
).asDiagonal()), sq_m2
+= (s1
*v1
).asDiagonal().toDenseMatrix() );
100 VERIFY_IS_APPROX( (sq_m1
-= (s1
*v1
).asDiagonal()), sq_m2
-= (s1
*v1
).asDiagonal().toDenseMatrix() );
101 VERIFY_IS_APPROX( (sq_m1
= (s1
*v1
).asDiagonal()), (s1
*v1
).asDiagonal().toDenseMatrix() );
107 Matrix3Xd points
= Matrix3Xd::Random(3, 3);
108 Vector2d diag
= Vector2d::Random();
109 Matrix2Xd tmp1
= points
.topRows
<2>(), res1
, res2
;
110 VERIFY_IS_APPROX( res1
= diag
.asDiagonal() * points
.topRows
<2>(), res2
= diag
.asDiagonal() * tmp1
);
111 Matrix2d tmp2
= points
.topLeftCorner
<2,2>();
112 VERIFY_IS_APPROX(( res1
= points
.topLeftCorner
<2,2>()*diag
.asDiagonal()) , res2
= tmp2
*diag
.asDiagonal() );
115 void test_diagonalmatrices()
117 for(int i
= 0; i
< g_repeat
; i
++) {
118 CALL_SUBTEST_1( diagonalmatrices(Matrix
<float, 1, 1>()) );
119 CALL_SUBTEST_2( diagonalmatrices(Matrix3f()) );
120 CALL_SUBTEST_3( diagonalmatrices(Matrix
<double,3,3,RowMajor
>()) );
121 CALL_SUBTEST_4( diagonalmatrices(Matrix4d()) );
122 CALL_SUBTEST_5( diagonalmatrices(Matrix
<float,4,4,RowMajor
>()) );
123 CALL_SUBTEST_6( diagonalmatrices(MatrixXcf(internal::random
<int>(1,EIGEN_TEST_MAX_SIZE
), internal::random
<int>(1,EIGEN_TEST_MAX_SIZE
))) );
124 CALL_SUBTEST_7( diagonalmatrices(MatrixXi(internal::random
<int>(1,EIGEN_TEST_MAX_SIZE
), internal::random
<int>(1,EIGEN_TEST_MAX_SIZE
))) );
125 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
))) );
126 CALL_SUBTEST_9( diagonalmatrices(MatrixXf(internal::random
<int>(1,EIGEN_TEST_MAX_SIZE
), internal::random
<int>(1,EIGEN_TEST_MAX_SIZE
))) );
128 CALL_SUBTEST_10( bug987
<0>() );