diff --git a/edo/CMakeLists.txt b/edo/CMakeLists.txt index 10b1fbe23..9a07cd619 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 000000000..caed81408 --- /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 5b814b15d..4217a844e 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 eea3dcb90..c03fa57de 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 000000000..ade261ac7 --- /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 000000000..18c3f093f --- /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 250e6bf1e..075057186 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 144a5298a..74b2b6d29 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 000000000..ea754f9bd --- /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 cfd979fe4..41eb78f5e 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 be0e7d00a..db36810a0 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 199ded47a..de6cb26fa 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 b7e73c754..6420f0408 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 e0437d009..fad067507 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 3a653edc5..bc5066ac7 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 1ceea4f3b..7a3129a1d 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 91d932962..114f8fa17 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 8e62c378a..ae6de0eb3 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/install_symlink.py.cmake b/eo/install_symlink.py.cmake index fd71d68b5..382c0b9f6 100755 --- a/eo/install_symlink.py.cmake +++ b/eo/install_symlink.py.cmake @@ -31,8 +31,16 @@ def uninstall(): print('All symlinks have been removed.') def install(): - for dirname in DATA['dirs']: os.mkdir(dirname) - for src, dst in DATA['links']: os.symlink(src, dst) + for dirname in DATA['dirs']: + try: + os.makedirs(dirname) + except(os.error): + pass + for src, dst in DATA['links']: + try: + os.symlink(src, dst) + except: + pass print('All symlinks have been installed.') def data(): diff --git a/eo/src/apply.h b/eo/src/apply.h index f685f8d3b..01256e059 100644 --- a/eo/src/apply.h +++ b/eo/src/apply.h @@ -31,7 +31,10 @@ #include #include #include + +#ifdef _OPENMP #include +#endif /** Applies a unary function to a std::vector of things. diff --git a/eo/src/do/make_checkpoint.h b/eo/src/do/make_checkpoint.h index 7958ed5b0..cc0746ddb 100644 --- a/eo/src/do/make_checkpoint.h +++ b/eo/src/do/make_checkpoint.h @@ -1,45 +1,32 @@ // -*- mode: c++; c-indent-level: 4; c++-member-init-indent: 8; comment-column: 35; -*- - - //----------------------------------------------------------------------------- - // make_checkpoint.h - // (c) Maarten Keijzer, Marc Schoenauer and GeNeura Team, 2000 - /* - 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 of the License, or (at your option) any later version. + 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 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. + 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - - Contact: todos@geneura.ugr.es, http://geneura.ugr.es - - Marc.Schoenauer@polytechnique.fr - - mkeijzer@dhi.dk - - */ + 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + Contact: todos@geneura.ugr.es, http://geneura.ugr.es + Marc.Schoenauer@polytechnique.fr + mkeijzer@dhi.dk +*/ //----------------------------------------------------------------------------- - - #ifndef _make_checkpoint_h - #define _make_checkpoint_h - #ifdef HAVE_CONFIG_H #include #endif @@ -52,521 +39,315 @@ #include #include - - // at the moment, in utils/make_help.cpp - // this should become some eoUtils.cpp with corresponding eoUtils.h - bool testDirRes(std::string _dirName, bool _erase); - /////////////////// The checkpoint and other I/O ////////////// - - - /** * * CHANGE (March 2008): now receiving an eoValueParam instead of an eoEvalFuncCounter. This function is just interested * in the value of the parameter calculated on the evaluation function, not in the actual function itself!! * * @ingroup Builders -*/ + */ template eoCheckPoint& do_make_checkpoint(eoParser& _parser, eoState& _state, eoValueParam& _eval, eoContinue& _continue) { + // first, create a checkpoint from the eoContinue + eoCheckPoint *checkpoint = new eoCheckPoint(_continue); - // first, create a checkpoint from the eoContinue - eoCheckPoint *checkpoint = new eoCheckPoint(_continue); + _state.storeFunctor(checkpoint); - _state.storeFunctor(checkpoint); + //////////////////// + // Signal monitoring + //////////////////// +#ifndef _MSC_VER + // the CtrlC monitoring interception + eoSignal *mon_ctrlCCont; + eoValueParam& mon_ctrlCParam = _parser.createParam(false, "monitor-with-CtrlC", "Monitor current generation upon Ctrl C",0, "Stopping criterion"); + if (mon_ctrlCParam.value()) + { + mon_ctrlCCont = new eoSignal; + // store + _state.storeFunctor(mon_ctrlCCont); + // add to checkpoint + checkpoint->add(*mon_ctrlCCont); + } +#endif + /////////////////// + // Counters + ////////////////// - /////////////////// + // is nb Eval to be used as counter? + eoValueParam& useEvalParam = _parser.createParam(true, "useEval", "Use nb of eval. as counter (vs nb of gen.)", '\0', "Output"); + eoValueParam& useTimeParam = _parser.createParam(true, "useTime", "Display time (s) every generation", '\0', "Output"); + // if we want the time, we need an eoTimeCounter + eoTimeCounter * tCounter = NULL; - // Counters - - ////////////////// - - // is nb Eval to be used as counter? - - eoValueParam& useEvalParam = _parser.createParam(true, "useEval", "Use nb of eval. as counter (vs nb of gen.)", '\0', "Output"); - - eoValueParam& useTimeParam = _parser.createParam(true, "useTime", "Display time (s) every generation", '\0', "Output"); - - - - // if we want the time, we need an eoTimeCounter - - eoTimeCounter * tCounter = NULL; - - - - // Create anyway a generation-counter - - // Recent change (03/2002): it is now an eoIncrementorParam, both - - // a parameter AND updater so you can store it into the eoState - - eoIncrementorParam *generationCounter = new eoIncrementorParam("Gen."); - - // store it in the state - - _state.storeFunctor(generationCounter); - - // And add it to the checkpoint, - - checkpoint->add(*generationCounter); + // Create anyway a generation-counter + // Recent change (03/2002): it is now an eoIncrementorParam, both + // a parameter AND updater so you can store it into the eoState + eoIncrementorParam *generationCounter = new eoIncrementorParam("Gen."); + // store it in the state + _state.storeFunctor(generationCounter); + // And add it to the checkpoint, + checkpoint->add(*generationCounter); // dir for DISK output - eoValueParam& dirNameParam = _parser.createParam(std::string("Res"), "resDir", "Directory to store DISK outputs", '\0', "Output - Disk"); // shoudl we empty it if exists - eoValueParam& eraseParam = _parser.createParam(true, "eraseDir", "erase files in dirName if any", '\0', "Output - Disk"); bool dirOK = false; // not tested yet - - ///////////////////////////////////////// - // now some statistics on the population: - ///////////////////////////////////////// /** - * existing stats as of today, April 10. 2001 - * - * eoBestFitnessStat : best value in pop - type EOT::Fitness - * eoAverageStat : average value in pop - type EOT::Fitness - * eoSecondMomentStat: average + stdev - type std::pair - * eoSortedPopStat : whole population - type std::string (!!) - * eoScalarFitnessStat: the fitnesses - type std::vector - */ - - // Best fitness in population - //--------------------------- - eoValueParam& printBestParam = _parser.createParam(true, "printBestStat", "Print Best/avg/stdev every gen.", '\0', "Output"); - eoValueParam& plotBestParam = _parser.createParam(false, "plotBestStat", "Plot Best/avg Stat", '\0', "Output - Graphical"); - eoValueParam& fileBestParam = _parser.createParam(false, "fileBestStat", "Output bes/avg/std to file", '\0', "Output - Disk"); - - eoBestFitnessStat *bestStat = NULL; - if ( printBestParam.value() || plotBestParam.value() || fileBestParam.value() ) - - // we need the bestStat for at least one of the 3 above - - { - - bestStat = new eoBestFitnessStat; - - // store it - - _state.storeFunctor(bestStat); - - // add it to the checkpoint - - checkpoint->add(*bestStat); - - } - - + // we need the bestStat for at least one of the 3 above + { + bestStat = new eoBestFitnessStat; + // store it + _state.storeFunctor(bestStat); + // add it to the checkpoint + checkpoint->add(*bestStat); + // check if monitoring with signal + if ( mon_ctrlCParam.value() ) + mon_ctrlCCont->add(*bestStat); + } // Average fitness alone - //---------------------- - eoAverageStat *averageStat = NULL; // do we need averageStat? - - if ( plotBestParam.value() ) // we need it for gnuplot output - - { - - averageStat = new eoAverageStat; - - // store it - - _state.storeFunctor(averageStat); - - // add it to the checkpoint - - checkpoint->add(*averageStat); - - } - - + if ( printBestParam.value() || plotBestParam.value() || fileBestParam.value() ) // we need it for gnuplot output + { + averageStat = new eoAverageStat; + // store it + _state.storeFunctor(averageStat); + // add it to the checkpoint + checkpoint->add(*averageStat); + // check if monitoring with signal + if ( mon_ctrlCParam.value() ) + mon_ctrlCCont->add(*averageStat); + } // Second moment stats: average and stdev - //--------------------------------------- - eoSecondMomentStats *secondStat = NULL; - - if ( printBestParam.value() || fileBestParam.value() ) // we need it for screen output or file output - - { - - secondStat = new eoSecondMomentStats; - - // store it - - _state.storeFunctor(secondStat); - - // add it to the checkpoint - - checkpoint->add(*secondStat); - - } - - - - + if ( printBestParam.value() || fileBestParam.value() ) // we need it for screen output or file output + { + secondStat = new eoSecondMomentStats; + // store it + _state.storeFunctor(secondStat); + // add it to the checkpoint + checkpoint->add(*secondStat); + // check if monitoring with signal + if ( mon_ctrlCParam.value() ) + mon_ctrlCCont->add(*secondStat); + } // Dump of the whole population - //----------------------------- - eoSortedPopStat *popStat = NULL; - eoValueParam& printPopParam = _parser.createParam(false, "printPop", "Print sorted pop. every gen.", '\0', "Output"); if ( printPopParam.value() ) // we do want pop dump - - { - - popStat = new eoSortedPopStat; - - // store it - - _state.storeFunctor(popStat); - - // add it to the checkpoint - - checkpoint->add(*popStat); - - } - - - - + { + popStat = new eoSortedPopStat; + // store it + _state.storeFunctor(popStat); + // add it to the checkpoint + checkpoint->add(*popStat); + // check if monitoring with signal + if ( mon_ctrlCParam.value() ) + mon_ctrlCCont->add(*popStat); + } // do we wnat some histogram of fitnesses snpashots? - eoValueParam plotHistogramParam = _parser.createParam(false, "plotHisto", "Plot histogram of fitnesses", '\0', "Output - Graphical"); - - /////////////// - // The monitors - /////////////// // do we want an eoStdoutMonitor? - bool needStdoutMonitor = printBestParam.value() - || printPopParam.value() ; - - // The Stdout monitor will print parameters to the screen ... - if ( needStdoutMonitor ) + { + eoStdoutMonitor *monitor = new eoStdoutMonitor(/*false FIXME remove this deprecated prototype*/); + _state.storeFunctor(monitor); - { + // when called by the checkpoint (i.e. at every generation) + // check if monitoring with signal + if ( ! mon_ctrlCParam.value() ) + checkpoint->add(*monitor); + else + mon_ctrlCCont->add(*monitor); - eoStdoutMonitor *monitor = new eoStdoutMonitor(false); + // the monitor will output a series of parameters: add them + monitor->add(*generationCounter); - _state.storeFunctor(monitor); - - - - // when called by the checkpoint (i.e. at every generation) - - checkpoint->add(*monitor); - - - - // the monitor will output a series of parameters: add them - - monitor->add(*generationCounter); - - if (useEvalParam.value()) // we want nb of evaluations - - monitor->add(_eval); - - if (useTimeParam.value()) // we want time - - { - - tCounter = new eoTimeCounter; - - _state.storeFunctor(tCounter); - - checkpoint->add(*tCounter); - - monitor->add(*tCounter); - - } - - if (printBestParam.value()) - - { - - monitor->add(*bestStat); - - monitor->add(*secondStat); - - } - - if ( printPopParam.value()) - - monitor->add(*popStat); - - } + if (useEvalParam.value()) // we want nb of evaluations + monitor->add(_eval); + if (useTimeParam.value()) // we want time + { + tCounter = new eoTimeCounter; + _state.storeFunctor(tCounter); + // check if monitoring with signal + if ( ! mon_ctrlCParam.value() ) + checkpoint->add(*tCounter); + else + mon_ctrlCCont->add(*tCounter); + monitor->add(*tCounter); + } + if (printBestParam.value()) + { + monitor->add(*bestStat); + monitor->add(*secondStat); + } + if ( printPopParam.value()) + monitor->add(*popStat); + } // first handle the dir test - if we need at least one file - if ( ( fileBestParam.value() || plotBestParam.value() || - plotHistogramParam.value() ) - && !dirOK ) // just in case we add something before - - dirOK = testDirRes(dirNameParam.value(), eraseParam.value()); // TRUE - - + dirOK = testDirRes(dirNameParam.value(), eraseParam.value()); // TRUE if (fileBestParam.value()) // A file monitor for best & secondMoment - - { - + { #ifdef _MSVC - - std::string stmp = dirNameParam.value() + "\best.xg"; - + std::string stmp = dirNameParam.value() + "\best.xg"; #else - - std::string stmp = dirNameParam.value() + "/best.xg"; - + std::string stmp = dirNameParam.value() + "/best.xg"; #endif - - eoFileMonitor *fileMonitor = new eoFileMonitor(stmp); - - // save and give to checkpoint - - _state.storeFunctor(fileMonitor); - - checkpoint->add(*fileMonitor); - - // and feed with some statistics - - fileMonitor->add(*generationCounter); - - fileMonitor->add(_eval); - - if (tCounter) // we want the time as well - - { - - // std::cout << "On met timecounter\n"; - - fileMonitor->add(*tCounter); - - } - - fileMonitor->add(*bestStat); - - fileMonitor->add(*secondStat); - - } - - + eoFileMonitor *fileMonitor = new eoFileMonitor(stmp); + // save and give to checkpoint + _state.storeFunctor(fileMonitor); + checkpoint->add(*fileMonitor); + // and feed with some statistics + fileMonitor->add(*generationCounter); + fileMonitor->add(_eval); + if (tCounter) // we want the time as well + { + // std::cout << "On met timecounter\n"; + fileMonitor->add(*tCounter); + } + fileMonitor->add(*bestStat); + fileMonitor->add(*secondStat); + } #if defined(HAVE_GNUPLOT) - if (plotBestParam.value()) // an eoGnuplot1DMonitor for best & average - - { - - std::string stmp = dirNameParam.value() + "/gnu_best.xg"; - - eoGnuplot1DMonitor *gnuMonitor = new eoGnuplot1DMonitor(stmp,minimizing_fitness()); - - // save and give to checkpoint - - _state.storeFunctor(gnuMonitor); - - checkpoint->add(*gnuMonitor); - - // and feed with some statistics - - if (useEvalParam.value()) // do we want eval as X coordinate - - gnuMonitor->add(_eval); - - else if (tCounter) // or time? - - gnuMonitor->add(*tCounter); - - else // default: generation - - gnuMonitor->add(*generationCounter); - - gnuMonitor->add(*bestStat); - - gnuMonitor->add(*averageStat); - - } - - + { + std::string stmp = dirNameParam.value() + "/gnu_best.xg"; + eoGnuplot1DMonitor *gnuMonitor = new eoGnuplot1DMonitor(stmp,minimizing_fitness()); + // save and give to checkpoint + _state.storeFunctor(gnuMonitor); + checkpoint->add(*gnuMonitor); + // and feed with some statistics + if (useEvalParam.value()) // do we want eval as X coordinate + gnuMonitor->add(_eval); + else if (tCounter) // or time? + gnuMonitor->add(*tCounter); + else // default: generation + gnuMonitor->add(*generationCounter); + gnuMonitor->add(*bestStat); + gnuMonitor->add(*averageStat); + } // historgram? - if (plotHistogramParam.value()) // want to see how the fitness is spread? - - { - - eoScalarFitnessStat *fitStat = new eoScalarFitnessStat; - - _state.storeFunctor(fitStat); - - checkpoint->add(*fitStat); - - // a gnuplot-based monitor for snapshots: needs a dir name - - eoGnuplot1DSnapshot *fitSnapshot = new eoGnuplot1DSnapshot(dirNameParam.value()); - - _state.storeFunctor(fitSnapshot); - - // add any stat that is a std::vector to it - - fitSnapshot->add(*fitStat); - - // and of course add it to the checkpoint - - checkpoint->add(*fitSnapshot); - - } + { + eoScalarFitnessStat *fitStat = new eoScalarFitnessStat; + _state.storeFunctor(fitStat); + checkpoint->add(*fitStat); + // a gnuplot-based monitor for snapshots: needs a dir name + eoGnuplot1DSnapshot *fitSnapshot = new eoGnuplot1DSnapshot(dirNameParam.value()); + _state.storeFunctor(fitSnapshot); + // add any stat that is a std::vector to it + fitSnapshot->add(*fitStat); + // and of course add it to the checkpoint + checkpoint->add(*fitSnapshot); + } #endif ////////////////////////////////// - // State savers - ////////////////////////////// - - // feed the state to state savers - // save state every N generation - eoValueParam& saveFrequencyParam = _parser.createParam(unsigned(0), "saveFrequency", "Save every F generation (0 = only final state, absent = never)", '\0', "Persistence" ); - - if (_parser.isItThere(saveFrequencyParam)) + { + // first make sure dirName is OK + if (! dirOK ) + dirOK = testDirRes(dirNameParam.value(), eraseParam.value()); // TRUE - { - - // first make sure dirName is OK - - if (! dirOK ) - - dirOK = testDirRes(dirNameParam.value(), eraseParam.value()); // TRUE - - - - unsigned freq = (saveFrequencyParam.value()>0 ? saveFrequencyParam.value() : UINT_MAX ); - + unsigned freq = (saveFrequencyParam.value()>0 ? saveFrequencyParam.value() : UINT_MAX ); #ifdef _MSVC - - std::string stmp = dirNameParam.value() + "\generations"; - + std::string stmp = dirNameParam.value() + "\generations"; #else - - std::string stmp = dirNameParam.value() + "/generations"; - + std::string stmp = dirNameParam.value() + "/generations"; #endif - - eoCountedStateSaver *stateSaver1 = new eoCountedStateSaver(freq, _state, stmp); - - _state.storeFunctor(stateSaver1); - - checkpoint->add(*stateSaver1); - - } - - + eoCountedStateSaver *stateSaver1 = new eoCountedStateSaver(freq, _state, stmp); + _state.storeFunctor(stateSaver1); + checkpoint->add(*stateSaver1); + } // save state every T seconds - eoValueParam& saveTimeIntervalParam = _parser.createParam(unsigned(0), "saveTimeInterval", "Save every T seconds (0 or absent = never)", '\0',"Persistence" ); - if (_parser.isItThere(saveTimeIntervalParam) && saveTimeIntervalParam.value()>0) - - { - - // first make sure dirName is OK - - if (! dirOK ) - - dirOK = testDirRes(dirNameParam.value(), eraseParam.value()); // TRUE - - + { + // first make sure dirName is OK + if (! dirOK ) + dirOK = testDirRes(dirNameParam.value(), eraseParam.value()); // TRUE #ifdef _MSVC - - std::string stmp = dirNameParam.value() + "\time"; - + std::string stmp = dirNameParam.value() + "\time"; #else - - std::string stmp = dirNameParam.value() + "/time"; - + std::string stmp = dirNameParam.value() + "/time"; #endif - - eoTimedStateSaver *stateSaver2 = new eoTimedStateSaver(saveTimeIntervalParam.value(), _state, stmp); - - _state.storeFunctor(stateSaver2); - - checkpoint->add(*stateSaver2); - - } - - + eoTimedStateSaver *stateSaver2 = new eoTimedStateSaver(saveTimeIntervalParam.value(), _state, stmp); + _state.storeFunctor(stateSaver2); + checkpoint->add(*stateSaver2); + } // and that's it for the (control and) output - return *checkpoint; - } - - #endif diff --git a/eo/src/do/make_checkpoint_FDC.h b/eo/src/do/make_checkpoint_FDC.h index 33c7f7206..f241667f7 100644 --- a/eo/src/do/make_checkpoint_FDC.h +++ b/eo/src/do/make_checkpoint_FDC.h @@ -175,7 +175,7 @@ eoCheckPoint& do_make_checkpoint(eoParser& _parser, eoState& _state, eoEval // The Stdout monitor will print parameters to the screen ... if ( needStdoutMonitor ) { - eoStdoutMonitor *monitor = new eoStdoutMonitor(false); + eoStdoutMonitor *monitor = new eoStdoutMonitor(/*false FIXME remove this deprecated prototype*/); _state.storeFunctor(monitor); // when called by the checkpoint (i.e. at every generation) diff --git a/eo/src/do/make_checkpoint_assembled.h b/eo/src/do/make_checkpoint_assembled.h index 26463fab3..27d050ada 100644 --- a/eo/src/do/make_checkpoint_assembled.h +++ b/eo/src/do/make_checkpoint_assembled.h @@ -129,7 +129,7 @@ eoCheckPoint& do_make_checkpoint_assembled(eoParser& _parser, eoState& _sta // STDOUT // ------ - eoStdoutMonitor *monitor = new eoStdoutMonitor(false); + eoStdoutMonitor *monitor = new eoStdoutMonitor(/*false FIXME remove this deprecated prototype*/); _state.storeFunctor(monitor); checkpoint->add(*monitor); monitor->add(*generationCounter); diff --git a/eo/src/eoCombinedContinue.h b/eo/src/eoCombinedContinue.h index dfb70f67b..5162ffaa9 100644 --- a/eo/src/eoCombinedContinue.h +++ b/eo/src/eoCombinedContinue.h @@ -57,6 +57,7 @@ public: { } + /* FIXME remove in next release /// Ctor - for historical reasons ... should disspear some day eoCombinedContinue( eoContinue& _cont1, eoContinue& _cont2) : eoContinue(), std::vector* >() @@ -68,12 +69,14 @@ public: this->push_back(&_cont1); this->push_back(&_cont2); } + */ void add(eoContinue & _cont) { this->push_back(&_cont); } + /* FIXME remove in next release void removeLast(void) { #ifndef DEPRECATED_MESSAGES @@ -82,6 +85,7 @@ public: this->pop_back(); } + */ /** Returns false when one of the embedded continuators say so (logical and) diff --git a/eo/src/eoCombinedInit.h b/eo/src/eoCombinedInit.h index d41122d85..cc93620d3 100644 --- a/eo/src/eoCombinedInit.h +++ b/eo/src/eoCombinedInit.h @@ -44,11 +44,13 @@ public: rates.push_back(_rate); } + /* FIXME remove in next release void add(eoInit & _init, double _rate, bool _verbose) { eo::log << eo::warnings << "WARNING: the use of the verbose parameter in eoCombinedInit::add is deprecated and will be removed in the next release." << std::endl; add( _init, _rate ); } + */ /** The usual method to add objects to the combination */ diff --git a/eo/src/eoCtrlCContinue.h b/eo/src/eoCtrlCContinue.h index 9bbcf9c09..e239f7367 100644 --- a/eo/src/eoCtrlCContinue.h +++ b/eo/src/eoCtrlCContinue.h @@ -30,7 +30,7 @@ #ifndef eoCtrlCContinue_h #define eoCtrlCContinue_h -#include +#include #include /** diff --git a/eo/src/eoFunctorStore.h b/eo/src/eoFunctorStore.h index c609637b4..051daf2ae 100644 --- a/eo/src/eoFunctorStore.h +++ b/eo/src/eoFunctorStore.h @@ -28,6 +28,9 @@ #define _eoFunctorStore_h #include +#include + +#include "utils/eoLogger.h" class eoFunctorBase; @@ -52,6 +55,13 @@ public: template Functor& storeFunctor(Functor* r) { +#ifndef NDEBUG + unsigned int existing = std::count( vec.begin(), vec.end(), r ); + if( existing > 0 ) { + eo::log << eo::warnings << "WARNING: you asked eoFunctorStore to store the functor " << r << " " + << existing + 1 << " times, a segmentation fault may occur in the destructor." << std::endl; + } +#endif // If the compiler complains about the following line, // check if you really are giving it a pointer to an // eoFunctorBase derived object @@ -67,6 +77,7 @@ private : /** no assignment allowed */ eoFunctorStore operator=(const eoFunctorStore&); +protected: std::vector vec; }; diff --git a/eo/src/eoMergeReduce.h b/eo/src/eoMergeReduce.h index b3cb5b990..6a2618d9d 100644 --- a/eo/src/eoMergeReduce.h +++ b/eo/src/eoMergeReduce.h @@ -55,7 +55,7 @@ class eoMergeReduce : public eoReplacement merge(_merge), reduce(_reduce) {} - void operator()(eoPop& _parents, eoPop& _offspring) + virtual void operator()(eoPop& _parents, eoPop& _offspring) { merge(_parents, _offspring); // parents untouched, result in offspring reduce(_offspring, _parents.size()); @@ -92,6 +92,14 @@ class eoCommaReplacement : public eoMergeReduce public : eoCommaReplacement() : eoMergeReduce(no_elite, truncate) {} + virtual void operator()(eoPop& _parents, eoPop& _offspring) + { + // There must be more offsprings than parents, or else an exception will be raised + assert( _offspring.size() >= _parents.size() ); + + eoMergeReduce::operator()( _parents, _offspring ); + } + private : eoNoElitism no_elite; eoTruncate truncate; diff --git a/eo/src/eoPop.h b/eo/src/eoPop.h index 3ea53f466..9220e3c66 100644 --- a/eo/src/eoPop.h +++ b/eo/src/eoPop.h @@ -4,31 +4,41 @@ // eoPop.h // (c) GeNeura Team, 1998 /* - 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 of the License, or (at your option) any later version. + 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 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. + 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - Contact: todos@geneura.ugr.es, http://geneura.ugr.es - */ +Authors: + todos@geneura.ugr.es, http://geneura.ugr.es + jmerelo + gustavoromero + mac + maartenkeijzer + kuepper + okoenig + evomarc + Johann Dréo +*/ //----------------------------------------------------------------------------- -#ifndef _EOPOP_H -#define _EOPOP_H +#ifndef _EOPOP_H_ +#define _EOPOP_H_ #include #include #include // needed for GCC 3.2 #include +#include // EO includes #include // for eoInit @@ -54,18 +64,18 @@ template class eoPop: public std::vector, public eoObject, public eoPersistent { -public: + public: - using std::vector::size; - using std::vector::resize; - using std::vector::operator[]; - using std::vector::begin; - using std::vector::end; + using std::vector::size; + using std::vector::resize; + using std::vector::operator[]; + using std::vector::begin; + using std::vector::end; - typedef typename EOT::Fitness Fitness; + typedef typename EOT::Fitness Fitness; #if defined(__CUDACC__) - typedef typename std::vector::iterator iterator; - typedef typename std::vector::const_iterator const_iterator; + typedef typename std::vector::iterator iterator; + typedef typename std::vector::const_iterator const_iterator; #endif /** Default ctor. Creates empty pop @@ -74,266 +84,296 @@ public: /** Ctor for the initialization of chromosomes - @param _popSize total population size - @param _chromInit Initialization routine, produces EO's, needs to be an eoInit + @param _popSize total population size + @param _chromInit Initialization routine, produces EO's, needs to be an eoInit */ - eoPop( unsigned _popSize, eoInit& _chromInit ) - :std::vector() - { - resize(_popSize); - for ( unsigned i = 0; i < _popSize; i++ ) - { + eoPop( unsigned _popSize, eoInit& _chromInit ) + : std::vector() + { + resize(_popSize); + for ( unsigned i = 0; i < _popSize; i++ ) + { _chromInit(operator[](i)); - } - }; + } + } /** appends random guys at end of pop. - Can be used to initialize it pop is empty + Can be used to initialize it pop is empty - @param _newPopSize total population size - @param _chromInit Initialization routine, produces EO's, needs to be an eoInit + @param _newPopSize total population size + @param _chromInit Initialization routine, produces EO's, needs to be an eoInit */ - void append( unsigned _newPopSize, eoInit& _chromInit ) - { - unsigned oldSize = size(); - if (_newPopSize < oldSize) + void append( unsigned _newPopSize, eoInit& _chromInit ) { - throw std::runtime_error("New size smaller than old size in pop.append"); - return; + unsigned oldSize = size(); + if (_newPopSize < oldSize) + { + throw std::runtime_error("New size smaller than old size in pop.append"); + return; + } + if (_newPopSize == oldSize) + return; + resize(_newPopSize); // adjust the size + for ( unsigned i = oldSize; i < _newPopSize; i++ ) + { + _chromInit(operator[](i)); + } } - if (_newPopSize == oldSize) - return; - resize(_newPopSize); // adjust the size - for ( unsigned i = oldSize; i < _newPopSize; i++ ) + + + /** Ctor from an std::istream; reads the population from a stream, + each element should be in different lines + @param _is the stream + */ + eoPop( std::istream& _is ) :std::vector() { - _chromInit(operator[](i)); + readFrom( _is ); } - }; - /** Ctor from an std::istream; reads the population from a stream, - each element should be in different lines - @param _is the stream - */ - eoPop( std::istream& _is ) :std::vector() { - readFrom( _is ); - } - - /** Empty Dtor */ + /** Empty Dtor */ virtual ~eoPop() {} - /// helper struct for getting a pointer - struct Ref { const EOT* operator()(const EOT& eot) { return &eot;}}; - /// helper struct for comparing on pointers - struct Cmp { - bool operator()(const EOT* a, const EOT* b) const + /// helper struct for getting a pointer + struct Ref { const EOT* operator()(const EOT& eot) { return &eot;}}; + + /// helper struct for comparing on pointers + struct Cmp { + bool operator()(const EOT* a, const EOT* b) const { return b->operator<(*a); } - }; - /// helper struct for comparing (EA or PSO) - struct Cmp2 - { - bool operator()(const EOT & a,const EOT & b) const + }; + + /// helper struct for comparing (EA or PSO) + struct Cmp2 { + bool operator()(const EOT & a,const EOT & b) const + { return b.operator<(a); + } + }; + + + /** + sort the population. Use this member to sort in order + of descending Fitness, so the first individual is the best! + */ + void sort(void) + { + std::sort(begin(), end(), Cmp2()); } - }; + /** creates a std::vector pointing to the individuals in descending order */ + void sort(std::vector& result) const + { + result.resize(size()); - /** - sort the population. Use this member to sort in order - of descending Fitness, so the first individual is the best! - */ - void sort(void) - { - std::sort(begin(), end(), Cmp2()); - } + std::transform(begin(), end(), result.begin(), Ref()); - /** creates a std::vector pointing to the individuals in descending order */ - void sort(std::vector& result) const - { - result.resize(size()); + std::sort(result.begin(), result.end(), Cmp()); + } - std::transform(begin(), end(), result.begin(), Ref()); - std::sort(result.begin(), result.end(), Cmp()); - } + /** + shuffle the population. Use this member to put the population + in random order + */ + void shuffle(void) + { + UF_random_generator gen; + std::random_shuffle(begin(), end(), gen); + } - /** - shuffle the population. Use this member to put the population - in random order - */ - void shuffle(void) - { - UF_random_generator gen; - std::random_shuffle(begin(), end(), gen); - } - /** creates a std::vector pointing to the individuals in random order */ - void shuffle(std::vector& result) const - { - result.resize(size()); + /** creates a std::vector pointing to the individuals in random order */ + void shuffle(std::vector& result) const + { + result.resize(size()); - std::transform(begin(), end(), result.begin(), Ref()); + std::transform(begin(), end(), result.begin(), Ref()); - UF_random_generator gen; - std::random_shuffle(result.begin(), result.end(), gen); - } + UF_random_generator gen; + std::random_shuffle(result.begin(), result.end(), gen); + } - /** returns an iterator to the best individual DOES NOT MOVE ANYBODY */ + + /** returns an iterator to the best individual DOES NOT MOVE ANYBODY */ #if defined(__CUDACC__) - eoPop::iterator it_best_element() - { - eoPop:: iterator it = std::max_element(begin(), end()); + eoPop::iterator it_best_element() + { + eoPop:: iterator it = std::max_element(begin(), end()); #else - typename eoPop::iterator it_best_element() { - typename eoPop::iterator it = std::max_element(begin(), end()); + typename eoPop::iterator it_best_element() + { + assert( this->size() > 0 ); + typename eoPop::iterator it = std::max_element(begin(), end()); #endif - return it; - } + return it; + } - /** returns an iterator to the best individual DOES NOT MOVE ANYBODY */ - const EOT & best_element() const - { + + /** returns an iterator to the best individual DOES NOT MOVE ANYBODY */ + const EOT & best_element() const + { #if defined(__CUDACC__) - eoPop::const_iterator it = std::max_element(begin(), end()); + eoPop::const_iterator it = std::max_element(begin(), end()); #else - typename eoPop::const_iterator it = std::max_element(begin(), end()); + typename eoPop::const_iterator it = std::max_element(begin(), end()); #endif - return (*it); - } + return (*it); + } - /** returns a const reference to the worse individual DOES NOT MOVE ANYBODY */ - const EOT & worse_element() const - { + + /** returns a const reference to the worse individual DOES NOT MOVE ANYBODY */ + const EOT & worse_element() const + { #if defined(__CUDACC__) - eoPop::const_iterator it = std::min_element(begin(), end()); + eoPop::const_iterator it = std::min_element(begin(), end()); #else - typename eoPop::const_iterator it = std::min_element(begin(), end()); + assert( this->size() > 0 ); + typename eoPop::const_iterator it = std::min_element(begin(), end()); #endif - return (*it); - } + return (*it); + } - /** returns an iterator to the worse individual DOES NOT MOVE ANYBODY */ + + /** returns an iterator to the worse individual DOES NOT MOVE ANYBODY */ #if defined(__CUDACC__) - eoPop::iterator it_worse_element() - { - eoPop::iterator it = std::min_element(begin(), end()); + eoPop::iterator it_worse_element() + { + eoPop::iterator it = std::min_element(begin(), end()); #else - typename eoPop::iterator it_worse_element() - { - typename eoPop::iterator it = std::min_element(begin(), end()); + typename eoPop::iterator it_worse_element() + { + assert( this->size() > 0 ); + typename eoPop::iterator it = std::min_element(begin(), end()); #endif - return it; - } + return it; + } - /** - slightly faster algorithm than sort to find all individuals that are better - than the nth individual. INDIVIDUALS ARE MOVED AROUND in the pop. - */ + + /** + slightly faster algorithm than sort to find all individuals that are better + than the nth individual. INDIVIDUALS ARE MOVED AROUND in the pop. + */ #if defined(__CUDACC__) - eoPop::iterator nth_element(int nth) - { - eoPop::iterator it = begin() + nth; + eoPop::iterator nth_element(int nth) + { + eoPop::iterator it = begin() + nth; #else - typename eoPop::iterator nth_element(int nth) - { - typename eoPop::iterator it = begin() + nth; + typename eoPop::iterator nth_element(int nth) + { + assert( this->size() > 0 ); + typename eoPop::iterator it = begin() + nth; #endif - std::nth_element(begin(), it, end(), std::greater()); - return it; - } + std::nth_element(begin(), it, end(), std::greater()); + return it; + } - struct GetFitness { Fitness operator()(const EOT& _eo) const { return _eo.fitness(); } }; - /** returns the fitness of the nth element */ - Fitness nth_element_fitness(int which) const - { // probably not the fastest way to do this, but what the heck + struct GetFitness { Fitness operator()(const EOT& _eo) const { return _eo.fitness(); } }; - std::vector fitness(size()); - std::transform(begin(), end(), fitness.begin(), GetFitness()); - typename std::vector::iterator it = fitness.begin() + which; - std::nth_element(fitness.begin(), it, fitness.end(), std::greater()); - return *it; - } + /** returns the fitness of the nth element */ + Fitness nth_element_fitness(int which) const + { // probably not the fastest way to do this, but what the heck - /** const nth_element function, returns pointers to sorted individuals - * up the the nth - */ - void nth_element(int which, std::vector& result) const - { + std::vector fitness(size()); + std::transform(begin(), end(), fitness.begin(), GetFitness()); - result.resize(size()); - std::transform(begin(), end(), result.begin(), Ref()); + typename std::vector::iterator it = fitness.begin() + which; + std::nth_element(fitness.begin(), it, fitness.end(), std::greater()); + return *it; + } - typename std::vector::iterator it = result.begin() + which; - std::nth_element(result.begin(), it, result.end(), Cmp()); - } + /** const nth_element function, returns pointers to sorted individuals + * up the the nth + */ + void nth_element(int which, std::vector& result) const + { - /** does STL swap with other pop */ - void swap(eoPop& other) - { - std::swap(static_cast& >(*this), static_cast& >(other)); - } + assert( this->size() > 0 ); + result.resize(size()); + std::transform(begin(), end(), result.begin(), Ref()); - /** - * Prints sorted pop but does NOT modify it! - * - * @param _os A std::ostream. - */ - virtual void sortedPrintOn(std::ostream& _os) const - { - std::vector result; - sort(result); - _os << size() << '\n'; - for (unsigned i = 0; i < size(); ++i) - { - _os << *result[i] << std::endl; - } - } + typename std::vector::iterator it = result.begin() + which; - /** - * Write object. It's called printOn since it prints the object _on_ a stream. - * @param _os A std::ostream. - */ - virtual void printOn(std::ostream& _os) const - { - _os << size() << '\n'; - std::copy( begin(), end(), std::ostream_iterator( _os, "\n") ); - } + std::nth_element(result.begin(), it, result.end(), Cmp()); + } - /** @name Methods from eoObject */ - //@{ - /** - * Read object. The EOT class must have a ctor from a stream; - * @param _is A std::istream. - */ - virtual void readFrom(std::istream& _is) - { - size_t sz; - _is >> sz; - resize(sz); + /** does STL swap with other pop */ + void swap(eoPop& other) + { + std::swap(static_cast& >(*this), static_cast& >(other)); + } - for (size_t i = 0; i < sz; ++i) { - operator[](i).readFrom( _is ); - } - } - /** Inherited from eoObject. Returns the class name. - @see eoObject - */ - virtual std::string className() const {return "eoPop";}; - //@} + /** + * Prints sorted pop but does NOT modify it! + * + * @param _os A std::ostream. + */ + virtual void sortedPrintOn(std::ostream& _os) const + { + std::vector result; + sort(result); + _os << size() << '\n'; + for (unsigned i = 0; i < size(); ++i) + { + _os << *result[i] << std::endl; + } + } - virtual void invalidate() - { - for (unsigned i=0; ioperator[](i).invalidate(); - } -}; -#endif + /** + * Write object. It's called printOn since it prints the object _on_ a stream. + * @param _os A std::ostream. + */ + virtual void printOn(std::ostream& _os) const + { + _os << size() << '\n'; + std::copy( begin(), end(), std::ostream_iterator( _os, "\n") ); + } + + + /** @name Methods from eoObject */ + //@{ + /** + * Read object. The EOT class must have a ctor from a stream; + * @param _is A std::istream. + */ + virtual void readFrom(std::istream& _is) + { + size_t sz; + _is >> sz; + + resize(sz); + + for (size_t i = 0; i < sz; ++i) { + operator[](i).readFrom( _is ); + } + } + + + /** Inherited from eoObject. Returns the class name. + @see eoObject + */ + virtual std::string className() const {return "eoPop";}; + //@} + + + /** Invalidate the whole population + */ + virtual void invalidate() + { + for (unsigned i=0; ioperator[](i).invalidate(); + } + +}; // class eoPop + +#endif // _EOPOP_H_ + diff --git a/eo/src/eoProportionalCombinedOp.h b/eo/src/eoProportionalCombinedOp.h index 60c478903..823ac79c9 100644 --- a/eo/src/eoProportionalCombinedOp.h +++ b/eo/src/eoProportionalCombinedOp.h @@ -186,6 +186,7 @@ public: virtual std::string className() const { return "eoPropCombinedQuadOp"; } + /* FIXME remove in next release virtual void add(eoQuadOp & _op, const double _rate, bool _verbose) { #ifndef DEPRECATED_MESSAGES @@ -195,6 +196,7 @@ public: add(_op,_rate); } + */ // addition of a true operator virtual void add(eoQuadOp & _op, const double _rate) @@ -202,7 +204,7 @@ public: ops.push_back(&_op); rates.push_back(_rate); // compute the relative rates in percent - to warn the user! - printOn( eo::log << eo::logging ); + printOn( eo::log << eo::logging ); } // outputs the operators and percentages diff --git a/eo/src/eoScalarFitnessAssembled.h b/eo/src/eoScalarFitnessAssembled.h index 95168ec64..50e9038de 100644 --- a/eo/src/eoScalarFitnessAssembled.h +++ b/eo/src/eoScalarFitnessAssembled.h @@ -212,7 +212,7 @@ public: //! Print term values and descriptions void printAll(std::ostream& os) const { for (size_type i=0; i < size(); ++i ) - os << FitnessTraits::getDescription(i) << " = " << operator[](i) << " "; + os << FitnessTraits::getDescription(i) << " = " << this->operator[](i) << " "; } //! Comparison, using less by default diff --git a/eo/src/ga/make_continue_ga.cpp b/eo/src/ga/make_continue_ga.cpp index 1b25a0c85..fb4662c32 100644 --- a/eo/src/ga/make_continue_ga.cpp +++ b/eo/src/ga/make_continue_ga.cpp @@ -37,7 +37,7 @@ * * The corresponding ***INSTANCIATED DECLARATIONS*** are contained * in ga.h - * while the TEMPLATIZED code is define in make_contninue.h in the src/do dir + * while the TEMPLATIZED code is define in make_continue.h in the src/do dir * * Unlike most EO .h files, it does not (and should not) contain any code, * just declarations diff --git a/eo/src/ga/make_ga.h b/eo/src/ga/make_ga.h index ce594903f..206094881 100644 --- a/eo/src/ga/make_ga.h +++ b/eo/src/ga/make_ga.h @@ -57,8 +57,8 @@ */ // the genotypes -eoInit > & make_genotype(eoParser& _parser, eoState& _state, eoBit _eo); - eoInit > & make_genotype(eoParser& _parser, eoState& _state, eoBit _eo); +eoInit > & make_genotype(eoParser& _parser, eoState& _state, eoBit _eo, float _bias=0.5); + eoInit > & make_genotype(eoParser& _parser, eoState& _state, eoBit _eo, float _bias=0.5); // the operators eoGenOp >& make_op(eoParser& _parser, eoState& _state, eoInit >& _init); diff --git a/eo/src/ga/make_genotype_ga.cpp b/eo/src/ga/make_genotype_ga.cpp index 4f9e69ef1..3344a8d87 100644 --- a/eo/src/ga/make_genotype_ga.cpp +++ b/eo/src/ga/make_genotype_ga.cpp @@ -45,11 +45,11 @@ /// The following function merely call the templatized do_* functions above -eoInit > & make_genotype(eoParser& _parser, eoState& _state, eoBit _eo) +eoInit > & make_genotype(eoParser& _parser, eoState& _state, eoBit _eo, float _bias) { - return do_make_genotype(_parser, _state, _eo); + return do_make_genotype(_parser, _state, _eo, _bias); } -eoInit > & make_genotype(eoParser& _parser, eoState& _state, eoBit _eo) +eoInit > & make_genotype(eoParser& _parser, eoState& _state, eoBit _eo, float _bias) { - return do_make_genotype(_parser, _state, _eo); + return do_make_genotype(_parser, _state, _eo, _bias); } diff --git a/eo/src/ga/make_genotype_ga.h b/eo/src/ga/make_genotype_ga.h index ea1b20054..fad4f7563 100644 --- a/eo/src/ga/make_genotype_ga.h +++ b/eo/src/ga/make_genotype_ga.h @@ -60,7 +60,7 @@ * @ingroup Builders */ template -eoInit & do_make_genotype(eoParser& _parser, eoState& _state, EOT) +eoInit & do_make_genotype(eoParser& _parser, eoState& _state, EOT, float _bias=0.5) { // for bitstring, only thing needed is the size // but it might have been already read in the definition fo the performance @@ -68,7 +68,7 @@ eoInit & do_make_genotype(eoParser& _parser, eoState& _state, EOT) // Then we can built a bitstring random initializer // based on boolean_generator class (see utils/rnd_generator.h) - eoBooleanGenerator * gen = new eoBooleanGenerator; + eoBooleanGenerator * gen = new eoBooleanGenerator(_bias); _state.storeFunctor(gen); eoInitFixedLength* init = new eoInitFixedLength(theSize, *gen); // store in state diff --git a/eo/src/ga/make_op.h b/eo/src/ga/make_op.h index 045148eca..2035a4f85 100644 --- a/eo/src/ga/make_op.h +++ b/eo/src/ga/make_op.h @@ -156,11 +156,23 @@ eoGenOp & do_make_op(eoParser& _parser, eoState& _state, eoInit& _init if ( (bitFlipRateParam.value() < 0) ) throw std::runtime_error("Invalid bitFlipRate"); + // oneBitFlip eoValueParam & oneBitRateParam = _parser.createParam(0.01, "oneBitRate", "Relative rate for deterministic bit-flip mutation", 'd', "Variation Operators" ); // minimum check if ( (oneBitRateParam.value() < 0) ) throw std::runtime_error("Invalid oneBitRate"); + // kBitFlip + eoValueParam & kBitParam = _parser.createParam((unsigned)1, "kBit", "Number of bit for deterministic k bit-flip mutation", 0, "Variation Operators" ); + // minimum check + if ( ! kBitParam.value() ) + throw std::runtime_error("Invalid kBit"); + + eoValueParam & kBitRateParam = _parser.createParam(0.0, "kBitRate", "Relative rate for deterministic k bit-flip mutation", 0, "Variation Operators" ); + // minimum check + if ( (kBitRateParam.value() < 0) ) + throw std::runtime_error("Invalid kBitRate"); + // minimum check // bool bMut = true; // not used ? if (bitFlipRateParam.value()+oneBitRateParam.value()==0) @@ -184,6 +196,11 @@ eoGenOp & do_make_op(eoParser& _parser, eoState& _state, eoInit& _init _state.storeFunctor(ptMon); ptCombinedMonOp->add(*ptMon, oneBitRateParam.value()); + // mutate exactly k bit per individual + ptMon = new eoDetBitFlip(kBitParam.value()); + _state.storeFunctor(ptMon); + ptCombinedMonOp->add(*ptMon, kBitRateParam.value()); + _state.storeFunctor(ptCombinedMonOp); // now build the eoGenOp: diff --git a/eo/src/gp/eoParseTree.h b/eo/src/gp/eoParseTree.h index 11ec105ec..88737d919 100644 --- a/eo/src/gp/eoParseTree.h +++ b/eo/src/gp/eoParseTree.h @@ -94,7 +94,7 @@ public: while (size() > _size) { - back() = operator[](size()-2); + back() = this->operator[](size()-2); } } @@ -150,7 +150,7 @@ public: v[i] = node; } parse_tree tmp(v.begin(), v.end()); - swap(tmp); + this->swap(tmp); /* * old code which caused problems for paradisEO diff --git a/eo/src/utils/CMakeLists.txt b/eo/src/utils/CMakeLists.txt index 010c6d418..5224f6520 100644 --- a/eo/src/utils/CMakeLists.txt +++ b/eo/src/utils/CMakeLists.txt @@ -29,6 +29,7 @@ SET(EOUTILS_SOURCES pipecom.cpp eoLogger.cpp eoParallel.cpp + eoSignal.cpp ) ADD_LIBRARY(eoutils STATIC ${EOUTILS_SOURCES}) diff --git a/eo/src/utils/checkpointing b/eo/src/utils/checkpointing index 7e3c34a68..f7fd0e55b 100644 --- a/eo/src/utils/checkpointing +++ b/eo/src/utils/checkpointing @@ -36,6 +36,7 @@ #include #endif #include +#include #include #include #include diff --git a/eo/src/utils/eoOStreamMonitor.cpp b/eo/src/utils/eoOStreamMonitor.cpp index 3365301e9..6836f337e 100644 --- a/eo/src/utils/eoOStreamMonitor.cpp +++ b/eo/src/utils/eoOStreamMonitor.cpp @@ -37,6 +37,7 @@ eoMonitor& eoOStreamMonitor::operator()(void) } // if firstime // ok, now the real saving. write out + // FIXME deprecated, remove in next release //! @todo old verbose formatting, do we still need it? /* for (iterator it = vec.begin (); it != vec.end (); ++it) { diff --git a/eo/src/utils/eoOStreamMonitor.h b/eo/src/utils/eoOStreamMonitor.h index b941b05f2..982c954f9 100644 --- a/eo/src/utils/eoOStreamMonitor.h +++ b/eo/src/utils/eoOStreamMonitor.h @@ -44,14 +44,17 @@ Authors: class eoOStreamMonitor : public eoMonitor { public : - eoOStreamMonitor( std::ostream & _out, bool /*_verbose*/=true, std::string _delim = "\t", unsigned int _width=20, char _fill=' ' ) : + /* FIXME remove in next release + eoOStreamMonitor( std::ostream & _out, bool _verbose=true, std::string _delim = "\t", unsigned int _width=20, char _fill=' ' ) : out(_out), delim(_delim), width(_width), fill(_fill), firsttime(true) { #ifndef DEPRECATED_MESSAGES eo::log << eo::warnings << "WARNING: the use of the verbose parameter in eoOStreamMonitor constructor is deprecated and will be removed in the next release" << std::endl; #pragma message "WARNING: the use of the verbose parameter in eoOStreamMonitor constructor is deprecated and will be removed in the next release" #endif // !DEPRECATED_MESSAGES + } + */ eoOStreamMonitor( std::ostream & _out, std::string _delim = "\t", unsigned int _width=20, char _fill=' ' ) : out(_out), delim(_delim), width(_width), fill(_fill), firsttime(true) diff --git a/eo/src/utils/eoParallel.cpp b/eo/src/utils/eoParallel.cpp index d9d09c38b..f8e3c745c 100644 --- a/eo/src/utils/eoParallel.cpp +++ b/eo/src/utils/eoParallel.cpp @@ -25,7 +25,9 @@ Caner Candan */ +#ifdef _OPENMP #include +#endif #include "eoParallel.h" #include "eoLogger.h" diff --git a/eo/src/utils/eoParserLogger.h b/eo/src/utils/eoParserLogger.h deleted file mode 100644 index de6f06e6a..000000000 --- a/eo/src/utils/eoParserLogger.h +++ /dev/null @@ -1,36 +0,0 @@ -// -*- mode: c++; c-indent-level: 4; c++-member-init-indent: 8; comment-column: 35; -*- - -/* -(c) Thales group, 2010 - - 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; - version 2 of the License. - - 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - -Contact: http://eodev.sourceforge.net - -Authors: -Caner Candan - -*/ - -#ifndef EO_PARSER_LOGGER_H -#define EO_PARSER_LOGGER_H - -#include "eoParser.h" - -#warning "[eoParserLogger] is deprecated" - -typedef eoParser eoParserLogger; - -#endif // !EO_PARSER_LOGGER_H diff --git a/eo/src/utils/eoRNG.h b/eo/src/utils/eoRNG.h index 984e76271..78223c35a 100644 --- a/eo/src/utils/eoRNG.h +++ b/eo/src/utils/eoRNG.h @@ -150,7 +150,8 @@ public : initialize(2*s); } - /** Re-initializes the Random Number Generator + /* FIXME remove in next release + ** Re-initializes the Random Number Generator This is the traditional seeding procedure. This version is deprecated and only provided for compatibility with old code. In new projects you should @@ -159,11 +160,12 @@ public : @see reseed for details on usage of the seeding value. @version old version (deprecated) - */ + * void oldReseed(uint32_t s) { initialize(s); } + */ /** Random number from unifom distribution diff --git a/eo/src/utils/eoSignal.cpp b/eo/src/utils/eoSignal.cpp new file mode 100644 index 000000000..745d21bd3 --- /dev/null +++ b/eo/src/utils/eoSignal.cpp @@ -0,0 +1,36 @@ +// -*- mode: c++; c-indent-level: 4; c++-member-init-indent: 8; comment-column: 35; -*- + +/** + 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 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + + Contact: http://eodev.sourceforge.net + + Autors: todos@geneura.ugr.es, http://geneura.ugr.es + Marc.Schoenauer@polytechnique.fr + mak@dhi.dk + Caner.Candan@univ-angers.fr +*/ + +#include + +/** + * @addtogroup Continuators + * @{ + */ + +// --- Global variables - but don't know what else to do - MS --- +std::map< int, bool > signals_called; + +/** @} */ diff --git a/eo/src/utils/eoSignal.h b/eo/src/utils/eoSignal.h new file mode 100644 index 000000000..9a89cb196 --- /dev/null +++ b/eo/src/utils/eoSignal.h @@ -0,0 +1,106 @@ +// -*- mode: c++; c-indent-level: 4; c++-member-init-indent: 8; comment-column: 35; -*- + +/** + 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 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + + Contact: http://eodev.sourceforge.net + + Authors: todos@geneura.ugr.es, http://geneura.ugr.es + Marc.Schoenauer@polytechnique.fr + mak@dhi.dk + Caner.Candan@univ-angers.fr +*/ + +#ifndef _eoSignal_h +#define _eoSignal_h + +#include +#include +#include + +#include +#include + +/** + * @addtogroup Continuators + * @{ + */ + +extern std::map< int, bool > signals_called; + +/** eoSignal inherits from eoCheckPoint including signals handling (see signal(7)) + * + * @ingroup Utilities + */ +template +class eoSignal : public eoCheckPoint +{ +public : + + eoSignal( int sig = SIGINT ) : eoCheckPoint( _dummyContinue ), _sig( sig ) + { + ::signals_called[_sig] = false; + +#ifndef _WINDOWS +#ifdef SIGQUIT + ::signal( _sig, handler ); +#endif // !SIGQUIT +#endif // !_WINDOWS + } + + eoSignal( eoContinue& _cont, int sig = SIGINT ) : eoCheckPoint( _cont ), _sig( sig ) + { + ::signals_called[_sig] = false; + +#ifndef _WINDOWS +#ifdef SIGQUIT + ::signal( _sig, handler ); +#endif // !SIGQUIT +#endif // !_WINDOWS + } + + bool operator()( const eoPop& _pop ) + { + bool& called = ::signals_called[_sig]; + if ( called ) + { + eo::log << eo::logging << "Signal granted…" << std::endl ; + called = false; + return this->eoCheckPoint::operator()( _pop ); + } + return true; + } + + virtual std::string className(void) const { return "eoSignal"; } + + static void handler( int sig ) + { + ::signals_called[sig] = true; + eo::log << eo::logging << "Signal wished…" << std::endl ; + } + +private: + class DummyContinue : public eoContinue + { + public: + bool operator() ( const eoPop& ) { return true; } + } _dummyContinue; + + int _sig; +}; + +/** @} */ + +#endif // !_eoSignal_h diff --git a/eo/src/utils/eoState.cpp b/eo/src/utils/eoState.cpp index d9d06d99e..c6d385001 100644 --- a/eo/src/utils/eoState.cpp +++ b/eo/src/utils/eoState.cpp @@ -18,7 +18,7 @@ using namespace std; -void removeComment(string& str, string comment) +void eoState::removeComment(string& str, string comment) { string::size_type pos = str.find(comment); @@ -28,21 +28,23 @@ void removeComment(string& str, string comment) } } -bool is_section(const string& str, string& name) +bool eoState::is_section(const string& str, string& name) { - string::size_type pos = str.find("\\section{"); + string::size_type pos = str.find(_tag_section_so); if (pos == string::npos) return false; //else - string::size_type end = str.find("}"); + string::size_type end = str.find(_tag_section_sc); if (end == string::npos) return false; // else - name = str.substr(pos + 9, end-9); + // affect name, passed by reference + // Note: substr( start, count ) + name = str.substr( pos + _tag_section_so.size(), end - _tag_section_so.size() ); return true; } @@ -84,6 +86,7 @@ void eoState::load(const string& _filename) load(is); } +// FIXME implement parsing and loading of other formats void eoState::load(std::istream& is) { string str; @@ -158,16 +161,49 @@ void eoState::save(const string& filename) const save(os); } -void eoState::save(std::ostream& os) const -{ // saves in order of insertion - for (vector::const_iterator it = creationOrder.begin(); it != creationOrder.end(); ++it) - { - os << "\\section{" << (*it)->first << "}\n"; - (*it)->second->printOn(os); - os << '\n'; - } +//void eoState::save(std::ostream& os) const +//{ // saves in order of insertion +// for (vector::const_iterator it = creationOrder.begin(); it != creationOrder.end(); ++it) +// { +// os << "\\section{" << (*it)->first << "}\n"; +// (*it)->second->printOn(os); +// os << '\n'; +// } +//} + +void eoState::saveSection( std::ostream& os, vector::const_iterator it) const +{ + os << _tag_section_so << (*it)->first << _tag_section_sc; + + os << _tag_content_s; + (*it)->second->printOn(os); + os << _tag_content_e; + + os << _tag_section_e; } + +void eoState::save(std::ostream& os) const +{ + os << _tag_state_so << _tag_state_name << _tag_state_sc; + + // save the first section + assert( creationOrder.size() > 0 ); + // saves in order of insertion + vector::const_iterator it = creationOrder.begin(); + saveSection(os,it); + it++; + + while( it != creationOrder.end() ) { + // add a separator only before [1,n] elements + os << _tag_section_sep; + saveSection(os, it); + it++; + } + os << _tag_state_e; +} + + string eoState::createObjectName(eoObject* obj) { if (obj == 0) diff --git a/eo/src/utils/eoState.h b/eo/src/utils/eoState.h index 53c3a83d5..256dcd965 100644 --- a/eo/src/utils/eoState.h +++ b/eo/src/utils/eoState.h @@ -31,6 +31,7 @@ #include #include #include +#include #include @@ -56,10 +57,50 @@ class eoState : public eoFunctorStore { public : - eoState(void) {} + eoState(std::string name="") : + _tag_state_so(""), + _tag_state_name(name), + _tag_state_sc(""), + _tag_section_so("\\section{"), + _tag_section_sc("}\n"), + _tag_content_s(""), + _tag_content_e(""), + _tag_section_sep(""), + _tag_section_e("\n"), + _tag_state_e("") + {} ~eoState(void); + void formatLatex(std::string name) + { + _tag_state_so = ""; + _tag_state_name = name; + _tag_state_sc = ""; + _tag_section_so = "\\section{"; + _tag_section_sc = "}\n"; + _tag_content_s = ""; + _tag_content_e = ""; + _tag_section_sep = ""; + _tag_section_e = "\n"; + _tag_state_e = ""; + } + + void formatJSON(std::string name) + { + _tag_state_so = "{ \""; + _tag_state_name = name; + _tag_state_sc = "\":\n"; + _tag_section_so = "\t{ \""; + _tag_section_sc = "\":\n"; + _tag_content_s = "\""; + _tag_content_e = "\""; + _tag_section_sep = ",\n"; + _tag_section_e = "\t}\n"; + _tag_state_e = "}\n"; + } + + /** * Object registration function, note that it does not take ownership! */ @@ -131,6 +172,43 @@ private : eoState(const eoState&); eoState& operator=(const eoState&); + /* \@{ + * s=start, e=end + * o=open, c=close + * + * { "my_state": + * { + * "section_pop":"…", + * "section_rng":"…" + * } + * } + * + * // JSON LATEX (default) + */ + std::string _tag_state_so; // { " + std::string _tag_state_name; // my_state + std::string _tag_state_sc; // ": + + std::string _tag_section_so; // { " \\section{ + std::string _tag_section_sc; // ": }\n + + std::string _tag_content_s; // " + std::string _tag_content_e; // " + + std::string _tag_section_sep;// , + + std::string _tag_section_e; // } \n + + std::string _tag_state_e; // } + /** \@} */ + + void removeComment( std::string& str, std::string comment); + + bool is_section(const std::string& str, std::string& name); + +protected: + void saveSection( std::ostream& os, std::vector::const_iterator it) const; + }; /** @example t-eoStateAndParser.cpp */ diff --git a/eo/src/utils/eoStdoutMonitor.h b/eo/src/utils/eoStdoutMonitor.h index a1979b5d7..d886aed3a 100644 --- a/eo/src/utils/eoStdoutMonitor.h +++ b/eo/src/utils/eoStdoutMonitor.h @@ -43,11 +43,15 @@ Authors: class eoStdoutMonitor : public eoOStreamMonitor { public : + /* FIXME remove in next release eoStdoutMonitor(bool _verbose, std::string _delim = "\t", unsigned int _width=20, char _fill=' ' ) : eoOStreamMonitor( std::cout, _verbose, _delim, _width, _fill) { - eo::log << eo::warnings << "WARNING: the use of the verbose parameter in eoStdutMonitor constructor is deprecated and will be removed in the next release" << std::endl; +#ifndef DEPRECATED_MESSAGES + eo::log << eo::warnings << "WARNING: the use of the verbose parameter in eoStdoutMonitor constructor is deprecated and will be removed in the next release" << std::endl; +#endif // !DEPRECATED_MESSAGES } + */ eoStdoutMonitor(std::string _delim = "\t", unsigned int _width=20, char _fill=' ' ) : eoOStreamMonitor( std::cout, _delim, _width, _fill) diff --git a/eo/test/CMakeLists.txt b/eo/test/CMakeLists.txt index 4e68b02ad..c4fcc8db5 100644 --- a/eo/test/CMakeLists.txt +++ b/eo/test/CMakeLists.txt @@ -66,7 +66,7 @@ SET (TEST_LIST t-eoLogger t-eoIQRStat t-eoParallel - t-openmp + #t-openmp # does not work anymore since functions used in this test were removed from EO #t-eoDualFitness t-eoParser ) diff --git a/eo/test/t-MGE-control.cpp b/eo/test/t-MGE-control.cpp index 240dd3688..d2d4d224d 100644 --- a/eo/test/t-MGE-control.cpp +++ b/eo/test/t-MGE-control.cpp @@ -69,7 +69,8 @@ int main() // Terminators eoGenContinue continuator1(10); eoFitContinue continuator2(CHROM_SIZE); - eoCombinedContinue continuator(continuator1, continuator2); + eoCombinedContinue continuator(continuator1); + continuator.add( continuator2 ); eoCheckPoint checkpoint(continuator); eoStdoutMonitor monitor; checkpoint.add(monitor); diff --git a/eo/test/t-MGE.cpp b/eo/test/t-MGE.cpp index a122b5e70..275847e18 100644 --- a/eo/test/t-MGE.cpp +++ b/eo/test/t-MGE.cpp @@ -73,7 +73,8 @@ int main() // Terminators eoGenContinue continuator1(10); eoFitContinue continuator2(CHROM_SIZE); - eoCombinedContinue continuator(continuator1, continuator2); + eoCombinedContinue continuator(continuator1); + continuator.add( continuator2); eoCheckPoint checkpoint(continuator); eoStdoutMonitor monitor; checkpoint.add(monitor); diff --git a/eo/test/t-MGE1bit.cpp b/eo/test/t-MGE1bit.cpp index 842f5cd77..6ef1c874c 100644 --- a/eo/test/t-MGE1bit.cpp +++ b/eo/test/t-MGE1bit.cpp @@ -72,7 +72,8 @@ int main() // Terminators eoGenContinue continuator1(10); eoFitContinue continuator2(CHROM_SIZE); - eoCombinedContinue continuator(continuator1, continuator2); + eoCombinedContinue continuator(continuator1); + continuator.add(continuator2); eoCheckPoint checkpoint(continuator); eoStdoutMonitor monitor; checkpoint.add(monitor); diff --git a/eo/test/t-eobin.cpp b/eo/test/t-eobin.cpp index d857dd822..2a36d0ee1 100644 --- a/eo/test/t-eobin.cpp +++ b/eo/test/t-eobin.cpp @@ -139,7 +139,8 @@ void main_function() eoGenContinue continuator1(50); eoFitContinue continuator2(65535.f); - eoCombinedContinue continuator(continuator1, continuator2); + eoCombinedContinue continuator(continuator1); + continuator.add( continuator2); eoCheckPoint checkpoint(continuator); diff --git a/eo/test/t-openmp.cpp b/eo/test/t-openmp.cpp index a1d680876..d2f4cf3b5 100644 --- a/eo/test/t-openmp.cpp +++ b/eo/test/t-openmp.cpp @@ -39,6 +39,8 @@ Caner Candan #include +#include + #include "real_value.h" //-----------------------------------------------------------------------------