eigen2_cholesky.cpp
Go to the documentation of this file.
00001 // This file is part of Eigen, a lightweight C++ template library
00002 // for linear algebra. Eigen itself is part of the KDE project.
00003 //
00004 // Copyright (C) 2008 Gael Guennebaud <g.gael@free.fr>
00005 //
00006 // Eigen is free software; you can redistribute it and/or
00007 // modify it under the terms of the GNU Lesser General Public
00008 // License as published by the Free Software Foundation; either
00009 // version 3 of the License, or (at your option) any later version.
00010 //
00011 // Alternatively, you can redistribute it and/or
00012 // modify it under the terms of the GNU General Public License as
00013 // published by the Free Software Foundation; either version 2 of
00014 // the License, or (at your option) any later version.
00015 //
00016 // Eigen is distributed in the hope that it will be useful, but WITHOUT ANY
00017 // WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
00018 // FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License or the
00019 // GNU General Public License for more details.
00020 //
00021 // You should have received a copy of the GNU Lesser General Public
00022 // License and a copy of the GNU General Public License along with
00023 // Eigen. If not, see <http://www.gnu.org/licenses/>.
00024 
00025 #define EIGEN_NO_ASSERTION_CHECKING
00026 #include "main.h"
00027 #include <Eigen/Cholesky>
00028 #include <Eigen/LU>
00029 
00030 #ifdef HAS_GSL
00031 #include "gsl_helper.h"
00032 #endif
00033 
00034 template<typename MatrixType> void cholesky(const MatrixType& m)
00035 {
00036   /* this test covers the following files:
00037      LLT.h LDLT.h
00038   */
00039   int rows = m.rows();
00040   int cols = m.cols();
00041 
00042   typedef typename MatrixType::Scalar Scalar;
00043   typedef typename NumTraits<Scalar>::Real RealScalar;
00044   typedef Matrix<Scalar, MatrixType::RowsAtCompileTime, MatrixType::RowsAtCompileTime> SquareMatrixType;
00045   typedef Matrix<Scalar, MatrixType::RowsAtCompileTime, 1> VectorType;
00046 
00047   MatrixType a0 = MatrixType::Random(rows,cols);
00048   VectorType vecB = VectorType::Random(rows), vecX(rows);
00049   MatrixType matB = MatrixType::Random(rows,cols), matX(rows,cols);
00050   SquareMatrixType symm =  a0 * a0.adjoint();
00051   // let's make sure the matrix is not singular or near singular
00052   MatrixType a1 = MatrixType::Random(rows,cols);
00053   symm += a1 * a1.adjoint();
00054 
00055   #ifdef HAS_GSL
00056   if (ei_is_same_type<RealScalar,double>::ret)
00057   {
00058     typedef GslTraits<Scalar> Gsl;
00059     typename Gsl::Matrix gMatA=0, gSymm=0;
00060     typename Gsl::Vector gVecB=0, gVecX=0;
00061     convert<MatrixType>(symm, gSymm);
00062     convert<MatrixType>(symm, gMatA);
00063     convert<VectorType>(vecB, gVecB);
00064     convert<VectorType>(vecB, gVecX);
00065     Gsl::cholesky(gMatA);
00066     Gsl::cholesky_solve(gMatA, gVecB, gVecX);
00067     VectorType vecX(rows), _vecX, _vecB;
00068     convert(gVecX, _vecX);
00069     symm.llt().solve(vecB, &vecX);
00070     Gsl::prod(gSymm, gVecX, gVecB);
00071     convert(gVecB, _vecB);
00072     // test gsl itself !
00073     VERIFY_IS_APPROX(vecB, _vecB);
00074     VERIFY_IS_APPROX(vecX, _vecX);
00075 
00076     Gsl::free(gMatA);
00077     Gsl::free(gSymm);
00078     Gsl::free(gVecB);
00079     Gsl::free(gVecX);
00080   }
00081   #endif
00082 
00083   {
00084     LDLT<SquareMatrixType> ldlt(symm);
00085     VERIFY(ldlt.isPositiveDefinite());
00086     // in eigen3, LDLT is pivoting
00087     //VERIFY_IS_APPROX(symm, ldlt.matrixL() * ldlt.vectorD().asDiagonal() * ldlt.matrixL().adjoint());
00088     ldlt.solve(vecB, &vecX);
00089     VERIFY_IS_APPROX(symm * vecX, vecB);
00090     ldlt.solve(matB, &matX);
00091     VERIFY_IS_APPROX(symm * matX, matB);
00092   }
00093 
00094   {
00095     LLT<SquareMatrixType> chol(symm);
00096     VERIFY(chol.isPositiveDefinite());
00097     VERIFY_IS_APPROX(symm, chol.matrixL() * chol.matrixL().adjoint());
00098     chol.solve(vecB, &vecX);
00099     VERIFY_IS_APPROX(symm * vecX, vecB);
00100     chol.solve(matB, &matX);
00101     VERIFY_IS_APPROX(symm * matX, matB);
00102   }
00103 
00104 #if 0 // cholesky is not rank-revealing anyway
00105   // test isPositiveDefinite on non definite matrix
00106   if (rows>4)
00107   {
00108     SquareMatrixType symm =  a0.block(0,0,rows,cols-4) * a0.block(0,0,rows,cols-4).adjoint();
00109     LLT<SquareMatrixType> chol(symm);
00110     VERIFY(!chol.isPositiveDefinite());
00111     LDLT<SquareMatrixType> cholnosqrt(symm);
00112     VERIFY(!cholnosqrt.isPositiveDefinite());
00113   }
00114 #endif
00115 }
00116 
00117 void test_eigen2_cholesky()
00118 {
00119   for(int i = 0; i < g_repeat; i++) {
00120     CALL_SUBTEST_1( cholesky(Matrix<double,1,1>()) );
00121     CALL_SUBTEST_2( cholesky(Matrix2d()) );
00122     CALL_SUBTEST_3( cholesky(Matrix3f()) );
00123     CALL_SUBTEST_4( cholesky(Matrix4d()) );
00124     CALL_SUBTEST_5( cholesky(MatrixXcd(7,7)) );
00125     CALL_SUBTEST_6( cholesky(MatrixXf(17,17)) );
00126     CALL_SUBTEST_7( cholesky(MatrixXd(33,33)) );
00127   }
00128 }


libicr
Author(s): Robert Krug
autogenerated on Mon Jan 6 2014 11:32:38