1 // This file is part of Eigen, a lightweight C++ template library
4 // Copyright (C) 2016 Gael Guennebaud <gael.guennebaud@inria.fr>
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 #include <Eigen/Cholesky>
15 // This file test inplace decomposition through Ref<>, as supported by Cholesky, LU, and QR decompositions.
17 template<typename DecType
,typename MatrixType
> void inplace(bool square
= false, bool SPD
= false)
19 typedef typename
MatrixType::Scalar Scalar
;
20 typedef Matrix
<Scalar
, MatrixType::RowsAtCompileTime
, 1> RhsType
;
21 typedef Matrix
<Scalar
, MatrixType::ColsAtCompileTime
, 1> ResType
;
23 Index rows
= MatrixType::RowsAtCompileTime
==Dynamic
? internal::random
<Index
>(2,EIGEN_TEST_MAX_SIZE
/2) : Index(MatrixType::RowsAtCompileTime
);
24 Index cols
= MatrixType::ColsAtCompileTime
==Dynamic
? (square
?rows
:internal::random
<Index
>(2,rows
)) : Index(MatrixType::ColsAtCompileTime
);
26 MatrixType A
= MatrixType::Random(rows
,cols
);
27 RhsType b
= RhsType::Random(rows
);
33 A
.topRows(cols
) = A
.topRows(cols
).adjoint() * A
.topRows(cols
);
34 A
.diagonal().array() += 1e-3;
42 // Check that the content of A has been modified
43 VERIFY_IS_NOT_APPROX( A
, A0
);
45 // Check that the decomposition is correct:
48 VERIFY_IS_APPROX( A0
* (x
= dec
.solve(b
)), b
);
52 VERIFY_IS_APPROX( A0
.transpose() * A0
* (x
= dec
.solve(b
)), A0
.transpose() * b
);
55 // Check that modifying A breaks the current dec:
59 VERIFY_IS_NOT_APPROX( A0
* (x
= dec
.solve(b
)), b
);
63 VERIFY_IS_NOT_APPROX( A0
.transpose() * A0
* (x
= dec
.solve(b
)), A0
.transpose() * b
);
66 // Check that calling compute(A1) does not modify A1:
69 VERIFY_IS_EQUAL(A0
,A1
);
70 VERIFY_IS_NOT_APPROX( A
, A0
);
73 VERIFY_IS_APPROX( A0
* (x
= dec
.solve(b
)), b
);
77 VERIFY_IS_APPROX( A0
.transpose() * A0
* (x
= dec
.solve(b
)), A0
.transpose() * b
);
82 void test_inplace_decomposition()
84 EIGEN_UNUSED
typedef Matrix
<double,4,3> Matrix43d
;
85 for(int i
= 0; i
< g_repeat
; i
++) {
86 CALL_SUBTEST_1(( inplace
<LLT
<Ref
<MatrixXd
> >, MatrixXd
>(true,true) ));
87 CALL_SUBTEST_1(( inplace
<LLT
<Ref
<Matrix4d
> >, Matrix4d
>(true,true) ));
89 CALL_SUBTEST_2(( inplace
<LDLT
<Ref
<MatrixXd
> >, MatrixXd
>(true,true) ));
90 CALL_SUBTEST_2(( inplace
<LDLT
<Ref
<Matrix4d
> >, Matrix4d
>(true,true) ));
92 CALL_SUBTEST_3(( inplace
<PartialPivLU
<Ref
<MatrixXd
> >, MatrixXd
>(true,false) ));
93 CALL_SUBTEST_3(( inplace
<PartialPivLU
<Ref
<Matrix4d
> >, Matrix4d
>(true,false) ));
95 CALL_SUBTEST_4(( inplace
<FullPivLU
<Ref
<MatrixXd
> >, MatrixXd
>(true,false) ));
96 CALL_SUBTEST_4(( inplace
<FullPivLU
<Ref
<Matrix4d
> >, Matrix4d
>(true,false) ));
98 CALL_SUBTEST_5(( inplace
<HouseholderQR
<Ref
<MatrixXd
> >, MatrixXd
>(false,false) ));
99 CALL_SUBTEST_5(( inplace
<HouseholderQR
<Ref
<Matrix43d
> >, Matrix43d
>(false,false) ));
101 CALL_SUBTEST_6(( inplace
<ColPivHouseholderQR
<Ref
<MatrixXd
> >, MatrixXd
>(false,false) ));
102 CALL_SUBTEST_6(( inplace
<ColPivHouseholderQR
<Ref
<Matrix43d
> >, Matrix43d
>(false,false) ));
104 CALL_SUBTEST_7(( inplace
<FullPivHouseholderQR
<Ref
<MatrixXd
> >, MatrixXd
>(false,false) ));
105 CALL_SUBTEST_7(( inplace
<FullPivHouseholderQR
<Ref
<Matrix43d
> >, Matrix43d
>(false,false) ));
107 CALL_SUBTEST_8(( inplace
<CompleteOrthogonalDecomposition
<Ref
<MatrixXd
> >, MatrixXd
>(false,false) ));
108 CALL_SUBTEST_8(( inplace
<CompleteOrthogonalDecomposition
<Ref
<Matrix43d
> >, Matrix43d
>(false,false) ));