diff --git a/CMakeLists.txt b/CMakeLists.txt index 715fc0cfa..da9615509 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -25,9 +25,13 @@ INCLUDE(FindPkgConfig) PKG_CHECK_MODULES(EO eo REQUIRED) PKG_CHECK_MODULES(MO mo REQUIRED) +FIND_PACKAGE(Boost 1.33.0) + INCLUDE_DIRECTORIES( ${EO_INCLUDE_DIRS} ${MO_INCLUDE_DIRS} + ${Boost_INCLUDE_DIRS} + /Dev/ometah-0.3/common ) ###################################################################################### diff --git a/application/cma_sa/CMakeLists.txt b/application/cma_sa/CMakeLists.txt index d68a49c07..c67ab0dd1 100644 --- a/application/cma_sa/CMakeLists.txt +++ b/application/cma_sa/CMakeLists.txt @@ -1,7 +1,12 @@ PROJECT(cma_sa) +FIND_PACKAGE(Boost 1.33.0) + INCLUDE_DIRECTORIES(${CMAKE_CURRENT_SOURCE_DIR}) +INCLUDE_DIRECTORIES(${Boost_INCLUDE_DIRS}) +LINK_DIRECTORIES(${Boost_LIBRARY_DIRS}) + SET(RESOURCES cma_sa.param plot.py @@ -20,4 +25,4 @@ FILE(GLOB SOURCES *.cpp) SET(EXECUTABLE_OUTPUT_PATH ${DO_BINARY_DIR}) ADD_EXECUTABLE(${PROJECT_NAME} ${SOURCES}) -TARGET_LINK_LIBRARIES(${PROJECT_NAME} do ${EO_LIBRARIES} ${MO_LIBRARIES}) +TARGET_LINK_LIBRARIES(${PROJECT_NAME} do ${EO_LIBRARIES} ${MO_LIBRARIES} ${Boost_LIBRARIES}) diff --git a/src/doCMASA.h b/src/doCMASA.h index c2a3cf8e8..31d1411a7 100644 --- a/src/doCMASA.h +++ b/src/doCMASA.h @@ -168,7 +168,7 @@ public: for (int i = 0; i < size; ++i) { - hv.update( distrib.variance()[i] ); + //hv.update( distrib.varcovar()[i] ); } _ofs_params_var << hv << std::endl; @@ -286,7 +286,7 @@ public: ofs << size << " "; std::copy(distrib.mean().begin(), distrib.mean().end(), std::ostream_iterator< double >(ofs, " ")); - std::copy(distrib.variance().begin(), distrib.variance().end(), std::ostream_iterator< double >(ofs, " ")); + //std::copy(distrib.varcovar().begin(), distrib.varcovar().end(), std::ostream_iterator< double >(ofs, " ")); ofs << std::endl; } @@ -336,7 +336,7 @@ public: for (int i = 0; i < size; ++i) { - hv.update( distrib.variance()[i] ); + //hv.update( distrib.varcovar()[i] ); } _ofs_params_var << hv << std::endl; diff --git a/src/doEstimatorNormal.h b/src/doEstimatorNormal.h index 3bd2058fc..b3cc1f3ec 100644 --- a/src/doEstimatorNormal.h +++ b/src/doEstimatorNormal.h @@ -9,6 +9,8 @@ template < typename EOT > class doEstimatorNormal : public doEstimator< doNormal< EOT > > { public: + typedef typename EOT::AtomType AtomType; + doNormal< EOT > operator()(eoPop& pop) { unsigned int popsize = pop.size(); @@ -17,23 +19,12 @@ public: unsigned int dimsize = pop[0].size(); assert(dimsize > 0); - doCovMatrix cov(dimsize); + //doCovMatrix cov(dimsize); + doUblasCovMatrix< EOT > cov; - for (unsigned int i = 0; i < popsize; ++i) - { - cov.update(pop[i]); - } + cov.update(pop); - EOT mean(dimsize); - EOT covariance(dimsize); - - for (unsigned int d = 0; d < dimsize; ++d) - { - mean[d] = cov.get_mean(d); - covariance[d] = cov.get_var(d); - } - - return doNormal< EOT >(mean, covariance); + return doNormal< EOT >(cov.get_mean(), cov.get_varcovar()); } }; diff --git a/src/doNormal.h b/src/doNormal.h index 6de887fc9..dd869fcea 100644 --- a/src/doNormal.h +++ b/src/doNormal.h @@ -8,8 +8,10 @@ template < typename EOT > class doNormal : public doDistrib< EOT >, public doNormalParams< EOT > { public: - doNormal(EOT mean, EOT variance) - : doNormalParams< EOT >(mean, variance) + typedef typename EOT::AtomType AtomType; + + doNormal( const EOT& mean, const ublas::symmetric_matrix< AtomType, ublas::lower >& varcovar ) + : doNormalParams< EOT >( mean, varcovar ) {} }; diff --git a/src/doNormalParams.h b/src/doNormalParams.h index 87a3a65aa..4a240957a 100644 --- a/src/doNormalParams.h +++ b/src/doNormalParams.h @@ -1,29 +1,38 @@ #ifndef _doNormalParams_h #define _doNormalParams_h +#include +#include + +namespace ublas = boost::numeric::ublas; + template < typename EOT > class doNormalParams { public: - doNormalParams(EOT mean, EOT variance) - : _mean(mean), _variance(variance) + typedef typename EOT::AtomType AtomType; + + doNormalParams(const EOT& mean, const ublas::symmetric_matrix< AtomType, ublas::lower >& varcovar) + : _mean(mean), _varcovar(varcovar) { assert(_mean.size() > 0); - assert(_mean.size() == _variance.size()); + assert(_mean.size() == _varcovar.size1()); + assert(_mean.size() == _varcovar.size2()); } EOT& mean(){return _mean;} - EOT& variance(){return _variance;} + ublas::symmetric_matrix< AtomType, ublas::lower >& varcovar(){return _varcovar;} unsigned int size() { - assert(_mean.size() == _variance.size()); + assert(_mean.size() == _varcovar.size1()); + assert(_mean.size() == _varcovar.size2()); return _mean.size(); } private: EOT _mean; - EOT _variance; + ublas::symmetric_matrix< AtomType, ublas::lower > _varcovar; }; #endif // !_doNormalParams_h diff --git a/src/doSamplerNormal.h b/src/doSamplerNormal.h index 7ba4c2d5b..21c0fafc6 100644 --- a/src/doSamplerNormal.h +++ b/src/doSamplerNormal.h @@ -6,6 +6,7 @@ #include "doSampler.h" #include "doNormal.h" #include "doBounder.h" +#include "doStats.h" /** * doSamplerNormal @@ -45,10 +46,16 @@ public: for (unsigned int i = 0; i < size; ++i) { - solution.push_back( - rng.normal(distrib.mean()[i], - distrib.variance()[i]) - ); + Cholesky< EOT > cholesky; + + cholesky.update( distrib.varcovar() ); + + // solution.push_back( + // rng.normal(distrib.mean()[i], + // distrib.varcovar()[i]) + // ); + + //rng.normal() + } //------------------------------------------------------------- diff --git a/src/doStats.h b/src/doStats.h index 94756fa3f..27bef3342 100644 --- a/src/doStats.h +++ b/src/doStats.h @@ -18,7 +18,14 @@ #ifndef _doStats_h #define _doStats_h +#include +#include +#include + #include +#include + +namespace ublas = boost::numeric::ublas; class doStats : public eoPrintable { @@ -110,9 +117,146 @@ protected: double _hv; }; -class doCholesky : public doStats +template < typename EOT > +class doUblasCovMatrix : public doStats { - +public: + typedef typename EOT::AtomType AtomType; + + virtual void update( const eoPop< EOT >& pop ) + { + unsigned int p_size = pop.size(); // population size + + assert(p_size > 0); + + unsigned int s_size = pop[0].size(); // solution size + + assert(s_size > 0); + + ublas::matrix< AtomType > sample( p_size, s_size ); + + for (unsigned int i = 0; i < p_size; ++i) + { + for (unsigned int j = 0; j < s_size; ++j) + { + sample(i, j) = pop[i][j]; + } + } + + _varcovar.resize(s_size, s_size); + + // variance-covariance matrix are symmetric (and semi-definite positive), + // thus a triangular storage is sufficient + ublas::symmetric_matrix< AtomType, ublas::lower > var(s_size, s_size); + + // variance-covariance matrix computation : A * transpose(A) + var = ublas::prod( sample, ublas::trans( sample ) ); + + for (unsigned int i = 0; i < s_size; ++i) + { + // triangular LOWER matrix, thus j is not going further than i + for (unsigned int j = 0; j <= i; ++j) + { + // we want a reducted covariance matrix + _varcovar(i, j) = var(i, j) / p_size; + } + } + + //_varcovar = varcovar; + + _mean.resize(s_size); + + // unit vector + ublas::scalar_vector< AtomType > u( p_size, 1 ); + + // sum over columns + ublas::vector< AtomType > mean = ublas::prod( ublas::trans( sample ), u ); + + // division by n + mean /= p_size; + + // copy results in the params std::vector + std::copy(mean.begin(), mean.end(), _mean.begin()); + } + + const ublas::symmetric_matrix< AtomType, ublas::lower >& get_varcovar() const {return _varcovar;} + + const EOT& get_mean() const {return _mean;} + +private: + ublas::symmetric_matrix< AtomType, ublas::lower > _varcovar; + EOT _mean; +}; + +template < typename EOT > +class Cholesky : public doStats +{ +public: + typedef typename EOT::AtomType AtomType; + + virtual void update( const ublas::symmetric_matrix< AtomType, ublas::lower >& V) + { + unsigned int Vl = V.size1(); + + assert(Vl > 0); + + unsigned int Vc = V.size2(); + + assert(Vc > 0); + + _L.resize(Vl, Vc); + + unsigned int i,j,k; + + // first column + i=0; + + // diagonal + j=0; + _L(0, 0) = sqrt( V(0, 0) ); + + // end of the column + for ( j = 1; j < Vc; ++j ) + { + _L(j, 0) = V(0, j) / _L(0, 0); + } + + // end of the matrix + for ( i = 1; i < Vl; ++i ) + { // each column + + // diagonal + double sum = 0.0; + + for ( k = 0; k < i; ++k) + { + sum += _L(i, k) * _L(i, k); + } + + assert( ( V(i, i) - sum ) > 0 ); + + _L(i, i) = sqrt( V(i, i) - sum ); + + for ( j = i + 1; j < Vl; ++j ) + { // rows + + // one element + sum = 0.0; + + for ( k = 0; k < i; ++k ) + { + sum += _L(j, k) * _L(i, k); + } + + _L(j, i) = (V(j, i) - sum) / _L(i, i); + } + } + } + + const ublas::symmetric_matrix< AtomType, ublas::lower >& get_L() const {return _L;} + +private: + ublas::symmetric_matrix< AtomType, ublas::lower > _L; }; #endif // !_doStats_h