xref: /aosp_15_r20/external/eigen/test/inplace_decomposition.cpp (revision bf2c37156dfe67e5dfebd6d394bad8b2ab5804d4)
1*bf2c3715SXin Li // This file is part of Eigen, a lightweight C++ template library
2*bf2c3715SXin Li // for linear algebra.
3*bf2c3715SXin Li //
4*bf2c3715SXin Li // Copyright (C) 2016 Gael Guennebaud <[email protected]>
5*bf2c3715SXin Li //
6*bf2c3715SXin Li // This Source Code Form is subject to the terms of the Mozilla
7*bf2c3715SXin Li // Public License v. 2.0. If a copy of the MPL was not distributed
8*bf2c3715SXin Li // with this file, You can obtain one at http://mozilla.org/MPL/2.0/.
9*bf2c3715SXin Li 
10*bf2c3715SXin Li #include "main.h"
11*bf2c3715SXin Li #include <Eigen/LU>
12*bf2c3715SXin Li #include <Eigen/Cholesky>
13*bf2c3715SXin Li #include <Eigen/QR>
14*bf2c3715SXin Li 
15*bf2c3715SXin Li // This file test inplace decomposition through Ref<>, as supported by Cholesky, LU, and QR decompositions.
16*bf2c3715SXin Li 
inplace(bool square=false,bool SPD=false)17*bf2c3715SXin Li template<typename DecType,typename MatrixType> void inplace(bool square = false, bool SPD = false)
18*bf2c3715SXin Li {
19*bf2c3715SXin Li   typedef typename MatrixType::Scalar Scalar;
20*bf2c3715SXin Li   typedef Matrix<Scalar, MatrixType::RowsAtCompileTime, 1> RhsType;
21*bf2c3715SXin Li   typedef Matrix<Scalar, MatrixType::ColsAtCompileTime, 1> ResType;
22*bf2c3715SXin Li 
23*bf2c3715SXin Li   Index rows = MatrixType::RowsAtCompileTime==Dynamic ? internal::random<Index>(2,EIGEN_TEST_MAX_SIZE/2) : Index(MatrixType::RowsAtCompileTime);
24*bf2c3715SXin Li   Index cols = MatrixType::ColsAtCompileTime==Dynamic ? (square?rows:internal::random<Index>(2,rows))    : Index(MatrixType::ColsAtCompileTime);
25*bf2c3715SXin Li 
26*bf2c3715SXin Li   MatrixType A = MatrixType::Random(rows,cols);
27*bf2c3715SXin Li   RhsType b = RhsType::Random(rows);
28*bf2c3715SXin Li   ResType x(cols);
29*bf2c3715SXin Li 
30*bf2c3715SXin Li   if(SPD)
31*bf2c3715SXin Li   {
32*bf2c3715SXin Li     assert(square);
33*bf2c3715SXin Li     A.topRows(cols) = A.topRows(cols).adjoint() * A.topRows(cols);
34*bf2c3715SXin Li     A.diagonal().array() += 1e-3;
35*bf2c3715SXin Li   }
36*bf2c3715SXin Li 
37*bf2c3715SXin Li   MatrixType A0 = A;
38*bf2c3715SXin Li   MatrixType A1 = A;
39*bf2c3715SXin Li 
40*bf2c3715SXin Li   DecType dec(A);
41*bf2c3715SXin Li 
42*bf2c3715SXin Li   // Check that the content of A has been modified
43*bf2c3715SXin Li   VERIFY_IS_NOT_APPROX( A, A0 );
44*bf2c3715SXin Li 
45*bf2c3715SXin Li   // Check that the decomposition is correct:
46*bf2c3715SXin Li   if(rows==cols)
47*bf2c3715SXin Li   {
48*bf2c3715SXin Li     VERIFY_IS_APPROX( A0 * (x = dec.solve(b)), b );
49*bf2c3715SXin Li   }
50*bf2c3715SXin Li   else
51*bf2c3715SXin Li   {
52*bf2c3715SXin Li     VERIFY_IS_APPROX( A0.transpose() * A0 * (x = dec.solve(b)), A0.transpose() * b );
53*bf2c3715SXin Li   }
54*bf2c3715SXin Li 
55*bf2c3715SXin Li   // Check that modifying A breaks the current dec:
56*bf2c3715SXin Li   A.setRandom();
57*bf2c3715SXin Li   if(rows==cols)
58*bf2c3715SXin Li   {
59*bf2c3715SXin Li     VERIFY_IS_NOT_APPROX( A0 * (x = dec.solve(b)), b );
60*bf2c3715SXin Li   }
61*bf2c3715SXin Li   else
62*bf2c3715SXin Li   {
63*bf2c3715SXin Li     VERIFY_IS_NOT_APPROX( A0.transpose() * A0 * (x = dec.solve(b)), A0.transpose() * b );
64*bf2c3715SXin Li   }
65*bf2c3715SXin Li 
66*bf2c3715SXin Li   // Check that calling compute(A1) does not modify A1:
67*bf2c3715SXin Li   A = A0;
68*bf2c3715SXin Li   dec.compute(A1);
69*bf2c3715SXin Li   VERIFY_IS_EQUAL(A0,A1);
70*bf2c3715SXin Li   VERIFY_IS_NOT_APPROX( A, A0 );
71*bf2c3715SXin Li   if(rows==cols)
72*bf2c3715SXin Li   {
73*bf2c3715SXin Li     VERIFY_IS_APPROX( A0 * (x = dec.solve(b)), b );
74*bf2c3715SXin Li   }
75*bf2c3715SXin Li   else
76*bf2c3715SXin Li   {
77*bf2c3715SXin Li     VERIFY_IS_APPROX( A0.transpose() * A0 * (x = dec.solve(b)), A0.transpose() * b );
78*bf2c3715SXin Li   }
79*bf2c3715SXin Li }
80*bf2c3715SXin Li 
81*bf2c3715SXin Li 
EIGEN_DECLARE_TEST(inplace_decomposition)82*bf2c3715SXin Li EIGEN_DECLARE_TEST(inplace_decomposition)
83*bf2c3715SXin Li {
84*bf2c3715SXin Li   EIGEN_UNUSED typedef Matrix<double,4,3> Matrix43d;
85*bf2c3715SXin Li   for(int i = 0; i < g_repeat; i++) {
86*bf2c3715SXin Li     CALL_SUBTEST_1(( inplace<LLT<Ref<MatrixXd> >, MatrixXd>(true,true) ));
87*bf2c3715SXin Li     CALL_SUBTEST_1(( inplace<LLT<Ref<Matrix4d> >, Matrix4d>(true,true) ));
88*bf2c3715SXin Li 
89*bf2c3715SXin Li     CALL_SUBTEST_2(( inplace<LDLT<Ref<MatrixXd> >, MatrixXd>(true,true) ));
90*bf2c3715SXin Li     CALL_SUBTEST_2(( inplace<LDLT<Ref<Matrix4d> >, Matrix4d>(true,true) ));
91*bf2c3715SXin Li 
92*bf2c3715SXin Li     CALL_SUBTEST_3(( inplace<PartialPivLU<Ref<MatrixXd> >, MatrixXd>(true,false) ));
93*bf2c3715SXin Li     CALL_SUBTEST_3(( inplace<PartialPivLU<Ref<Matrix4d> >, Matrix4d>(true,false) ));
94*bf2c3715SXin Li 
95*bf2c3715SXin Li     CALL_SUBTEST_4(( inplace<FullPivLU<Ref<MatrixXd> >, MatrixXd>(true,false) ));
96*bf2c3715SXin Li     CALL_SUBTEST_4(( inplace<FullPivLU<Ref<Matrix4d> >, Matrix4d>(true,false) ));
97*bf2c3715SXin Li 
98*bf2c3715SXin Li     CALL_SUBTEST_5(( inplace<HouseholderQR<Ref<MatrixXd> >, MatrixXd>(false,false) ));
99*bf2c3715SXin Li     CALL_SUBTEST_5(( inplace<HouseholderQR<Ref<Matrix43d> >, Matrix43d>(false,false) ));
100*bf2c3715SXin Li 
101*bf2c3715SXin Li     CALL_SUBTEST_6(( inplace<ColPivHouseholderQR<Ref<MatrixXd> >, MatrixXd>(false,false) ));
102*bf2c3715SXin Li     CALL_SUBTEST_6(( inplace<ColPivHouseholderQR<Ref<Matrix43d> >, Matrix43d>(false,false) ));
103*bf2c3715SXin Li 
104*bf2c3715SXin Li     CALL_SUBTEST_7(( inplace<FullPivHouseholderQR<Ref<MatrixXd> >, MatrixXd>(false,false) ));
105*bf2c3715SXin Li     CALL_SUBTEST_7(( inplace<FullPivHouseholderQR<Ref<Matrix43d> >, Matrix43d>(false,false) ));
106*bf2c3715SXin Li 
107*bf2c3715SXin Li     CALL_SUBTEST_8(( inplace<CompleteOrthogonalDecomposition<Ref<MatrixXd> >, MatrixXd>(false,false) ));
108*bf2c3715SXin Li     CALL_SUBTEST_8(( inplace<CompleteOrthogonalDecomposition<Ref<Matrix43d> >, Matrix43d>(false,false) ));
109*bf2c3715SXin Li   }
110*bf2c3715SXin Li }
111