BUGFIX: factorized matrix are not symetric, cholesky factorization should process different types for covariance and decomposition + better format output for cholesky test
This commit is contained in:
parent
e0f691c148
commit
fe2cebc0e8
2 changed files with 110 additions and 54 deletions
|
|
@ -28,6 +28,9 @@ Authors:
|
|||
#include <vector>
|
||||
#include <cstdlib>
|
||||
#include <iostream>
|
||||
#include <sstream>
|
||||
#include <limits>
|
||||
#include <iomanip>
|
||||
|
||||
#include <eo>
|
||||
#include <es.h>
|
||||
|
|
@ -36,26 +39,73 @@ Authors:
|
|||
typedef eoReal< eoMinimizingFitness > EOT;
|
||||
typedef edoNormalMulti<EOT> EOD;
|
||||
|
||||
std::ostream& operator<< (std::ostream& out, const ublas::symmetric_matrix< double, ublas::lower >& mat )
|
||||
|
||||
void setformat( std::ostream& out )
|
||||
{
|
||||
out << std::right;
|
||||
out << std::setfill(' ');
|
||||
out << std::setw( 5 + std::numeric_limits<double>::digits10);
|
||||
out << std::setprecision(std::numeric_limits<double>::digits10);
|
||||
out << std::setiosflags(std::ios_base::showpoint);
|
||||
}
|
||||
|
||||
|
||||
template<typename MT>
|
||||
std::string format(const MT& mat )
|
||||
{
|
||||
std::ostringstream out;
|
||||
setformat(out);
|
||||
|
||||
for( unsigned int i=0; i<mat.size1(); ++i) {
|
||||
for( unsigned int j=0; j<=i; ++j) {
|
||||
for( unsigned int j=0; j<mat.size2(); ++j) {
|
||||
out << mat(i,j) << "\t";
|
||||
} // columns
|
||||
out << std::endl;
|
||||
} // rows
|
||||
|
||||
return out;
|
||||
return out.str();
|
||||
}
|
||||
|
||||
|
||||
template< typename T >
|
||||
T round( T val, T prec = 1.0 )
|
||||
{
|
||||
return (val > 0.0) ?
|
||||
floor(val * prec + 0.5) / prec :
|
||||
ceil(val * prec - 0.5) / prec ;
|
||||
}
|
||||
|
||||
|
||||
template<typename MT>
|
||||
bool equal( const MT& M1, const MT& M2, double prec /* = 1/std::numeric_limits<double>::digits10 ???*/ )
|
||||
{
|
||||
if( M1.size1() != M2.size1() || M1.size2() != M2.size2() ) {
|
||||
return false;
|
||||
}
|
||||
|
||||
for( unsigned int i=0; i<M1.size1(); ++i ) {
|
||||
for( unsigned int j=0; j<M1.size2(); ++j ) {
|
||||
if( round(M1(i,j),prec) != round(M2(i,j),prec) ) {
|
||||
std::cout << "round(M(" << i << "," << j << "," << prec << ") == "
|
||||
<< round(M1(i,j),prec) << " != " << round(M2(i,j),prec) << std::endl;
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
int main(int argc, char** argv)
|
||||
{
|
||||
unsigned int N = 4;
|
||||
|
||||
typedef edoSamplerNormalMulti<EOT,EOD>::Cholesky::MatrixType MatrixType;
|
||||
typedef edoSamplerNormalMulti<EOT,EOD>::Cholesky::CovarMat CovarMat;
|
||||
typedef edoSamplerNormalMulti<EOT,EOD>::Cholesky::FactorMat FactorMat;
|
||||
|
||||
// a variance-covariance matrix of size N*N
|
||||
MatrixType V(N,N);
|
||||
CovarMat V(N,N);
|
||||
|
||||
// random covariance matrix
|
||||
for( unsigned int i=0; i<N; ++i) {
|
||||
|
|
@ -65,29 +115,35 @@ int main(int argc, char** argv)
|
|||
}
|
||||
}
|
||||
|
||||
std::cout << "Covariance matrix" << std::endl << V << std::endl;
|
||||
std::cout << "-----------------------------------------------------------" << std::endl;
|
||||
double precision = 1e-15;
|
||||
setformat(std::cout);
|
||||
std::string linesep = "--------------------------------------------------------------------------------------------";
|
||||
|
||||
std::cout << "Covariance matrix" << std::endl << format(V) << std::endl;
|
||||
std::cout << linesep << std::endl;
|
||||
|
||||
edoSamplerNormalMulti<EOT,EOD>::Cholesky LLT( edoSamplerNormalMulti<EOT,EOD>::Cholesky::standard );
|
||||
FactorMat L0 = LLT(V);
|
||||
std::cout << "LLT" << std::endl << format(L0) << std::endl;
|
||||
CovarMat V0 = ublas::prod( L0, ublas::trans(L0) );
|
||||
std::cout << "LLT covar" << std::endl << format(V0) << std::endl;
|
||||
assert( equal(V0,V,precision) );
|
||||
std::cout << linesep << std::endl;
|
||||
|
||||
edoSamplerNormalMulti<EOT,EOD>::Cholesky LLTa( edoSamplerNormalMulti<EOT,EOD>::Cholesky::absolute );
|
||||
edoSamplerNormalMulti<EOT,EOD>::Cholesky LDLT( edoSamplerNormalMulti<EOT,EOD>::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;
|
||||
FactorMat L1 = LLTa(V);
|
||||
std::cout << "LLT abs" << std::endl << format(L1) << std::endl;
|
||||
CovarMat V1 = ublas::prod( L1, ublas::trans(L1) );
|
||||
std::cout << "LLT covar" << std::endl << format(V1) << std::endl;
|
||||
assert( equal(V1,V,precision) );
|
||||
std::cout << linesep << std::endl;
|
||||
|
||||
MatrixType L2 = LDLT(V);
|
||||
std::cout << "LDLT: L" << std::endl << L2 << std::endl;
|
||||
MatrixType V2 = ublas::prod( L2, ublas::trans(L2) );
|
||||
std::cout << "LDLT covar" << std::endl << V2 << std::endl;
|
||||
std::cout << "-----------------------------------------------------------" << std::endl;
|
||||
edoSamplerNormalMulti<EOT,EOD>::Cholesky LDLT( edoSamplerNormalMulti<EOT,EOD>::Cholesky::robust );
|
||||
FactorMat L2 = LDLT(V);
|
||||
std::cout << "LDLT" << std::endl << format(L2) << std::endl;
|
||||
CovarMat V2 = ublas::prod( L2, ublas::trans(L2) );
|
||||
std::cout << "LDLT covar" << std::endl << format(V2) << std::endl;
|
||||
assert( equal(V2,V,precision) );
|
||||
std::cout << linesep << std::endl;
|
||||
|
||||
}
|
||||
|
|
|
|||
Reference in a new issue