You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

113 lines
3.5 KiB

  1. // This file is part of Eigen, a lightweight C++ template library
  2. // for linear algebra. Eigen itself is part of the KDE project.
  3. //
  4. // Copyright (C) 2008 Gael Guennebaud <g.gael@free.fr>
  5. //
  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/.
  9. #define EIGEN_NO_ASSERTION_CHECKING
  10. #include "main.h"
  11. #include <Eigen/Cholesky>
  12. #include <Eigen/LU>
  13. #ifdef HAS_GSL
  14. #include "gsl_helper.h"
  15. #endif
  16. template<typename MatrixType> void cholesky(const MatrixType& m)
  17. {
  18. /* this test covers the following files:
  19. LLT.h LDLT.h
  20. */
  21. int rows = m.rows();
  22. int cols = m.cols();
  23. typedef typename MatrixType::Scalar Scalar;
  24. typedef typename NumTraits<Scalar>::Real RealScalar;
  25. typedef Matrix<Scalar, MatrixType::RowsAtCompileTime, MatrixType::RowsAtCompileTime> SquareMatrixType;
  26. typedef Matrix<Scalar, MatrixType::RowsAtCompileTime, 1> VectorType;
  27. MatrixType a0 = MatrixType::Random(rows,cols);
  28. VectorType vecB = VectorType::Random(rows), vecX(rows);
  29. MatrixType matB = MatrixType::Random(rows,cols), matX(rows,cols);
  30. SquareMatrixType symm = a0 * a0.adjoint();
  31. // let's make sure the matrix is not singular or near singular
  32. MatrixType a1 = MatrixType::Random(rows,cols);
  33. symm += a1 * a1.adjoint();
  34. #ifdef HAS_GSL
  35. if (ei_is_same_type<RealScalar,double>::ret)
  36. {
  37. typedef GslTraits<Scalar> Gsl;
  38. typename Gsl::Matrix gMatA=0, gSymm=0;
  39. typename Gsl::Vector gVecB=0, gVecX=0;
  40. convert<MatrixType>(symm, gSymm);
  41. convert<MatrixType>(symm, gMatA);
  42. convert<VectorType>(vecB, gVecB);
  43. convert<VectorType>(vecB, gVecX);
  44. Gsl::cholesky(gMatA);
  45. Gsl::cholesky_solve(gMatA, gVecB, gVecX);
  46. VectorType vecX(rows), _vecX, _vecB;
  47. convert(gVecX, _vecX);
  48. symm.llt().solve(vecB, &vecX);
  49. Gsl::prod(gSymm, gVecX, gVecB);
  50. convert(gVecB, _vecB);
  51. // test gsl itself !
  52. VERIFY_IS_APPROX(vecB, _vecB);
  53. VERIFY_IS_APPROX(vecX, _vecX);
  54. Gsl::free(gMatA);
  55. Gsl::free(gSymm);
  56. Gsl::free(gVecB);
  57. Gsl::free(gVecX);
  58. }
  59. #endif
  60. {
  61. LDLT<SquareMatrixType> ldlt(symm);
  62. VERIFY(ldlt.isPositiveDefinite());
  63. // in eigen3, LDLT is pivoting
  64. //VERIFY_IS_APPROX(symm, ldlt.matrixL() * ldlt.vectorD().asDiagonal() * ldlt.matrixL().adjoint());
  65. ldlt.solve(vecB, &vecX);
  66. VERIFY_IS_APPROX(symm * vecX, vecB);
  67. ldlt.solve(matB, &matX);
  68. VERIFY_IS_APPROX(symm * matX, matB);
  69. }
  70. {
  71. LLT<SquareMatrixType> chol(symm);
  72. VERIFY(chol.isPositiveDefinite());
  73. VERIFY_IS_APPROX(symm, chol.matrixL() * chol.matrixL().adjoint());
  74. chol.solve(vecB, &vecX);
  75. VERIFY_IS_APPROX(symm * vecX, vecB);
  76. chol.solve(matB, &matX);
  77. VERIFY_IS_APPROX(symm * matX, matB);
  78. }
  79. #if 0 // cholesky is not rank-revealing anyway
  80. // test isPositiveDefinite on non definite matrix
  81. if (rows>4)
  82. {
  83. SquareMatrixType symm = a0.block(0,0,rows,cols-4) * a0.block(0,0,rows,cols-4).adjoint();
  84. LLT<SquareMatrixType> chol(symm);
  85. VERIFY(!chol.isPositiveDefinite());
  86. LDLT<SquareMatrixType> cholnosqrt(symm);
  87. VERIFY(!cholnosqrt.isPositiveDefinite());
  88. }
  89. #endif
  90. }
  91. void test_eigen2_cholesky()
  92. {
  93. for(int i = 0; i < g_repeat; i++) {
  94. CALL_SUBTEST_1( cholesky(Matrix<double,1,1>()) );
  95. CALL_SUBTEST_2( cholesky(Matrix2d()) );
  96. CALL_SUBTEST_3( cholesky(Matrix3f()) );
  97. CALL_SUBTEST_4( cholesky(Matrix4d()) );
  98. CALL_SUBTEST_5( cholesky(MatrixXcd(7,7)) );
  99. CALL_SUBTEST_6( cholesky(MatrixXf(17,17)) );
  100. CALL_SUBTEST_7( cholesky(MatrixXd(33,33)) );
  101. }
  102. }