From b2b1a964235ea9d15e3b547660ce0a38eb88ddda Mon Sep 17 00:00:00 2001 From: nojhan Date: Sat, 12 Nov 2011 15:52:18 +0100 Subject: [PATCH] working robust cholesky factorization, with test binary --- edo/src/edoSamplerNormalMulti.h | 48 +++++++++------- edo/test/CMakeLists.txt | 1 + edo/test/t-cholesky.cpp | 97 +++++++++++++++++++++++++++++++++ 3 files changed, 126 insertions(+), 20 deletions(-) create mode 100644 edo/test/t-cholesky.cpp diff --git a/edo/src/edoSamplerNormalMulti.h b/edo/src/edoSamplerNormalMulti.h index c16c77ef..997b29c6 100644 --- a/edo/src/edoSamplerNormalMulti.h +++ b/edo/src/edoSamplerNormalMulti.h @@ -84,7 +84,7 @@ public: */ Cholesky(const MatrixType& V, Cholesky::Method use = standard ) : _use(use) { - factsorize( V ); + factorize( V ); } @@ -99,10 +99,19 @@ public: //! The decomposition of the covariance matrix const MatrixType & decomposition() const {return _L;} + /** When your using the LDLT robust decomposition (by passing the "robust" + * option to the constructor, @see factorize_LDTL), this is the diagonal + * matrix part. + */ + const MatrixType & diagonal() const {return _D;} + protected: //! The decomposition is a (lower) symetric matrix, just like the covariance matrix MatrixType _L; + + //! The diagonal matrix when using the LDLT factorization + MatrixType _D; /** Assert that the covariance matrix have the required properties and returns its dimension. @@ -243,37 +252,36 @@ public: } // for i in [1,N[ } - /** This alternative algorithm does not use square root BUT the covariance - * matrix must be invertible. + + /** This alternative algorithm do not use square root. * * Computes L and D such as V = L D Lt */ void factorize_LDLT( const MatrixType& V) { - unsigned int N = assert_properties( V ); + // use "int" everywhere, because of the "j-1" operation + int N = assert_properties( V ); + // example of an invertible matrix whose decomposition is undefined + assert( V(0,0) != 0 ); - unsigned int i, j, k; - //MatrixType D = ublas::zero_matrix(N); - std::vector _D(N,0); + _D = ublas::zero_matrix(N,N); + _D(0,0) = V(0,0); + + for( int j=0; j +*/ + +#include +#include +#include + +#include +#include +#include + +typedef eoReal< eoMinimizingFitness > EOT; +typedef edoNormalMulti EOD; + +std::ostream& operator<< (std::ostream& out, const ublas::symmetric_matrix< double, ublas::lower >& mat ) +{ + for( unsigned int i=0; i::Cholesky::MatrixType MatrixType; + + // a variance-covariance matrix of size N*N + MatrixType V(N,N); + + // random covariance matrix + for( unsigned int i=0; i 0 + for( unsigned int j=i+1; j::Cholesky LLT( edoSamplerNormalMulti::Cholesky::standard ); + edoSamplerNormalMulti::Cholesky LLTa( edoSamplerNormalMulti::Cholesky::absolute ); + edoSamplerNormalMulti::Cholesky LDLT( edoSamplerNormalMulti::Cholesky::robust ); + + MatrixType L0 = LLT(V); + std::cout << "LLT" << std::endl << L0 << std::endl; + MatrixType V0 = ublas::prod( L0, ublas::trans(L0) ); + std::cout << "LLT covar" << std::endl << V0 << std::endl; + std::cout << "-----------------------------------------------------------" << std::endl; + + MatrixType L1 = LLTa(V); + std::cout << "LLT abs" << std::endl << L1 << std::endl; + MatrixType V1 = ublas::prod( L1, ublas::trans(L1) ); + std::cout << "LLT covar" << std::endl << V1 << std::endl; + std::cout << "-----------------------------------------------------------" << std::endl; + + MatrixType L2 = LDLT(V); + MatrixType D2 = LDLT.diagonal(); + std::cout << "LDLT" << std::endl << L2 << std::endl; + // ublas do not allow nested products, we should use a temporary matrix, + // thus the inline instanciation of a MatrixType + // see: http://www.crystalclearsoftware.com/cgi-bin/boost_wiki/wiki.pl?Effective_UBLAS + MatrixType V2 = ublas::prod( MatrixType(ublas::prod( L2, D2 )), ublas::trans(L2) ); + std::cout << "LDLT covar" << std::endl << V2 << std::endl; + std::cout << "-----------------------------------------------------------" << std::endl; + +}