diff --git a/cholesky.h b/cholesky.h index 4fda38d..3573cdb 100644 --- a/cholesky.h +++ b/cholesky.h @@ -289,7 +289,7 @@ public: sqrt_D(i,i) = sqrt(D(i,i)); } - // the factorization is thus _L*D^1/2 + // the factorization is thus L*D^1/2 return ublas::prod( L, sqrt_D ); } }; diff --git a/test.cpp b/test.cpp index 203220c..b6e4177 100644 --- a/test.cpp +++ b/test.cpp @@ -24,6 +24,9 @@ Authors: #include #include #include +#include +#include +#include #include "cholesky.h" @@ -130,14 +133,23 @@ void test( unsigned int M, unsigned int N, unsigned int F, unsigned int R, unsig typedef typename cholesky::Cholesky::CovarMat CovarMat; typedef typename cholesky::Cholesky::FactorMat FactorMat; + typedef typename std::map< std::string, cholesky::Cholesky* > AlgoMap; + + AlgoMap algos; + algos["LLT"] = new cholesky::LLT; + algos["LLTa"] = new cholesky::LLTabs; + algos["LLTz"] = new cholesky::LLTzero; + algos["LDLT"] = new cholesky::LDLT; - cholesky::LLT llt; - cholesky::LLTabs llta; - cholesky::LLTzero lltz; - cholesky::LDLT ldlt; + // init data structures on the same keys than given algorithms + std::map fails; + // triangular errors sum + std::map > errors; + for( typename AlgoMap::iterator ialgo = algos.begin(); ialgo != algos.end(); ++ialgo ) { + fails[ialgo->first] = 0; + errors[ialgo->first] = std::vector(); + } - unsigned int llt_fail = 0; - std::vector s0,s1,s2,s3; for( unsigned int n=0; nsecond)(V); + CovarMat Vn = ublas::prod( L, ublas::trans(L) ); + errors[ialgo->first].push_back( trigsum(error(V,Vn)) ); + + } catch( cholesky::NotDefinitePositive & error ) { + fails[ialgo->first]++; #ifndef NDEBUG - std::cout << "LLT FAILED:\t" << error.what() << std::endl; + std::cout << "FAILED:\t" << error.what() << std::endl; #endif + } + + } // for ialgo in algos + } // for n in R + + for( typename AlgoMap::iterator ialgo = algos.begin(); ialgo != algos.end(); ++ialgo ) { + std::string a = ialgo->first; + + std::cout << "\t" << a << ": (" << fails[a] << "/" << R << ")\t"; + if( errors[a].size() == 0 ) { + std::cout << "NAN"; + } else { + std::cout << sum(errors[a])/R; } - - FactorMat L1 = llta(V); - // reconstruct the covariance matrix - CovarMat V1 = ublas::prod( L1, ublas::trans(L1) ); - // store the triangular error distance with the initial covar matrix - s1.push_back( trigsum(error(V,V1)) ); - - FactorMat L2 = lltz(V); - CovarMat V2 = ublas::prod( L2, ublas::trans(L2) ); - s2.push_back( trigsum(error(V,V2)) ); - - FactorMat L3 = ldlt(V); - CovarMat V3 = ublas::prod( L3, ublas::trans(L3) ); - s3.push_back( trigsum(error(V,V3)) ); - } - - std::cout << "Average error:" << std::endl; - - std::cout << "\tLLT: "; - if( s0.size() == 0 ) { - std::cout << "NAN"; - } else { - std::cout << sum(s0)/R; - } - std::cout << "\t" << llt_fail << "/" << R << " failures" << std::endl; - - std::cout << "\tLLTa: " << sum(s1)/R << std::endl; - std::cout << "\tLLTz: " << sum(s2)/R << std::endl; - std::cout << "\tLDLT: " << sum(s3)/R << std::endl; + std::cout << std::endl; + } // for a in algos } @@ -230,6 +230,8 @@ int main(int argc, char** argv) std::clog << "\tmatrix size = " << N << std::endl; std::clog << "\trandom range = " << F << std::endl; std::clog << "\trepetitions = " << R << std::endl; + std::clog << "Legend:" << std::endl; + std::clog << "\tAlgo: (failures/runs)\tAverage error" << std::endl; std::cout << std::endl << "FLOAT" << std::endl; test(M,N,F,R,seed);