t-cholesky.cpp
00001 
00002 /*
00003 The Evolving Distribution Objects framework (EDO) is a template-based,
00004 ANSI-C++ evolutionary computation library which helps you to write your
00005 own estimation of distribution algorithms.
00006 
00007 This library is free software; you can redistribute it and/or
00008 modify it under the terms of the GNU Lesser General Public
00009 License as published by the Free Software Foundation; either
00010 version 2.1 of the License, or (at your option) any later version.
00011 
00012 This library is distributed in the hope that it will be useful,
00013 but WITHOUT ANY WARRANTY; without even the implied warranty of
00014 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00015 Lesser General Public License for more details.
00016 
00017 You should have received a copy of the GNU Lesser General Public
00018 License along with this library; if not, write to the Free Software
00019 Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
00020 
00021 Copyright (C) 2010 Thales group
00022 */
00023 /*
00024 Authors:
00025     Johann Dréo <johann.dreo@thalesgroup.com>
00026 */
00027 
00028 //#include <vector>
00029 #include <cstdlib>
00030 #include <iostream>
00031 #include <sstream>
00032 #include <limits>
00033 #include <iomanip>
00034 #include <ctime>
00035 
00036 #include <eo>
00037 #include <es.h>
00038 #include <edo>
00039 
00040 typedef eoReal< eoMinimizingFitness > EOT;
00041 typedef edoNormalMulti<EOT> EOD;
00042 
00043 
00044 void setformat( std::ostream& out )
00045 {
00046     out << std::right;
00047     out << std::setfill(' ');
00048     out << std::setw( 5 + std::numeric_limits<double>::digits10);
00049     out << std::setprecision(std::numeric_limits<double>::digits10);
00050     out << std::setiosflags(std::ios_base::showpoint);
00051 }
00052 
00053 
00054 template<typename MT>
00055 std::string format(const MT& mat )
00056 {
00057     std::ostringstream out;
00058     setformat(out);
00059 
00060     for( unsigned int i=0; i<mat.size1(); ++i) {
00061         for( unsigned int j=0; j<mat.size2(); ++j) {
00062             out << mat(i,j) << "\t";
00063         } // columns
00064         out << std::endl;
00065     } // rows
00066 
00067     return out.str();
00068 }
00069 
00070 
00071 template< typename T >
00072 T round( T val, T prec = 1.0 )
00073 { 
00074     return (val > 0.0) ? 
00075         floor(val * prec + 0.5) / prec : 
00076          ceil(val * prec - 0.5) / prec ; 
00077 }
00078 
00079 
00080 template<typename MT>
00081 bool equal( const MT& M1, const MT& M2, double prec /* = 1/std::numeric_limits<double>::digits10 ???*/ )
00082 {
00083     if( M1.size1() != M2.size1() || M1.size2() != M2.size2() ) {
00084         return false;
00085     }
00086 
00087     for( unsigned int i=0; i<M1.size1(); ++i ) {
00088         for( unsigned int j=0; j<M1.size2(); ++j ) {
00089             if( round(M1(i,j),prec) != round(M2(i,j),prec) ) {
00090                 std::cout << "round(M(" << i << "," << j << "," << prec << ") == " 
00091                     << round(M1(i,j),prec) << " != " << round(M2(i,j),prec) << std::endl;
00092                 return false;
00093             }
00094         }
00095     }
00096 
00097     return true;
00098 }
00099 
00100 
00101 template<typename MT >
00102 MT error( const MT& M1, const MT& M2 )
00103 {
00104     assert( M1.size1() == M2.size1() && M1.size1() == M2.size2() );
00105 
00106     MT Err = ublas::zero_matrix<double>(M1.size1(),M1.size2());
00107 
00108     for( unsigned int i=0; i<M1.size1(); ++i ) {
00109         for( unsigned int j=0; j<M1.size2(); ++j ) {
00110             Err(i,j) = M1(i,j) - M2(i,j);
00111         }
00112     }
00113 
00114     return Err;
00115 }
00116 
00117 
00118 template<typename MT >
00119 double trigsum( const MT& M )
00120 {
00121     double sum;
00122     for( unsigned int i=0; i<M.size1(); ++i ) {
00123         for( unsigned int j=i; j<M.size2(); ++j ) { // triangular browsing
00124             sum += fabs( M(i,j) ); // absolute deviation
00125         }
00126     }
00127     return sum;
00128 }
00129 
00130 
00131 template<typename T>
00132 double sum( const T& c )
00133 {
00134      return std::accumulate(c.begin(), c.end(), 0);
00135 }
00136 
00137 
00138 int main(int argc, char** argv)
00139 {
00140     srand(time(0));
00141 
00142     unsigned int N = 4; // size of matrix
00143     unsigned int R = 1000; // nb of repetitions
00144 
00145     if( argc >= 2 ) {
00146         N = std::atoi(argv[1]);
00147     }
00148     if( argc >= 3 ) {
00149         R = std::atoi(argv[2]);
00150     }
00151 
00152     std::cout << "Usage: t-cholesky [matrix size] [repetitions]" << std::endl;
00153     std::cout << "matrix size = " << N << std::endl;
00154     std::cout << "repetitions = " << R << std::endl;
00155 
00156     typedef edoSamplerNormalMulti<EOT,EOD>::Cholesky::CovarMat CovarMat;
00157     typedef edoSamplerNormalMulti<EOT,EOD>::Cholesky::FactorMat FactorMat;
00158 
00159     edoSamplerNormalMulti<EOT,EOD>::Cholesky LLT( edoSamplerNormalMulti<EOT,EOD>::Cholesky::standard );
00160     edoSamplerNormalMulti<EOT,EOD>::Cholesky LLTa( edoSamplerNormalMulti<EOT,EOD>::Cholesky::absolute );
00161     edoSamplerNormalMulti<EOT,EOD>::Cholesky LLTz( edoSamplerNormalMulti<EOT,EOD>::Cholesky::zeroing );
00162     edoSamplerNormalMulti<EOT,EOD>::Cholesky LDLT( edoSamplerNormalMulti<EOT,EOD>::Cholesky::robust );
00163 
00164     std::vector<double> s0,s1,s2,s3;
00165     for( unsigned int n=0; n<R; ++n ) {
00166 
00167         // a variance-covariance matrix of size N*N
00168         CovarMat V(N,N);
00169 
00170         // random covariance matrix
00171         for( unsigned int i=0; i<N; ++i) {
00172             V(i,i) = std::pow(rand(),2); // variance should be >= 0
00173             for( unsigned int j=i+1; j<N; ++j) {
00174                 V(i,j) = rand();
00175             }
00176         }
00177 
00178         FactorMat L0 = LLT(V);
00179         CovarMat V0 = ublas::prod( L0, ublas::trans(L0) );
00180         s0.push_back( trigsum(error(V,V0)) );
00181 
00182         FactorMat L1 = LLTa(V);
00183         CovarMat V1 = ublas::prod( L1, ublas::trans(L1) );
00184         s1.push_back( trigsum(error(V,V1)) );
00185 
00186         FactorMat L2 = LLTz(V);
00187         CovarMat V2 = ublas::prod( L2, ublas::trans(L2) );
00188         s2.push_back( trigsum(error(V,V2)) );
00189 
00190         FactorMat L3 = LDLT(V);
00191         CovarMat V3 = ublas::prod( L3, ublas::trans(L3) );
00192         s3.push_back( trigsum(error(V,V3)) );
00193     }
00194 
00195     std::cout << "Average error:" << std::endl;
00196     std::cout << "\tLLT:  " << sum(s0)/R << std::endl;
00197     std::cout << "\tLLTa: " << sum(s1)/R << std::endl;
00198     std::cout << "\tLLTz: " << sum(s2)/R << std::endl;
00199     std::cout << "\tLDLT: " << sum(s3)/R << std::endl;
00200 
00201 //    double precision = 1e-15;
00202 //    if( argc >= 4 ) {
00203 //        precision = std::atof(argv[3]);
00204 //    }
00205 //    std::cout << "precision = " << precision << std::endl;
00206 //    std::cout << "usage: t-cholesky [N] [precision]" << std::endl;
00207 //    std::cout << "N = " << N << std::endl;
00208 //    std::cout << "precision = " << precision << std::endl;
00209 //    std::string linesep = "--------------------------------------------------------------------------------------------";
00210 //    std::cout << linesep << std::endl;
00211 //
00212 //    setformat(std::cout);
00213 //
00214 //    std::cout << "Covariance matrix" << std::endl << format(V) << std::endl;
00215 //    std::cout << linesep << std::endl;
00216 //
00217 //    edoSamplerNormalMulti<EOT,EOD>::Cholesky LLT( edoSamplerNormalMulti<EOT,EOD>::Cholesky::standard );
00218 //    FactorMat L0 = LLT(V);
00219 //    CovarMat V0 = ublas::prod( L0, ublas::trans(L0) );
00220 //    CovarMat E0 = error(V,V0);
00221 //    std::cout << "LLT" << std::endl << format(E0) << std::endl;
00222 //    std::cout << trigsum(E0) << std::endl;
00223 //    std::cout << "LLT" << std::endl << format(L0) << std::endl;
00224 //    std::cout << "LLT covar" << std::endl << format(V0) << std::endl;
00225 //    assert( equal(V0,V,precision) );
00226 //    std::cout << linesep << std::endl;
00227 //
00228 //    edoSamplerNormalMulti<EOT,EOD>::Cholesky LLTa( edoSamplerNormalMulti<EOT,EOD>::Cholesky::absolute );
00229 //    FactorMat L1 = LLTa(V);
00230 //    CovarMat V1 = ublas::prod( L1, ublas::trans(L1) );
00231 //    CovarMat E1 = error(V,V1);
00232 //    std::cout << "LLT abs" << std::endl << format(E1) << std::endl;
00233 //    std::cout << trigsum(E1) << std::endl;
00234 //    std::cout << "LLT abs" << std::endl << format(L1) << std::endl;
00235 //    std::cout << "LLT covar" << std::endl << format(V1) << std::endl;
00236 //    assert( equal(V1,V,precision) );
00237 //    std::cout << linesep << std::endl;
00238 //    
00239 //    edoSamplerNormalMulti<EOT,EOD>::Cholesky LDLT( edoSamplerNormalMulti<EOT,EOD>::Cholesky::robust );
00240 //    FactorMat L2 = LDLT(V);
00241 //    CovarMat V2 = ublas::prod( L2, ublas::trans(L2) );
00242 //    CovarMat E2 = error(V,V2);
00243 //    std::cout << "LDLT" << std::endl << format(E2) << std::endl;
00244 //    std::cout << trigsum(E2) << std::endl;
00245 //    std::cout << "LDLT" << std::endl << format(L2) << std::endl;
00246 //    std::cout << "LDLT covar" << std::endl << format(V2) << std::endl;
00247 //    assert( equal(V2,V,precision) );
00248 //    std::cout << linesep << std::endl;
00249     
00250 }
 All Classes Functions Variables Typedefs