diff --git a/edo/CMakeLists.txt b/edo/CMakeLists.txt index 10b1fbe2..9a07cd61 100644 --- a/edo/CMakeLists.txt +++ b/edo/CMakeLists.txt @@ -16,8 +16,8 @@ CMAKE_MINIMUM_REQUIRED(VERSION 2.6) PROJECT(EDO) -SET(PROJECT_VERSION_MAJOR 1) -SET(PROJECT_VERSION_MINOR 0) +SET(PROJECT_VERSION_MAJOR 0) +SET(PROJECT_VERSION_MINOR 1) SET(PROJECT_VERSION_PATCH 0) SET(PROJECT_VERSION "${PROJECT_VERSION_MAJOR}.${PROJECT_VERSION_MINOR}.${PROJECT_VERSION_PATCH}") @@ -29,25 +29,57 @@ SET(PROJECT_VERSION "${PROJECT_VERSION_MAJOR}.${PROJECT_VERSION_MINOR}.${PROJECT ###################################################################################### # include useful features for cmake -SET(CMAKE_MODULE_PATH ${CMAKE_SOURCE_DIR}/cmake/modules) +SET(CMAKE_MODULE_PATH ${PROJECT_SOURCE_DIR} ${CMAKE_SOURCE_DIR}/cmake/modules) + INCLUDE(FindDoxygen) INCLUDE(FindPkgConfig) -FIND_PACKAGE(Boost 1.33.0) +IF( WITH_BOOST AND WITH_EIGEN ) + MESSAGE( "ERROR: You have to choose between Boost:ublas and Eigen, you cannot compile with both libraries" ) + SET(IS_FATAL 1) +ELSEIF( NOT WITH_BOOST AND NOT WITH_EIGEN ) + #MESSAGE( "WARNING: Boost:ublas and Eigen are both deactivated, some features may lack." ) + # FIXME ideally, we would have a minimal implementation with STL vectors… + MESSAGE( "FIXME: Boost:ublas and Eigen are both deactivated, too much features will lack, you should choose one." ) + SET(IS_FATAL 1) +ENDIF() + +IF(WITH_BOOST) + FIND_PACKAGE(Boost 1.33.0) + IF( Boost_FOUND ) + INCLUDE_DIRECTORIES( ${Boost_INCLUDE_DIRS} ) + ADD_DEFINITIONS( -DWITH_BOOST ) + ELSE() + MESSAGE( "ERROR: You asked for Boost:ublas but it has nost been found." ) + SET(IS_FATAL 1) + ENDIF() +ELSEIF( WITH_EIGEN ) + # FIXME FindEigen3.cmake does not work + #find_package(Eigen3) + #include_directories(EIGEN3_INCLUDE_DIR) + SET( EIGEN3_FOUND 1) + SET( EIGEN3_INCLUDE_DIR "/usr/include/eigen3/" ) + + IF( EIGEN3_FOUND ) + INCLUDE_DIRECTORIES( ${EIGEN3_INCLUDE_DIR} ) + ADD_DEFINITIONS( -DWITH_EIGEN ) + ELSE() + MESSAGE( "ERROR: You asked for Eigen but it has nost been found." ) + SET(IS_FATAL 1) + ENDIF() +ENDIF() FIND_PACKAGE(EO) INCLUDE_DIRECTORIES( ${EO_INCLUDE_DIRS} ${MO_INCLUDE_DIRS} - ${Boost_INCLUDE_DIRS} - # /Dev/ometah-0.3/common - ) +) LINK_DIRECTORIES( ${EO_LIBRARY_DIRS} - ) +) ###################################################################################### @@ -58,7 +90,7 @@ LINK_DIRECTORIES( INCLUDE_DIRECTORIES( ${CMAKE_CURRENT_SOURCE_DIR}/src - ) +) ###################################################################################### @@ -92,7 +124,7 @@ SET(SAMPLE_SRCS) ###################################################################################### ADD_SUBDIRECTORY(src) -#ADD_SUBDIRECTORY(application) +ADD_SUBDIRECTORY(application) ADD_SUBDIRECTORY(test) ADD_SUBDIRECTORY(doc) diff --git a/edo/NEWS b/edo/NEWS new file mode 100644 index 00000000..caed8140 --- /dev/null +++ b/edo/NEWS @@ -0,0 +1,8 @@ +* current release + - alternative implementation of the multi-normal operators using the Eigen3 library + +* release 0.0 (2011-09-15) + - basic design for estimation of distribution algorithms and, more generally for randomized search heuristics + - continuous EDA example + - EDA using multi-normal distribution, implementation using the boost::ublas library + diff --git a/edo/README b/edo/README index 5b814b15..4217a844 100644 --- a/edo/README +++ b/edo/README @@ -33,11 +33,11 @@ In the edo/build/ directory: (Unix) > ctest Windows users, please refer to this tutorial: http://paradiseo.gforge.inria.fr/index.php?n=Paradiseo.VisualCTutorial -In the directory "application", there are several directory such as eda_sa which instantiate EDA-SA solver. +In the directory "application", there are several directory such as eda which instantiate EDA solver. -(Unix) After compilation you can run the binary "build/eda_sa" and see results. Parameters can be modified from command line. +(Unix) After compilation you can run the binary "build/eda" and see results. Parameters can be modified from command line. -(Windows) Add argument "eda_sa.param" and execute the corresponding algorithms. +(Windows) Add argument "eda.param" and execute the corresponding algorithms. Windows users, please refer to this tutorial: http://paradiseo.gforge.inria.fr/index.php?n=Paradiseo.VisualCTutorial diff --git a/edo/application/CMakeLists.txt b/edo/application/CMakeLists.txt index eea3dcb9..c03fa57d 100644 --- a/edo/application/CMakeLists.txt +++ b/edo/application/CMakeLists.txt @@ -7,8 +7,8 @@ INCLUDE_DIRECTORIES( ) ADD_SUBDIRECTORY(common) -ADD_SUBDIRECTORY(eda_sa) +#ADD_SUBDIRECTORY(eda_sa) ADD_SUBDIRECTORY(eda) -#ADD_SUBDIRECTORY(sa) +ADD_SUBDIRECTORY(cmaes) ###################################################################################### diff --git a/edo/application/cmaes/CMakeLists.txt b/edo/application/cmaes/CMakeLists.txt new file mode 100644 index 00000000..ade261ac --- /dev/null +++ b/edo/application/cmaes/CMakeLists.txt @@ -0,0 +1,33 @@ +PROJECT(cmaes) + + +#find_package(Eigen3 REQUIRED) +#include_directories(EIGEN3_INCLUDE_DIR) +INCLUDE_DIRECTORIES( ${EIGEN3_INCLUDE_DIR} ) +MESSAGE( "MESSAGE:" ${EIGEN3_INCLUDE_DIR} ) + +#FIND_PACKAGE(Boost 1.33.0) +INCLUDE_DIRECTORIES(${Boost_INCLUDE_DIRS}) +LINK_DIRECTORIES(${Boost_LIBRARY_DIRS}) + +INCLUDE_DIRECTORIES(${CMAKE_CURRENT_SOURCE_DIR}) + +SET(RESOURCES + ${PROJECT_NAME}.param + ) + +FOREACH(file ${RESOURCES}) + EXECUTE_PROCESS( + COMMAND ${CMAKE_COMMAND} -E copy_if_different + ${CMAKE_CURRENT_SOURCE_DIR}/${file} + ${EDO_BINARY_DIR}/${file} + ) +ENDFOREACH(file) + +#FILE(GLOB SOURCES *.cpp) + +SET(EXECUTABLE_OUTPUT_PATH ${EDO_BINARY_DIR}) + +ADD_EXECUTABLE(${PROJECT_NAME} main.cpp) +TARGET_LINK_LIBRARIES(${PROJECT_NAME} edo edoutils ${EO_LIBRARIES} ${Boost_LIBRARIES}) + diff --git a/edo/application/cmaes/main.cpp b/edo/application/cmaes/main.cpp new file mode 100644 index 00000000..18c3f093 --- /dev/null +++ b/edo/application/cmaes/main.cpp @@ -0,0 +1,181 @@ +/* +The Evolving Distribution Objects framework (EDO) is a template-based, +ANSI-C++ evolutionary computation library which helps you to write your +own estimation of distribution algorithms. + +This library is free software; you can redistribute it and/or +modify it under the terms of the GNU Lesser General Public +License as published by the Free Software Foundation; either +version 2.1 of the License, or (at your option) any later version. + +This library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Lesser General Public License for more details. + +You should have received a copy of the GNU Lesser General Public +License along with this library; if not, write to the Free Software +Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + +Copyright (C) 2010 Thales group +*/ +/* +Authors: + Johann Dréo + Caner Candan +*/ + +#include +#include + +#include + +#include +#include +#include +#include + +#include + +#include "Rosenbrock.h" +#include "Sphere.h" + + +typedef eoReal EOT; +typedef edoNormalMulti< EOT > Distrib; + + +int main(int ac, char** av) +{ + eoParser parser(ac, av); + + // Letters used by the following declarations: + // a d i p t + + std::string section("Algorithm parameters"); + + eoState state; + + // Instantiate all needed parameters for EDA algorithm + double selection_rate = parser.createParam((double)0.5, "selection_rate", "Selection Rate", 'R', section).value(); // R + + eoSelect< EOT >* selector = new eoDetSelect< EOT >( selection_rate ); + state.storeFunctor(selector); + + edoEstimator< Distrib >* estimator = new edoEstimatorNormalMulti< EOT >(); + state.storeFunctor(estimator); + + eoEvalFunc< EOT >* plainEval = new Rosenbrock< EOT >(); + state.storeFunctor(plainEval); + + unsigned long max_eval = parser.getORcreateParam((unsigned long)0, "maxEval", "Maximum number of evaluations (0 = none)", 'E', "Stopping criterion").value(); // E + eoEvalFuncCounterBounder< EOT > eval(*plainEval, max_eval); + + eoRndGenerator< double >* gen = new eoUniformGenerator< double >(-5, 5); + state.storeFunctor(gen); + + unsigned int dimension_size = parser.createParam((unsigned int)10, "dimension-size", "Dimension size", 'd', section).value(); // d + + eoInitFixedLength< EOT >* init = new eoInitFixedLength< EOT >( dimension_size, *gen ); + state.storeFunctor(init); + + + // (1) Population init and sampler + // Generation of population from do_make_pop (creates parameters, manages persistance and so on...) + // ... and creates the parameters: L P r S + // this first sampler creates a uniform distribution independently from our distribution (it does not use edoUniform). + eoPop< EOT >& pop = do_make_pop(parser, state, *init); + + // (2) First evaluation before starting the research algorithm + apply(eval, pop); + + // Prepare bounder class to set bounds of sampling. + // This is used by edoSampler. + edoBounder< EOT >* bounder = + new edoBounderRng< EOT >( EOT(pop[0].size(), -5), EOT(pop[0].size(), 5), *gen); // FIXME do not use hard-coded bounds + state.storeFunctor(bounder); + + // Prepare sampler class with a specific distribution + edoSampler< Distrib >* sampler = new edoSamplerNormalMulti< EOT >( *bounder ); + state.storeFunctor(sampler); + + // stopping criteria + // ... and creates the parameter letters: C E g G s T + eoContinue< EOT >& eo_continue = do_make_continue(parser, state, eval); + + // population output + eoCheckPoint< EOT >& pop_continue = do_make_checkpoint(parser, state, eval, eo_continue); + + // distribution output + edoDummyContinue< Distrib >* dummy_continue = new edoDummyContinue< Distrib >(); + state.storeFunctor(dummy_continue); + + edoCheckPoint< Distrib >* distribution_continue = new edoCheckPoint< Distrib >( *dummy_continue ); + state.storeFunctor(distribution_continue); + + // eoEPRemplacement causes the using of the current and previous + // sample for sampling. + eoReplacement< EOT >* replacor = new eoEPReplacement< EOT >(pop.size()); + state.storeFunctor(replacor); + + // Some stuff to display helper when we are using -h option + if (parser.userNeedsHelp()) + { + parser.printHelp(std::cout); + exit(1); + } + + // Help + Verbose routines + make_verbose(parser); + make_help(parser); + + // population output (after helper) + // + // FIXME: theses objects are instanciated there in order to avoid a folder + // removing as edoFileSnapshot does within ctor. + edoPopStat< EOT >* popStat = new edoPopStat; + state.storeFunctor(popStat); + pop_continue.add(*popStat); + + edoFileSnapshot* fileSnapshot = new edoFileSnapshot("EDA_ResPop"); + state.storeFunctor(fileSnapshot); + fileSnapshot->add(*popStat); + pop_continue.add(*fileSnapshot); + + // distribution output (after helper) + edoDistribStat< Distrib >* distrib_stat = new edoStatNormalMulti< EOT >(); + state.storeFunctor(distrib_stat); + + distribution_continue->add( *distrib_stat ); + + // eoMonitor* stdout_monitor = new eoStdoutMonitor(); + // state.storeFunctor(stdout_monitor); + // stdout_monitor->add(*distrib_stat); + // distribution_continue->add( *stdout_monitor ); + + eoFileMonitor* file_monitor = new eoFileMonitor("eda_distribution_bounds.txt"); + state.storeFunctor(file_monitor); + file_monitor->add(*distrib_stat); + distribution_continue->add( *file_monitor ); + + eoPopLoopEval popEval( eval ); + + // EDA algorithm configuration + edoAlgo< Distrib >* algo = new edoEDA< Distrib > + (popEval, *selector, *estimator, *sampler, *replacor, + pop_continue, *distribution_continue ); + + + // Beginning of the algorithm call + try { + do_run(*algo, pop); + + } catch (eoEvalFuncCounterBounderException& e) { + eo::log << eo::warnings << "warning: " << e.what() << std::endl; + + } catch (std::exception& e) { + eo::log << eo::errors << "error: " << e.what() << std::endl; + exit(EXIT_FAILURE); + } + return 0; +} diff --git a/edo/application/eda/main.cpp b/edo/application/eda/main.cpp index 250e6bf1..07505718 100644 --- a/edo/application/eda/main.cpp +++ b/edo/application/eda/main.cpp @@ -26,7 +26,7 @@ Authors: */ #include -#include +// #include #include @@ -92,7 +92,7 @@ int main(int ac, char** av) // Prepare bounder class to set bounds of sampling. // This is used by edoSampler. edoBounder< EOT >* bounder = - new edoBounderRng< EOT >( EOT(pop[0].size(), -5), EOT(pop[0].size(), 5), *gen); // FIXME do not use hard-coded bounds + new edoBounderRng< EOT >( EOT(dimension_size, -5), EOT(dimension_size, 5), *gen); // FIXME do not use hard-coded bounds state.storeFunctor(bounder); // Prepare sampler class with a specific distribution @@ -117,7 +117,11 @@ int main(int ac, char** av) // sample for sampling. eoReplacement< EOT >* replacor = new eoEPReplacement< EOT >(pop.size()); state.storeFunctor(replacor); - + + // Help + Verbose routines + make_verbose(parser); + make_help(parser); + // Some stuff to display helper when we are using -h option if (parser.userNeedsHelp()) { @@ -125,10 +129,6 @@ int main(int ac, char** av) exit(1); } - // Help + Verbose routines - make_verbose(parser); - make_help(parser); - // population output (after helper) // // FIXME: theses objects are instanciated there in order to avoid a folder @@ -162,9 +162,8 @@ int main(int ac, char** av) // EDA algorithm configuration edoAlgo< Distrib >* algo = new edoEDA< Distrib > - (*selector, *estimator, *sampler, - pop_continue, *distribution_continue, - popEval, *replacor); + (popEval, *selector, *estimator, *sampler, *replacor, + pop_continue, *distribution_continue ); // Beginning of the algorithm call try { diff --git a/edo/build_gcc_linux_debug b/edo/build_gcc_linux_debug index 144a5298..74b2b6d2 100755 --- a/edo/build_gcc_linux_debug +++ b/edo/build_gcc_linux_debug @@ -2,6 +2,6 @@ mkdir -p debug cd debug -cmake -DCMAKE_BUILD_TYPE=Debug .. +cmake -DCMAKE_BUILD_TYPE=Debug -DWITH_BOOST=1 .. make cd .. diff --git a/edo/build_gcc_linux_eigen_debug b/edo/build_gcc_linux_eigen_debug new file mode 100755 index 00000000..ea754f9b --- /dev/null +++ b/edo/build_gcc_linux_eigen_debug @@ -0,0 +1,7 @@ +#!/usr/bin/env sh + +mkdir -p debug +cd debug +cmake -DCMAKE_BUILD_TYPE=Debug -DWITH_EIGEN=1 .. +make +cd .. diff --git a/edo/src/edoEstimatorNormalMulti.h b/edo/src/edoEstimatorNormalMulti.h index cfd979fe..41eb78f5 100644 --- a/edo/src/edoEstimatorNormalMulti.h +++ b/edo/src/edoEstimatorNormalMulti.h @@ -29,11 +29,13 @@ Authors: #ifndef _edoEstimatorNormalMulti_h #define _edoEstimatorNormalMulti_h + #include "edoEstimator.h" #include "edoNormalMulti.h" -//! edoEstimatorNormalMulti< EOT > +#ifdef WITH_BOOST +//! edoEstimatorNormalMulti< EOT > template < typename EOT > class edoEstimatorNormalMulti : public edoEstimator< edoNormalMulti< EOT > > { @@ -41,95 +43,95 @@ public: class CovMatrix { public: - typedef typename EOT::AtomType AtomType; + typedef typename EOT::AtomType AtomType; - CovMatrix( const eoPop< EOT >& pop ) - { - //------------------------------------------------------------- - // Some checks before starting to estimate covar - //------------------------------------------------------------- + CovMatrix( const eoPop< EOT >& pop ) + { + //------------------------------------------------------------- + // Some checks before starting to estimate covar + //------------------------------------------------------------- - unsigned int p_size = pop.size(); // population size - assert(p_size > 0); + 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); + unsigned int s_size = pop[0].size(); // solution size + assert(s_size > 0); - //------------------------------------------------------------- + //------------------------------------------------------------- - //------------------------------------------------------------- - // Copy the population to an ublas matrix - //------------------------------------------------------------- + //------------------------------------------------------------- + // Copy the population to an ublas matrix + //------------------------------------------------------------- - ublas::matrix< AtomType > sample( p_size, s_size ); + 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]; - } - } + 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); + _varcovar.resize(s_size); - //------------------------------------------------------------- - // variance-covariance matrix are symmetric (and semi-definite - // positive), thus a triangular storage is sufficient - // - // variance-covariance matrix computation : transpose(A) * A - //------------------------------------------------------------- + //------------------------------------------------------------- + // variance-covariance matrix are symmetric (and semi-definite + // positive), thus a triangular storage is sufficient + // + // variance-covariance matrix computation : transpose(A) * A + //------------------------------------------------------------- - ublas::symmetric_matrix< AtomType, ublas::lower > var = ublas::prod( ublas::trans( sample ), sample ); + ublas::symmetric_matrix< AtomType, ublas::lower > var = ublas::prod( ublas::trans( sample ), sample ); - // Be sure that the symmetric matrix got the good size + // Be sure that the symmetric matrix got the good size - assert(var.size1() == s_size); - assert(var.size2() == s_size); - assert(var.size1() == _varcovar.size1()); - assert(var.size2() == _varcovar.size2()); + assert(var.size1() == s_size); + assert(var.size2() == s_size); + assert(var.size1() == _varcovar.size1()); + assert(var.size2() == _varcovar.size2()); - //------------------------------------------------------------- + //------------------------------------------------------------- - // TODO: to remove the comment below + // TODO: to remove the comment below - // 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; - // } - // } + // 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 = var / p_size; + _varcovar = var / p_size; - _mean.resize(s_size); // FIXME: check if it is really used because of the assignation below + _mean.resize(s_size); // FIXME: check if it is really used because of the assignation below - // unit vector - ublas::scalar_vector< AtomType > u( p_size, 1 ); + // unit vector + ublas::scalar_vector< AtomType > u( p_size, 1 ); - // sum over columns - _mean = ublas::prod( ublas::trans( sample ), u ); + // sum over columns + _mean = ublas::prod( ublas::trans( sample ), u ); - // division by n - _mean /= p_size; - } + // division by n + _mean /= p_size; + } - const ublas::symmetric_matrix< AtomType, ublas::lower >& get_varcovar() const {return _varcovar;} + const ublas::symmetric_matrix< AtomType, ublas::lower >& get_varcovar() const {return _varcovar;} - const ublas::vector< AtomType >& get_mean() const {return _mean;} + const ublas::vector< AtomType >& get_mean() const {return _mean;} private: - ublas::symmetric_matrix< AtomType, ublas::lower > _varcovar; - ublas::vector< AtomType > _mean; + ublas::symmetric_matrix< AtomType, ublas::lower > _varcovar; + ublas::vector< AtomType > _mean; }; public: @@ -137,16 +139,102 @@ public: edoNormalMulti< EOT > operator()(eoPop& pop) { - unsigned int popsize = pop.size(); - assert(popsize > 0); + unsigned int popsize = pop.size(); + assert(popsize > 0); - unsigned int dimsize = pop[0].size(); - assert(dimsize > 0); + unsigned int dimsize = pop[0].size(); + assert(dimsize > 0); - CovMatrix cov( pop ); + CovMatrix cov( pop ); - return edoNormalMulti< EOT >( cov.get_mean(), cov.get_varcovar() ); + return edoNormalMulti< EOT >( cov.get_mean(), cov.get_varcovar() ); } }; +#else +#ifdef WITH_EIGEN + +//! edoEstimatorNormalMulti< EOT > +template < typename EOT, typename EOD = edoNormalMulti > +class edoEstimatorNormalMulti : public edoEstimator< EOD > +{ +public: + class CovMatrix + { + public: + typedef typename EOT::AtomType AtomType; + typedef typename EOD::Vector Vector; + typedef typename EOD::Matrix Matrix; + + CovMatrix( const eoPop< EOT >& pop ) + { + // Some checks before starting to estimate covar + 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); + + // Copy the population to an ublas matrix + Matrix 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]; + } + } + + // variance-covariance matrix are symmetric, thus a triangular storage is sufficient + // variance-covariance matrix computation : transpose(A) * A + Matrix var = sample.transpose() * sample; + + // Be sure that the symmetric matrix got the good size + assert(var.innerSize() == s_size); + assert(var.outerSize() == s_size); + + _varcovar = var / p_size; + + // unit vector + Vector u( p_size); + u = Vector::Constant(p_size, 1); + + // sum over columns + _mean = sample.transpose() * u; + + // division by n + _mean /= p_size; + } + + const Matrix& get_varcovar() const {return _varcovar;} + + const Vector& get_mean() const {return _mean;} + + private: + Matrix _varcovar; + Vector _mean; + }; + +public: + typedef typename EOT::AtomType AtomType; + + edoNormalMulti< EOT > operator()(eoPop& pop) + { + unsigned int p_size = pop.size(); + assert(p_size > 0); + + unsigned int s_size = pop[0].size(); + assert(s_size > 0); + + CovMatrix cov( pop ); + + assert( cov.get_mean().innerSize() == s_size ); + assert( cov.get_mean().outerSize() == 1 ); + assert( cov.get_varcovar().innerSize() == s_size ); + assert( cov.get_varcovar().outerSize() == s_size ); + + return edoNormalMulti< EOT >( cov.get_mean(), cov.get_varcovar() ); + } +}; +#endif // WITH_EIGEN +#endif // WITH_BOOST + #endif // !_edoEstimatorNormalMulti_h diff --git a/edo/src/edoNormalMulti.h b/edo/src/edoNormalMulti.h index be0e7d00..db36810a 100644 --- a/edo/src/edoNormalMulti.h +++ b/edo/src/edoNormalMulti.h @@ -21,22 +21,24 @@ Copyright (C) 2010 Thales group */ /* Authors: - Johann Dreo - Caner Candan + Johann Dreo + Caner Candan */ #ifndef _edoNormalMulti_h #define _edoNormalMulti_h +#include "edoDistrib.h" + +#ifdef WITH_BOOST + #include #include -#include "edoDistrib.h" namespace ublas = boost::numeric::ublas; //! edoNormalMulti< EOT > - template < typename EOT > class edoNormalMulti : public edoDistrib< EOT > { @@ -48,18 +50,18 @@ public: const ublas::vector< AtomType >& mean, const ublas::symmetric_matrix< AtomType, ublas::lower >& varcovar ) - : _mean(mean), _varcovar(varcovar) + : _mean(mean), _varcovar(varcovar) { - assert(_mean.size() > 0); - assert(_mean.size() == _varcovar.size1()); - assert(_mean.size() == _varcovar.size2()); + assert(_mean.size() > 0); + assert(_mean.size() == _varcovar.size1()); + assert(_mean.size() == _varcovar.size2()); } unsigned int size() { - assert(_mean.size() == _varcovar.size1()); - assert(_mean.size() == _varcovar.size2()); - return _mean.size(); + assert(_mean.size() == _varcovar.size1()); + assert(_mean.size() == _varcovar.size2()); + return _mean.size(); } ublas::vector< AtomType > mean() const {return _mean;} @@ -70,4 +72,49 @@ private: ublas::symmetric_matrix< AtomType, ublas::lower > _varcovar; }; + +#else +#ifdef WITH_EIGEN + +#include + +template < typename EOT > +class edoNormalMulti : public edoDistrib< EOT > +{ +public: + typedef typename EOT::AtomType AtomType; + typedef Eigen::Matrix< AtomType, Eigen::Dynamic, 1> Vector; + typedef Eigen::Matrix< AtomType, Eigen::Dynamic, Eigen::Dynamic> Matrix; + + edoNormalMulti( + const Vector & mean, + const Matrix & varcovar + ) + : _mean(mean), _varcovar(varcovar) + { + assert(_mean.innerSize() > 0); + assert(_mean.innerSize() == _varcovar.innerSize()); + assert(_mean.innerSize() == _varcovar.outerSize()); + } + + unsigned int size() + { + assert(_mean.innerSize() == _varcovar.innerSize()); + assert(_mean.innerSize() == _varcovar.outerSize()); + return _mean.innerSize(); + } + + Vector mean() const {return _mean;} + Matrix varcovar() const {return _varcovar;} + +private: + Vector _mean; + Matrix _varcovar; +}; + + + +#endif // WITH_EIGEN +#endif // WITH_BOOST + #endif // !_edoNormalMulti_h diff --git a/edo/src/edoNormalMultiCenter.h b/edo/src/edoNormalMultiCenter.h index 199ded47..de6cb26f 100644 --- a/edo/src/edoNormalMultiCenter.h +++ b/edo/src/edoNormalMultiCenter.h @@ -31,6 +31,8 @@ Authors: #include "edoModifierMass.h" #include "edoNormalMulti.h" +#ifdef WITH_BOOST + //! edoNormalMultiCenter< EOT > template < typename EOT > @@ -41,10 +43,35 @@ public: void operator() ( edoNormalMulti< EOT >& distrib, EOT& mass ) { - ublas::vector< AtomType > mean( distrib.size() ); - std::copy( mass.begin(), mass.end(), mean.begin() ); - distrib.mean() = mean; + ublas::vector< AtomType > mean( distrib.size() ); + std::copy( mass.begin(), mass.end(), mean.begin() ); + distrib.mean() = mean; } }; +#else +#ifdef WITH_EIGEN + +template < typename EOT, typename EOD = edoNormalMulti< EOT > > +class edoNormalMultiCenter : public edoModifierMass +{ +public: + typedef typename EOT::AtomType AtomType; + typedef typename EOD::Vector Vector; + + void operator() ( edoNormalMulti< EOT >& distrib, EOT& mass ) + { + assert( distrib.size() == mass.innerSize() ); + Vector mean( distrib.size() ); + for( unsigned int i=0; i < distrib.size(); i++ ) { + mean(i) = mass[i]; + } + distrib.mean() = mean; + } +}; + +#endif // WITH_EIGEN +#endif // WITH_BOOST + + #endif // !_edoNormalMultiCenter_h diff --git a/edo/src/edoSamplerNormalMulti.h b/edo/src/edoSamplerNormalMulti.h index b7e73c75..6420f040 100644 --- a/edo/src/edoSamplerNormalMulti.h +++ b/edo/src/edoSamplerNormalMulti.h @@ -32,9 +32,6 @@ Authors: #include #include -#include -#include -#include /** Sample points in a multi-normal law defined by a mean vector and a covariance matrix. * @@ -43,6 +40,13 @@ Authors: * - compute the Cholesky decomposition L of V (i.e. such as V=LL*) * - return X = M + LT */ + +#ifdef WITH_BOOST + +#include +#include +#include + template< class EOT, typename EOD = edoNormalMulti< EOT > > class edoSamplerNormalMulti : public edoSampler< EOD > { @@ -84,4 +88,86 @@ protected: cholesky::CholeskyLLT _cholesky; }; +#else +#ifdef WITH_EIGEN + +template< class EOT, typename EOD = edoNormalMulti< EOT > > +class edoSamplerNormalMulti : public edoSampler< EOD > +{ +public: + typedef typename EOT::AtomType AtomType; + + typedef typename EOD::Vector Vector; + typedef typename EOD::Matrix Matrix; + + edoSamplerNormalMulti( edoRepairer & repairer ) + : edoSampler< EOD >( repairer) + {} + + + EOT sample( EOD& distrib ) + { + unsigned int size = distrib.size(); + assert(size > 0); + + // LsD = cholesky decomposition of varcovar + + // Computes L and D such as V = L D L^T + Eigen::LDLT cholesky( distrib.varcovar() ); + Matrix L = cholesky.matrixL(); + assert(L.innerSize() == size); + assert(L.outerSize() == size); + + Matrix D = cholesky.vectorD().asDiagonal(); + assert(D.innerSize() == size); + assert(D.outerSize() == size); + + // now compute the final symetric matrix: LsD = L D^1/2 + // remember that V = ( L D^1/2) ( L D^1/2)^T + // fortunately, the square root of a diagonal matrix is the square + // root of all its elements + Matrix sqrtD = D.cwiseSqrt(); + assert(sqrtD.innerSize() == size); + assert(sqrtD.outerSize() == size); + + Matrix LsD = L * sqrtD; + assert(LsD.innerSize() == size); + assert(LsD.outerSize() == size); + + // T = vector of size elements drawn in N(0,1) + Vector T( size ); + for ( unsigned int i = 0; i < size; ++i ) { + T( i ) = rng.normal(); + } + assert(T.innerSize() == size); + assert(T.outerSize() == 1); + + // LDT = (L D^1/2) * T + Vector LDT = LsD * T; + assert(LDT.innerSize() == size); + assert(LDT.outerSize() == 1); + + // solution = means + LDT + Vector mean = distrib.mean(); + assert(mean.innerSize() == size); + assert(mean.outerSize() == 1); + + Vector typed_solution = mean + LDT; + assert(typed_solution.innerSize() == size); + assert(typed_solution.outerSize() == 1); + + // copy in the EOT structure (more probably a vector) + EOT solution( size ); + for( unsigned int i = 0; i < mean.innerSize(); i++ ) { + solution[i]= typed_solution(i); + } + assert( solution.size() == size ); + + return solution; + } +}; +#endif // WITH_EIGEN +#endif // WITH_BOOST + + #endif // !_edoSamplerNormalMulti_h diff --git a/edo/src/utils/edoCholesky.h b/edo/src/utils/edoCholesky.h index e0437d00..fad06750 100644 --- a/edo/src/utils/edoCholesky.h +++ b/edo/src/utils/edoCholesky.h @@ -27,6 +27,9 @@ Authors: namespace cholesky { + +#ifdef WITH_BOOST + /** Cholesky decomposition, given a matrix V, return a matrix L * such as V = L L^T (L^T being the transposed of L). * @@ -282,4 +285,11 @@ public: } }; +#else +#ifdef WITH_EIGEN + +#endif // WITH_EIGEN +#endif // WITH_BOOST + + } // namespace cholesky diff --git a/edo/src/utils/edoStatNormalMulti.h b/edo/src/utils/edoStatNormalMulti.h index 3a653edc..bc5066ac 100644 --- a/edo/src/utils/edoStatNormalMulti.h +++ b/edo/src/utils/edoStatNormalMulti.h @@ -28,13 +28,24 @@ Authors: #ifndef _edoStatNormalMulti_h #define _edoStatNormalMulti_h -#include +#include #include "edoStat.h" #include "edoNormalMulti.h" -//! edoStatNormalMulti< EOT > +#ifdef WITH_BOOST +#include + +#else +#ifdef WITH_EIGEN + + // include nothing + +#endif // WITH_EIGEN +#endif // WITH_BOOST + +//! edoStatNormalMulti< EOT > template < typename EOT > class edoStatNormalMulti : public edoDistribStat< edoNormalMulti< EOT > > { @@ -44,27 +55,28 @@ public: using edoDistribStat< edoNormalMulti< EOT > >::value; edoStatNormalMulti( std::string desc = "" ) - : edoDistribStat< edoNormalMulti< EOT > >( desc ) + : edoDistribStat< edoNormalMulti< EOT > >( desc ) {} void operator()( const edoNormalMulti< EOT >& distrib ) { - value() = "\n# ====== multi normal distribution dump =====\n"; + value() = "\n# ====== multi normal distribution dump =====\n"; - std::ostringstream os; + std::ostringstream os; - os << distrib.mean() << " " << distrib.varcovar() << std::endl; + os << distrib.mean() << std::endl << std::endl << distrib.varcovar() << std::endl; - // ublas::vector< AtomType > mean = distrib.mean(); - // std::copy(mean.begin(), mean.end(), std::ostream_iterator< std::string >( os, " " )); + // ublas::vector< AtomType > mean = distrib.mean(); + // std::copy(mean.begin(), mean.end(), std::ostream_iterator< std::string >( os, " " )); - // ublas::symmetric_matrix< AtomType, ublas::lower > varcovar = distrib.varcovar(); - // std::copy(varcovar.begin(), varcovar.end(), std::ostream_iterator< std::string >( os, " " )); + // ublas::symmetric_matrix< AtomType, ublas::lower > varcovar = distrib.varcovar(); + // std::copy(varcovar.begin(), varcovar.end(), std::ostream_iterator< std::string >( os, " " )); - // os << std::endl; + // os << std::endl; - value() += os.str(); + value() += os.str(); } }; + #endif // !_edoStatNormalMulti_h diff --git a/edo/test/CMakeLists.txt b/edo/test/CMakeLists.txt index 1ceea4f3..7a3129a1 100644 --- a/edo/test/CMakeLists.txt +++ b/edo/test/CMakeLists.txt @@ -33,7 +33,7 @@ LINK_DIRECTORIES(${Boost_LIBRARY_DIRS}) INCLUDE_DIRECTORIES(${CMAKE_SOURCE_DIR}/application/common) SET(SOURCES - t-cholesky + #t-cholesky t-edoEstimatorNormalMulti t-mean-distance t-bounderno diff --git a/edo/test/t-edoEstimatorNormalMulti.cpp b/edo/test/t-edoEstimatorNormalMulti.cpp index 91d93296..114f8fa1 100644 --- a/edo/test/t-edoEstimatorNormalMulti.cpp +++ b/edo/test/t-edoEstimatorNormalMulti.cpp @@ -40,22 +40,29 @@ typedef eoReal< eoMinimizingFitness > EOT; typedef edoNormalMulti< EOT > Distrib; typedef EOT::AtomType AtomType; +#ifdef WITH_BOOST +#include +#include + typedef ublas::vector< AtomType > Vector; + typedef ublas::symmetric_matrix< AtomType, ublas::lower > Matrix; +#else +#ifdef WITH_EIGEN +#include + typedef typename edoNormalMulti::Vector Vector; + typedef typename edoNormalMulti::Matrix Matrix; +#endif +#endif + int main(int ac, char** av) { - //----------------------------------------------------- // (0) parser + eo routines - //----------------------------------------------------- - eoParser parser(ac, av); - std::string section("Algorithm parameters"); - - unsigned int p_size = parser.createParam((unsigned int)100, "popSize", "Population Size", 'P', section).value(); // P - - unsigned int s_size = parser.createParam((unsigned int)2, "dimension-size", "Dimension size", 'd', section).value(); // d - - AtomType mean_value = parser.createParam((AtomType)0, "mean", "Mean value", 'm', section).value(); // m + std::string section("Algorithm parameters"); + unsigned int p_size = parser.createParam((unsigned int)100, "popSize", "Population Size", 'P', section).value(); // P + unsigned int s_size = parser.createParam((unsigned int)2, "dimension-size", "Dimension size", 'd', section).value(); // d + AtomType mean_value = parser.createParam((AtomType)0, "mean", "Mean value", 'm', section).value(); // m AtomType covar1_value = parser.createParam((AtomType)1.0, "covar1", "Covar value 1", '1', section).value(); AtomType covar2_value = parser.createParam((AtomType)0.5, "covar2", "Covar value 2", '2', section).value(); AtomType covar3_value = parser.createParam((AtomType)1.0, "covar3", "Covar value 3", '3', section).value(); @@ -66,29 +73,20 @@ int main(int ac, char** av) << covar3_value << "_gen"; std::string gen_filename = ss.str(); - if (parser.userNeedsHelp()) - { - parser.printHelp(std::cout); - exit(1); - } + if( parser.userNeedsHelp() ) { + parser.printHelp(std::cout); + exit(1); + } make_verbose(parser); make_help(parser); - assert(p_size > 0); assert(s_size > 0); - eoState state; - //----------------------------------------------------- - - - //----------------------------------------------------- // (1) Population init and sampler - //----------------------------------------------------- - eoRndGenerator< double >* gen = new eoUniformGenerator< double >(-5, 5); state.storeFunctor(gen); @@ -99,18 +97,14 @@ int main(int ac, char** av) // fill population thanks to eoInit instance eoPop< EOT >& pop = state.takeOwnership( eoPop< EOT >( p_size, *init ) ); - //----------------------------------------------------- - - - //----------------------------------------------------------------------------- // (2) distribution initial parameters - //----------------------------------------------------------------------------- + Vector mean( s_size ); - ublas::vector< AtomType > mean( s_size ); + for (unsigned int i = 0; i < s_size; ++i) { + mean( i ) = mean_value; + } - for (unsigned int i = 0; i < s_size; ++i) { mean( i ) = mean_value; } - - ublas::symmetric_matrix< AtomType, ublas::lower > varcovar( s_size, s_size ); + Matrix varcovar( s_size, s_size ); varcovar( 0, 0 ) = covar1_value; varcovar( 0, 1 ) = covar2_value; @@ -118,13 +112,7 @@ int main(int ac, char** av) Distrib distrib( mean, varcovar ); - //----------------------------------------------------------------------------- - - - //----------------------------------------------------------------------------- // (3a) distribution output preparation - //----------------------------------------------------------------------------- - edoDummyContinue< Distrib >* distrib_dummy_continue = new edoDummyContinue< Distrib >(); state.storeFunctor(distrib_dummy_continue); @@ -141,60 +129,29 @@ int main(int ac, char** av) distrib_file_snapshot->add(*distrib_stat); distrib_continue->add(*distrib_file_snapshot); - //----------------------------------------------------------------------------- - - - //----------------------------------------------------------------------------- // (3b) distribution output - //----------------------------------------------------------------------------- - (*distrib_continue)( distrib ); - //----------------------------------------------------------------------------- - - - //----------------------------------------------------------------------------- // Prepare bounder class to set bounds of sampling. // This is used by edoSampler. - //----------------------------------------------------------------------------- - - edoBounder< EOT >* bounder = new edoBounderRng< EOT >(EOT(pop[0].size(), -5), - EOT(pop[0].size(), 5), - *gen); + edoBounder< EOT >* bounder = new edoBounderRng< EOT >( + EOT(pop[0].size(), -5), EOT(pop[0].size(), 5), *gen + ); state.storeFunctor(bounder); - //----------------------------------------------------------------------------- - - - //----------------------------------------------------------------------------- // Prepare sampler class with a specific distribution - //----------------------------------------------------------------------------- - edoSampler< Distrib >* sampler = new edoSamplerNormalMulti< EOT >( *bounder ); state.storeFunctor(sampler); - //----------------------------------------------------------------------------- - - - //----------------------------------------------------------------------------- // (4) sampling phase - //----------------------------------------------------------------------------- - pop.clear(); - for (unsigned int i = 0; i < p_size; ++i) - { - EOT candidate_solution = (*sampler)( distrib ); - pop.push_back( candidate_solution ); - } + for( unsigned int i = 0; i < p_size; ++i ) { + EOT candidate_solution = (*sampler)( distrib ); + pop.push_back( candidate_solution ); + } - //----------------------------------------------------------------------------- - - - //----------------------------------------------------------------------------- // (5) population output - //----------------------------------------------------------------------------- - eoContinue< EOT >* pop_cont = new eoGenContinue< EOT >( 2 ); // never reached fitness state.storeFunctor(pop_cont); @@ -212,53 +169,31 @@ int main(int ac, char** av) (*pop_continue)( pop ); - //----------------------------------------------------------------------------- - - - //----------------------------------------------------------------------------- // (6) estimation phase - //----------------------------------------------------------------------------- - edoEstimator< Distrib >* estimator = new edoEstimatorNormalMulti< EOT >(); state.storeFunctor(estimator); distrib = (*estimator)( pop ); - //----------------------------------------------------------------------------- - - - //----------------------------------------------------------------------------- // (7) distribution output - //----------------------------------------------------------------------------- - (*distrib_continue)( distrib ); - //----------------------------------------------------------------------------- - - - //----------------------------------------------------------------------------- // (8) euclidianne distance estimation - //----------------------------------------------------------------------------- - - ublas::vector< AtomType > new_mean = distrib.mean(); - ublas::symmetric_matrix< AtomType, ublas::lower > new_varcovar = distrib.varcovar(); + Vector new_mean = distrib.mean(); + Matrix new_varcovar = distrib.varcovar(); AtomType distance = 0; - - for ( unsigned int d = 0; d < s_size; ++d ) - { - distance += pow( mean[ d ] - new_mean[ d ], 2 ); - } + for( unsigned int d = 0; d < s_size; ++d ) { + distance += pow( mean[ d ] - new_mean[ d ], 2 ); + } distance = sqrt( distance ); eo::log << eo::logging - << "mean: " << mean << std::endl - << "new mean: " << new_mean << std::endl - << "distance: " << distance << std::endl - ; - - //----------------------------------------------------------------------------- + << "mean: " << mean << std::endl + << "new mean: " << new_mean << std::endl + << "distance: " << distance << std::endl + ; return 0; } diff --git a/edo/test/t-mean-distance.cpp b/edo/test/t-mean-distance.cpp index 8e62c378..ae6de0eb 100644 --- a/edo/test/t-mean-distance.cpp +++ b/edo/test/t-mean-distance.cpp @@ -37,25 +37,33 @@ Authors: #include -#include -#include #include "Rosenbrock.h" #include "Sphere.h" typedef eoReal< eoMinimizingFitness > EOT; typedef edoNormalMulti< EOT > Distrib; -typedef EOT::AtomType AtomType; +typedef typename EOT::AtomType AtomType; + +#ifdef WITH_BOOST +#include +#include + typedef ublas::vector< AtomType > Vector; + typedef ublas::symmetric_matrix< AtomType, ublas::lower > Matrix; +#else +#ifdef WITH_EIGEN +#include + typedef typename edoNormalMulti::Vector Vector; + typedef typename edoNormalMulti::Matrix Matrix; +#endif +#endif int main(int ac, char** av) { - //----------------------------------------------------- // (0) parser + eo routines - //----------------------------------------------------- - eoParser parser(ac, av); - std::string section("Algorithm parameters"); + std::string section("Algorithm parameters"); unsigned int r_max = parser.createParam((unsigned int)100, "run-number", "Number of run", 'r', section).value(); // r unsigned int p_min = parser.createParam((unsigned int)10, "population-min", "Population min", 'p', section).value(); // p @@ -72,15 +80,15 @@ int main(int ac, char** av) std::string files_description = parser.createParam((std::string)"files_description.txt", "files-description", "Files description", 'F', section).value(); // F if (parser.userNeedsHelp()) - { - parser.printHelp(std::cout); - exit(1); - } + { + parser.printHelp(std::cout); + exit(1); + } make_verbose(parser); make_help(parser); - //----------------------------------------------------- + assert(r_max >= 1); assert(s_size >= 2); @@ -90,139 +98,146 @@ int main(int ac, char** av) ::mkdir( results_directory.c_str(), 0755 ); for ( unsigned int p_size = p_min; p_size <= p_max; p_size += p_step ) - { - assert(p_size >= p_min); + { + assert(p_size >= p_min); - std::ostringstream desc_file; - desc_file << results_directory << "/" << files_description; + std::ostringstream desc_file; + desc_file << results_directory << "/" << files_description; - std::ostringstream cur_file; - cur_file << results_directory << "/pop_" << p_size << ".txt"; + std::ostringstream cur_file; + cur_file << results_directory << "/pop_" << p_size << ".txt"; - eo::log << eo::file( desc_file.str() ) << cur_file.str().c_str() << std::endl; + eo::log << eo::file( desc_file.str() ) << cur_file.str().c_str() << std::endl; - eo::log << eo::file( cur_file.str() ); + eo::log << eo::file( cur_file.str() ); - eo::log << eo::logging << "run_number p_size s_size mean(0) mean(1) new-mean(0) new-mean(1) distance" << std::endl; + eo::log << eo::logging << "run_number p_size s_size mean(0) mean(1) new-mean(0) new-mean(1) distance" << std::endl; - eo::log << eo::quiet; + eo::log << eo::quiet; - for ( unsigned int r = 1; r <= r_max; ++r) - { + for ( unsigned int r = 1; r <= r_max; ++r) + { - eoState state; + eoState state; - //----------------------------------------------------- - // (1) Population init and sampler - //----------------------------------------------------- - eoRndGenerator< double >* gen = new eoUniformGenerator< double >(-5, 5); - state.storeFunctor(gen); - - eoInitFixedLength< EOT >* init = new eoInitFixedLength< EOT >( s_size, *gen ); - state.storeFunctor(init); - - // create an empty pop and let the state handle the memory - // fill population thanks to eoInit instance - eoPop< EOT >& pop = state.takeOwnership( eoPop< EOT >( p_size, *init ) ); - - //----------------------------------------------------- + // (1) Population init and sampler - //----------------------------------------------------------------------------- - // (2) distribution initial parameters - //----------------------------------------------------------------------------- + eoRndGenerator< double >* gen = new eoUniformGenerator< double >(-5, 5); + state.storeFunctor(gen); - ublas::vector< AtomType > mean( s_size, mean_value ); - ublas::symmetric_matrix< AtomType, ublas::lower > varcovar( s_size, s_size ); + eoInitFixedLength< EOT >* init = new eoInitFixedLength< EOT >( s_size, *gen ); + state.storeFunctor(init); - varcovar( 0, 0 ) = covar1_value; - varcovar( 0, 1 ) = covar2_value; - varcovar( 1, 1 ) = covar3_value; - - Distrib distrib( mean, varcovar ); - - //----------------------------------------------------------------------------- + // create an empty pop and let the state handle the memory + // fill population thanks to eoInit instance + eoPop< EOT >& pop = state.takeOwnership( eoPop< EOT >( p_size, *init ) ); - //----------------------------------------------------------------------------- - // Prepare bounder class to set bounds of sampling. - // This is used by edoSampler. - //----------------------------------------------------------------------------- - - edoBounder< EOT >* bounder = new edoBounderRng< EOT >(EOT(pop[0].size(), -5), - EOT(pop[0].size(), 5), - *gen); - state.storeFunctor(bounder); - - //----------------------------------------------------------------------------- - //----------------------------------------------------------------------------- - // Prepare sampler class with a specific distribution - //----------------------------------------------------------------------------- - edoSampler< Distrib >* sampler = new edoSamplerNormalMulti< EOT >( *bounder ); - state.storeFunctor(sampler); - - //----------------------------------------------------------------------------- + // (2) distribution initial parameters - //----------------------------------------------------------------------------- - // (4) sampling phase - //----------------------------------------------------------------------------- +#ifdef WITH_BOOST + Vector mean( s_size, mean_value ); +#else +#ifdef WITH_EIGEN + Vector mean( s_size ); + mean = Vector::Constant( s_size, mean_value); +#endif +#endif + Matrix varcovar( s_size, s_size ); - pop.clear(); + varcovar( 0, 0 ) = covar1_value; + varcovar( 0, 1 ) = covar2_value; + varcovar( 1, 1 ) = covar3_value; - for (unsigned int i = 0; i < p_size; ++i) - { - EOT candidate_solution = (*sampler)( distrib ); - pop.push_back( candidate_solution ); - } - - //----------------------------------------------------------------------------- + Distrib distrib( mean, varcovar ); - //----------------------------------------------------------------------------- - // (6) estimation phase - //----------------------------------------------------------------------------- - - edoEstimator< Distrib >* estimator = new edoEstimatorNormalMulti< EOT >(); - state.storeFunctor(estimator); - - distrib = (*estimator)( pop ); - - //----------------------------------------------------------------------------- - //----------------------------------------------------------------------------- - // (8) euclidianne distance estimation - //----------------------------------------------------------------------------- - ublas::vector< AtomType > new_mean = distrib.mean(); - ublas::symmetric_matrix< AtomType, ublas::lower > new_varcovar = distrib.varcovar(); + // Prepare bounder class to set bounds of sampling. + // This is used by edoSampler. - AtomType distance = 0; - for ( unsigned int d = 0; d < s_size; ++d ) - { - distance += pow( mean[ d ] - new_mean[ d ], 2 ); - } + edoBounder< EOT >* bounder = new edoBounderRng< EOT >(EOT(pop[0].size(), -5), + EOT(pop[0].size(), 5), + *gen); + state.storeFunctor(bounder); - distance = sqrt( distance ); - eo::log << r << " " << p_size << " " << s_size << " " - << mean(0) << " " << mean(1) << " " - << new_mean(0) << " " << new_mean(1) << " " - << distance << std::endl - ; - //----------------------------------------------------------------------------- - } - } + // Prepare sampler class with a specific distribution + + + edoSampler< Distrib >* sampler = new edoSamplerNormalMulti< EOT >( *bounder ); + state.storeFunctor(sampler); + + + + + + // (4) sampling phase + + + pop.clear(); + + for (unsigned int i = 0; i < p_size; ++i) + { + EOT candidate_solution = (*sampler)( distrib ); + pop.push_back( candidate_solution ); + } + + + + + + // (6) estimation phase + + + edoEstimator< Distrib >* estimator = new edoEstimatorNormalMulti< EOT >(); + state.storeFunctor(estimator); + + distrib = (*estimator)( pop ); + + + + + + // (8) euclidianne distance estimation + + + Vector new_mean = distrib.mean(); + Matrix new_varcovar = distrib.varcovar(); + + AtomType distance = 0; + + for ( unsigned int d = 0; d < s_size; ++d ) + { + distance += pow( mean[ d ] - new_mean[ d ], 2 ); + } + + distance = sqrt( distance ); + + eo::log << r << " " << p_size << " " << s_size << " " + << mean(0) << " " << mean(1) << " " + << new_mean(0) << " " << new_mean(1) << " " + << distance << std::endl + ; + + + + } + + } return 0; } diff --git a/eo/NEWS b/eo/NEWS index f4625d6c..369682af 100644 --- a/eo/NEWS +++ b/eo/NEWS @@ -1,4 +1,22 @@ * current version + - features: + - delete the deprecated code parts (was marked as deprecated in the release 1.1) + - eoSignal: a class to handle signal with eoCheckpoint instances + - eoDetSingleBitFlip: bit flip mutation that changes exactly k bits while checking for duplicate + - eoFunctorStat: a wrapper to turn any stand-alone function and into an eoStat + - generilazed the output of an eoState: now you can change the format, comes with defaults formatting (latex and json) + - eoWrongParamTypeException: a new exception to handle cases where a wrong template is given to eoParser::valueOf + - added a getParam method to the eoParser, that raise an exception if the parameter has not been declared + - eoParserLogger features are now included in the default eoParser + - build system: + - improvements of the build architecture + - create PKGBUILD file for archlinux package manager + - a FindEO module for CMake + - bugfixes: + - fixed regression with gcc 4.7 + - fixed compilation issues in Microsoft Visual C++, related to time measurement + - added several asserts accross the framework (note: asserts are included only in debug mode) + - lot of small bugfixes :-) * release 1.2 (16. May. 2011) - fixed the incremental allocation issue in variation operators which were @@ -20,11 +38,11 @@ - GCC 4.3 compatibility - new versatile log system with several nested verbose levels - classes using intern verbose parameters marked as deprecated, please update your code accordingly if you use one of the following files: - eo/src/eoCombinedInit.h - eo/src/eoGenContinue.h - eo/src/eoProportionalCombinedOp.h - eo/src/utils/eoData.h - eo/src/utils/eoStdoutMonitor.h + eo/src/eoCombinedInit.h + eo/src/eoGenContinue.h + eo/src/eoProportionalCombinedOp.h + eo/src/utils/eoData.h + eo/src/utils/eoStdoutMonitor.h - an evaluator that throw an exception if a maximum eval numbers has been reached, independently of the number of generations - new monitor that can write on any ostream - new continuator that can catch POSIX system user signals diff --git a/eo/src/apply.h b/eo/src/apply.h index 01256e05..bbd30aa3 100644 --- a/eo/src/apply.h +++ b/eo/src/apply.h @@ -58,14 +58,26 @@ void apply(eoUF& _proc, std::vector& _pop) if (!eo::parallel.isDynamic()) { #pragma omp parallel for if(eo::parallel.isEnabled()) //default(none) shared(_proc, _pop, size) +#ifdef _MSC_VER + //Visual Studio supports only OpenMP version 2.0 in which + //an index variable must be of a signed integral type + for (long long i = 0; i < size; ++i) { _proc(_pop[i]); } +#else // _MSC_VER for (size_t i = 0; i < size; ++i) { _proc(_pop[i]); } +#endif } else { #pragma omp parallel for schedule(dynamic) if(eo::parallel.isEnabled()) +#ifdef _MSC_VER + //Visual Studio supports only OpenMP version 2.0 in which + //an index variable must be of a signed integral type + for (long long i = 0; i < size; ++i) { _proc(_pop[i]); } +#else // _MSC_VER //doesnot work with gcc 4.1.2 //default(none) shared(_proc, _pop, size) for (size_t i = 0; i < size; ++i) { _proc(_pop[i]); } +#endif } if ( eo::parallel.enableResults() ) diff --git a/eo/src/eoEvalUserTimeThrowException.h b/eo/src/eoEvalUserTimeThrowException.h index ed0145de..2d9ccadd 100644 --- a/eo/src/eoEvalUserTimeThrowException.h +++ b/eo/src/eoEvalUserTimeThrowException.h @@ -21,27 +21,30 @@ Authors: Johann Dréo */ -#ifndef __unix__ -#warning "Warning: class 'eoEvalUserTimeThrowException' is only available under UNIX systems (defining 'rusage' in 'sys/resource.h'), contributions for other systems are welcomed." -#else +#if !defined(__unix__) && !defined(_WINDOWS) +#warning "Warning: class 'eoEvalUserTimeThrowException' is only available under UNIX (defining 'rusage' in 'sys/resource.h') or Win32 (defining 'GetProcessTimes' in 'WinBase.h') systems, contributions for other systems are welcomed." +#else //!defined(__unix__) && !defined(_WINDOWS) #ifndef __EOEVALUSERTIMETHROWEXCEPTION_H__ #define __EOEVALUSERTIMETHROWEXCEPTION_H__ -#include -#include - -#include - /** Check at each evaluation if a given CPU user time contract has been reached. * * Throw an eoMaxTimeException if the given max time has been reached. * Usefull if you want to end the search independently of generations. - * This class uses (almost-)POSIX headers. + * This class uses (almost-)POSIX or Win32 headers, depending on the platform. * It uses a computation of the user time used on the CPU. For a wallclock time measure, see eoEvalTimeThrowException * * @ingroup Evaluation */ + +#include + +#ifdef __unix__ + +#include +#include + template< class EOT > class eoEvalUserTimeThrowException : public eoEvalFuncCounter< EOT > { @@ -68,5 +71,41 @@ protected: struct rusage _usage; }; +#else +#ifdef _WINDOWS +//here _WINDOWS is defined + +#include + +template< class EOT > +class eoEvalUserTimeThrowException : public eoEvalFuncCounter< EOT > +{ +public: + eoEvalUserTimeThrowException( eoEvalFunc & func, const long max ) : eoEvalFuncCounter( func, "CPU-user"), _max(max) {} + + virtual void operator() ( EOT & eo ) + { + if( eo.invalid() ) { + FILETIME dummy; + GetProcessTimes(GetCurrentProcess(), &dummy, &dummy, &dummy, &_usage); + + ULARGE_INTEGER current; + current.LowPart = _usage.dwLowDateTime; + current.HighPart = _usage.dwHighDateTime; + if( current.QuadPart >= _max ) { + throw eoMaxTimeException( current.QuadPart ); + } else { + func(eo); + } + } + } + +protected: + const long _max; + FILETIME _usage; +}; + +#endif // _WINDOWS +#endif //__unix__ #endif // __EOEVALUSERTIMETHROWEXCEPTION_H__ -#endif // __UNIX__ +#endif //!defined(__unix__) && !defined(_WINDOWS)