00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
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
00037
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
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
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
00087
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
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 }