diff --git a/eo/ForRelease b/ForRelease similarity index 97% rename from eo/ForRelease rename to ForRelease index 290cfcb2..870f6cb8 100644 --- a/eo/ForRelease +++ b/ForRelease @@ -5,8 +5,8 @@ following steps: - Set version number in eo-conf.cmake - Check/update NEWS file, set release date and version in NEWS. - use the "archive_current.sh" script to create the source archive -- Build the packages - Put source archive and packages files at SourceForge +- Update the documentation on the website - Post news on SourceForge project-page - Send announcement to mailing lists - Bump version number to next "x.y.z-edge" in eo-conf.cmake diff --git a/edo/CMakeLists.txt b/edo/CMakeLists.txt index 10b1fbe2..3cb182b3 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,8 +124,8 @@ SET(SAMPLE_SRCS) ###################################################################################### ADD_SUBDIRECTORY(src) -#ADD_SUBDIRECTORY(application) -ADD_SUBDIRECTORY(test) +ADD_SUBDIRECTORY(application) +#ADD_SUBDIRECTORY(test) ADD_SUBDIRECTORY(doc) ###################################################################################### diff --git a/edo/NEWS b/edo/NEWS new file mode 100644 index 00000000..9c3ee2d2 --- /dev/null +++ b/edo/NEWS @@ -0,0 +1,10 @@ +* current release: + +* release 1.3.0 (2011-07-24) + - alternative implementation of the multi-normal operators using the Eigen3 library + +* release 0.0 (2011-09-15) + - basic design for estimation of distribution algorithms and, more generally for randomized search heuristics + - continuous EDA example + - EDA using multi-normal distribution, implementation using the boost::ublas library + diff --git a/edo/README b/edo/README index 5b814b15..4217a844 100644 --- a/edo/README +++ b/edo/README @@ -33,11 +33,11 @@ In the edo/build/ directory: (Unix) > ctest Windows users, please refer to this tutorial: http://paradiseo.gforge.inria.fr/index.php?n=Paradiseo.VisualCTutorial -In the directory "application", there are several directory such as eda_sa which instantiate EDA-SA solver. +In the directory "application", there are several directory such as eda which instantiate EDA solver. -(Unix) After compilation you can run the binary "build/eda_sa" and see results. Parameters can be modified from command line. +(Unix) After compilation you can run the binary "build/eda" and see results. Parameters can be modified from command line. -(Windows) Add argument "eda_sa.param" and execute the corresponding algorithms. +(Windows) Add argument "eda.param" and execute the corresponding algorithms. Windows users, please refer to this tutorial: http://paradiseo.gforge.inria.fr/index.php?n=Paradiseo.VisualCTutorial diff --git a/edo/application/CMakeLists.txt b/edo/application/CMakeLists.txt index eea3dcb9..c03fa57d 100644 --- a/edo/application/CMakeLists.txt +++ b/edo/application/CMakeLists.txt @@ -7,8 +7,8 @@ INCLUDE_DIRECTORIES( ) ADD_SUBDIRECTORY(common) -ADD_SUBDIRECTORY(eda_sa) +#ADD_SUBDIRECTORY(eda_sa) ADD_SUBDIRECTORY(eda) -#ADD_SUBDIRECTORY(sa) +ADD_SUBDIRECTORY(cmaes) ###################################################################################### diff --git a/edo/application/cmaes/CMakeLists.txt b/edo/application/cmaes/CMakeLists.txt new file mode 100644 index 00000000..ade261ac --- /dev/null +++ b/edo/application/cmaes/CMakeLists.txt @@ -0,0 +1,33 @@ +PROJECT(cmaes) + + +#find_package(Eigen3 REQUIRED) +#include_directories(EIGEN3_INCLUDE_DIR) +INCLUDE_DIRECTORIES( ${EIGEN3_INCLUDE_DIR} ) +MESSAGE( "MESSAGE:" ${EIGEN3_INCLUDE_DIR} ) + +#FIND_PACKAGE(Boost 1.33.0) +INCLUDE_DIRECTORIES(${Boost_INCLUDE_DIRS}) +LINK_DIRECTORIES(${Boost_LIBRARY_DIRS}) + +INCLUDE_DIRECTORIES(${CMAKE_CURRENT_SOURCE_DIR}) + +SET(RESOURCES + ${PROJECT_NAME}.param + ) + +FOREACH(file ${RESOURCES}) + EXECUTE_PROCESS( + COMMAND ${CMAKE_COMMAND} -E copy_if_different + ${CMAKE_CURRENT_SOURCE_DIR}/${file} + ${EDO_BINARY_DIR}/${file} + ) +ENDFOREACH(file) + +#FILE(GLOB SOURCES *.cpp) + +SET(EXECUTABLE_OUTPUT_PATH ${EDO_BINARY_DIR}) + +ADD_EXECUTABLE(${PROJECT_NAME} main.cpp) +TARGET_LINK_LIBRARIES(${PROJECT_NAME} edo edoutils ${EO_LIBRARIES} ${Boost_LIBRARIES}) + diff --git a/edo/application/cmaes/main.cpp b/edo/application/cmaes/main.cpp new file mode 100644 index 00000000..97d1d111 --- /dev/null +++ b/edo/application/cmaes/main.cpp @@ -0,0 +1,160 @@ +/* +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 RealVec; +typedef edoNormalAdaptive< RealVec > 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 + + unsigned long max_eval = parser.getORcreateParam((unsigned long)0, "maxEval", "Maximum number of evaluations (0 = none)", 'E', "Stopping criterion").value(); // E + + unsigned int dim = parser.createParam((unsigned int)10, "dimension-size", "Dimension size", 'd', section).value(); // d + + + double mu = dim / 2; + + + edoNormalAdaptive distribution(dim); + + eoSelect< RealVec >* selector = new eoRankMuSelect< RealVec >( mu ); + state.storeFunctor(selector); + + edoEstimator< Distrib >* estimator = new edoEstimatorNormalAdaptive( distribution ); + state.storeFunctor(estimator); + + eoEvalFunc< RealVec >* plainEval = new Rosenbrock< RealVec >(); + state.storeFunctor(plainEval); + + eoEvalFuncCounterBounder< RealVec > eval(*plainEval, max_eval); + + eoRndGenerator< double >* gen = new eoUniformGenerator< double >(-5, 5); + state.storeFunctor(gen); + + + eoInitFixedLength< RealVec >* init = new eoInitFixedLength< RealVec >( dim, *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< RealVec >& 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< RealVec >* bounder = + new edoBounderRng< RealVec >( RealVec(dim, -5), RealVec(dim, 5), *gen); // FIXME do not use hard-coded bounds + state.storeFunctor(bounder); + + // Prepare sampler class with a specific distribution + edoSampler< Distrib >* sampler = new edoSamplerNormalAdaptive< RealVec >( *bounder ); + state.storeFunctor(sampler); + + // stopping criteria + // ... and creates the parameter letters: C E g G s T + eoContinue< RealVec >& eo_continue = do_make_continue(parser, state, eval); + + // population output + eoCheckPoint< RealVec >& 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< RealVec >* replacor = new eoEPReplacement< RealVec >(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); + + eoPopLoopEval popEval( eval ); + + // EDA algorithm configuration + edoAlgo< Distrib >* algo = new edoAlgoAdaptive< Distrib > + (distribution, popEval, *selector, *estimator, *sampler, *replacor, + pop_continue, *distribution_continue ); + + + // Beginning of the algorithm call + try { + do_run(*algo, pop); + + } catch (eoEvalFuncCounterBounderException& e) { + eo::log << eo::warnings << "warning: " << e.what() << std::endl; + + } catch (std::exception& e) { + eo::log << eo::errors << "error: " << e.what() << std::endl; + exit(EXIT_FAILURE); + } + return 0; +} diff --git a/edo/application/eda/main.cpp b/edo/application/eda/main.cpp index 250e6bf1..6e024545 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 @@ -161,10 +161,9 @@ int main(int ac, char** av) eoPopLoopEval popEval( eval ); // EDA algorithm configuration - edoAlgo< Distrib >* algo = new edoEDA< Distrib > - (*selector, *estimator, *sampler, - pop_continue, *distribution_continue, - popEval, *replacor); + edoAlgo< Distrib >* algo = new edoAlgoStateless< Distrib > + (popEval, *selector, *estimator, *sampler, *replacor, + pop_continue, *distribution_continue ); // Beginning of the algorithm call try { diff --git a/edo/build_gcc_linux_debug b/edo/build_gcc_linux_debug index 144a5298..ea754f9b 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_EIGEN=1 .. make cd .. diff --git a/edo/build_gcc_linux_eigen_debug b/edo/build_gcc_linux_eigen_debug new file mode 100755 index 00000000..ea754f9b --- /dev/null +++ b/edo/build_gcc_linux_eigen_debug @@ -0,0 +1,7 @@ +#!/usr/bin/env sh + +mkdir -p debug +cd debug +cmake -DCMAKE_BUILD_TYPE=Debug -DWITH_EIGEN=1 .. +make +cd .. diff --git a/edo/build_gcc_linux_release b/edo/build_gcc_linux_release index fb220d04..a1a0f53b 100755 --- a/edo/build_gcc_linux_release +++ b/edo/build_gcc_linux_release @@ -2,6 +2,8 @@ mkdir -p release cd release -cmake .. +cmake -DWITH_EIGEN=1 .. +#cmake -DWITH_BOOST=1 .. + make cd .. diff --git a/edo/doc/doxyfile.cmake b/edo/doc/doxyfile.cmake index 1d610acc..fd565726 100644 --- a/edo/doc/doxyfile.cmake +++ b/edo/doc/doxyfile.cmake @@ -346,7 +346,7 @@ EXTRACT_ANON_NSPACES = NO # various overviews, but no documentation section is generated. # This option has no effect if EXTRACT_ALL is enabled. -HIDE_UNDOC_MEMBERS = YES +HIDE_UNDOC_MEMBERS = NO # If the HIDE_UNDOC_CLASSES tag is set to YES, Doxygen will hide all # undocumented classes that are normally visible in the class hierarchy. @@ -771,7 +771,7 @@ COLS_IN_ALPHA_INDEX = 3 # The IGNORE_PREFIX tag can be used to specify one or more prefixes that # should be ignored while generating the index headers. -IGNORE_PREFIX = moeo +IGNORE_PREFIX = edo #--------------------------------------------------------------------------- # configuration options related to the HTML output @@ -1273,13 +1273,13 @@ ENABLE_PREPROCESSING = YES # compilation will be performed. Macro expansion can be done in a controlled # way by setting EXPAND_ONLY_PREDEF to YES. -MACRO_EXPANSION = NO +MACRO_EXPANSION = YES # If the EXPAND_ONLY_PREDEF and MACRO_EXPANSION tags are both set to YES # then the macro expansion is limited to the macros specified with the # PREDEFINED and EXPAND_AS_DEFINED tags. -EXPAND_ONLY_PREDEF = NO +EXPAND_ONLY_PREDEF = YES # If the SEARCH_INCLUDES tag is set to YES (the default) the includes files # in the INCLUDE_PATH (see below) will be search if a #include is found. @@ -1307,14 +1307,14 @@ INCLUDE_FILE_PATTERNS = # undefined via #undef or recursively expanded use the := operator # instead of the = operator. -PREDEFINED = +PREDEFINED = WITH_EIGEN # If the MACRO_EXPANSION and EXPAND_ONLY_PREDEF tags are set to YES then # this tag can be used to specify a list of macro names that should be expanded. # The macro definition that is found in the sources will be used. # Use the PREDEFINED tag if you want to use a different macro definition. -EXPAND_AS_DEFINED = +EXPAND_AS_DEFINED = # If the SKIP_FUNCTION_MACROS tag is set to YES (the default) then # doxygen's preprocessor will remove all function-like macros that are alone diff --git a/edo/doc/edo_design.svg b/edo/doc/edo_design.svg new file mode 100644 index 00000000..07bfecb3 --- /dev/null +++ b/edo/doc/edo_design.svg @@ -0,0 +1,2689 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Evaluation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Selection + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Stop. criteria? + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Replacement + + Best solution + Parents + Genitors + Offsprings + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Initialization + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Estimator + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Sampler + + + Distrib + + + diff --git a/edo/doc/edo_distrib.svg b/edo/doc/edo_distrib.svg new file mode 100644 index 00000000..24b9a21f --- /dev/null +++ b/edo/doc/edo_distrib.svg @@ -0,0 +1,2885 @@ + + + + + EDO distribution coupling + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + EDO distribution coupling + + + Johann Dreo + + + 2012-07-19 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Modifier + + + + + + + population + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Estimator + + + + + + + + Distrib + + population + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Sampler + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Repairer + + + diff --git a/edo/doc/index.h b/edo/doc/index.h index e69de29b..76fc8a71 100644 --- a/edo/doc/index.h +++ b/edo/doc/index.h @@ -0,0 +1,39 @@ +/** @mainpage Welcome to Evolving Distribution Objects + +@section shortcuts In one word + +%EDO is an extension of %EO oriented toward Estimation-of-Distribution-like +Algorithms. + +You can search for advanced features by browsing the modules page. + +@section intro Introduction + +%EDO is an extension of %EO, that facilitate the design and implementation of +stochastic search metaheuristics. It is based on the assumption that those +algorithms are updating a probability distribution, that is used to generate +a sample (a population, in %EO) of solutions (individuals, in %EO). + +Basically, EDO decompose the variation operators of %EO in a set of +sub-operators that are binded by a distribution. Thus, most of the +representation-independent operators of %EO can be used in %EDO algorithms. + +Apart from choosing which distribution he want to use as a model, the user is +not supposed to directly manipulate it. Using the same approach than within %EO, +the user has just to indicate what he want to use, without having to bother how +he want to use it. + +On the designer side, it is still possible to implement specific operators +without having to change other ones. + + + +The two main operators are the Estimators, that builds a given +distribution according to a population and the Samplers that builds a +population according to a distribution. There is also Modifiers that +are here to change arbitrarily the parameters of a distribution, if necessary. + + + +*/ diff --git a/edo/install.cmake-dist b/edo/install.cmake-dist index b4f53211..35cc0617 100644 --- a/edo/install.cmake-dist +++ b/edo/install.cmake-dist @@ -2,19 +2,9 @@ # directory we need to build project SET(EO_DIR "<>" CACHE PATH "EO directory" FORCE) -SET(MO_DIR "<>" CACHE PATH "MO directory" FORCE) # automagically set parameters, do not edit SET(EO_INCLUDE_DIRS "${EO_DIR}/src" CACHE PATH "EO include directory" FORCE) SET(EO_LIBRARY_DIRS "${EO_DIR}/release/lib" CACHE PATH "EO library directory" FORCE) SET(EO_LIBRARIES eoutils eo es ga cma gcov) # do not use quotes around this list or it will fail - -SET(MO_INCLUDE_DIRS "${MO_DIR}/src" CACHE PATH "MO include directory" FORCE) -SET(MO_LIBRARY_DIRS "${MO_DIR}/release/lib" CACHE PATH "MO library directory" FORCE) -#SET(MO_LIBRARIES "mo") # no library is generated when building MO - -# ... or rather use pkg-config (dont forget to comment the code above) - -#PKG_CHECK_MODULES(EO eo REQUIRED) -#PKG_CHECK_MODULES(MO mo REQUIRED) diff --git a/edo/src/edo b/edo/src/edo index c03acd35..0da9ed9d 100644 --- a/edo/src/edo +++ b/edo/src/edo @@ -29,18 +29,22 @@ Authors: #define _edo_ #include "edoAlgo.h" -#include "edoEDASA.h" -#include "edoEDA.h" +//#include "edoEDASA.h" +#include "edoAlgoAdaptive.h" +#include "edoAlgoStateless.h" #include "edoDistrib.h" #include "edoUniform.h" #include "edoNormalMono.h" #include "edoNormalMulti.h" +#include "edoNormalAdaptive.h" #include "edoEstimator.h" #include "edoEstimatorUniform.h" #include "edoEstimatorNormalMono.h" #include "edoEstimatorNormalMulti.h" +#include "edoEstimatorAdaptive.h" +#include "edoEstimatorNormalAdaptive.h" #include "edoModifier.h" #include "edoModifierDispersion.h" @@ -53,6 +57,7 @@ Authors: #include "edoSamplerUniform.h" #include "edoSamplerNormalMono.h" #include "edoSamplerNormalMulti.h" +#include "edoSamplerNormalAdaptive.h" #include "edoVectorBounds.h" diff --git a/edo/src/edoAlgo.h b/edo/src/edoAlgo.h index b91a5c2a..b420f307 100644 --- a/edo/src/edoAlgo.h +++ b/edo/src/edoAlgo.h @@ -31,16 +31,29 @@ Authors: #include -/** An EDO algorithm difffers from a canonical EO algorithm because it is +/** + @defgroup Algorithms Algorithms + + In EDO, as in EO, an algorithm is a functor that takes one or several + solutions to an optimization problem as arguments, and iteratively modify + them with the help of operators.It differs from a canonical EO algorithm + because it is templatized on a edoDistrib rather than just an EOT. + + @see eoAlgo +*/ + +/** An EDO algorithm differs from a canonical EO algorithm because it is * templatized on a Distribution rather than just an EOT. * * Derivating from an eoAlgo, it should define an operator()( EOT sol ) + * + * @ingroup Algorithms */ template < typename D > class edoAlgo : public eoAlgo< typename D::EOType > { //! Alias for the type - typedef typename D::EOType EOT; + typedef typename D::EOType EOType; // virtual R operator()(A1) = 0; (defined in eoUF) diff --git a/edo/src/edoEDA.h b/edo/src/edoAlgoAdaptive.h similarity index 58% rename from edo/src/edoEDA.h rename to edo/src/edoAlgoAdaptive.h index f94e828f..5ee0f359 100644 --- a/edo/src/edoEDA.h +++ b/edo/src/edoAlgoAdaptive.h @@ -22,14 +22,13 @@ Copyright (C) 2010 Thales group /* Authors: Johann Dréo - Caner Candan + Pierre Savéant */ -#ifndef _edoEDA_h -#define _edoEDA_h +#ifndef _edoAlgoAdaptive_h +#define _edoAlgoAdaptive_h #include -#include #include @@ -39,28 +38,39 @@ Authors: #include "edoSampler.h" #include "edoContinue.h" -//! edoEDA< D > - +/** A generic stochastic search template for algorithms that need a distribution parameter. + * + * An adaptive algorithm will directly updates a distribution, it must thus be instanciated + * with an edoDistrib at hand. Thus, this distribution object should be instanciated appart. + * The reference to this distribution is generally also needed by at least one of the + * algorithm's operator, generally for algorithms that shares the same algorithms across + * operators and/or iterations. + * + * If you no operator needs to update the distribution, then it is simpler to use an + * edoAlgoStateless . + * + * @ingroup Algorithms + */ template < typename D > -class edoEDA : public edoAlgo< D > +class edoAlgoAdaptive : public edoAlgo< D > { public: //! Alias for the type EOT - typedef typename D::EOType EOT; + typedef typename D::EOType EOType; //! Alias for the atom type - typedef typename EOT::AtomType AtomType; + typedef typename EOType::AtomType AtomType; //! Alias for the fitness - typedef typename EOT::Fitness Fitness; + typedef typename EOType::Fitness Fitness; public: - //! edoEDA constructor /*! Takes algo operators, all are mandatory - \param evaluation Evaluate a population + \param distrib A distribution to use, if you want to update this parameter (e.gMA-ES) instead of replacing it (e.g. an EDA) + \param evaluator Evaluate a population \param selector Selection of the best candidate solutions in the population \param estimator Estimation of the distribution parameters \param sampler Generate feasible solutions using the distribution @@ -68,15 +78,17 @@ public: \param pop_continuator Stopping criterion based on the population features \param distribution_continuator Stopping criterion based on the distribution features */ - edoEDA ( - eoPopEvalFunc < EOT > & evaluator, - eoSelect< EOT > & selector, + edoAlgoAdaptive( + D & distrib, + eoPopEvalFunc < EOType > & evaluator, + eoSelect< EOType > & selector, edoEstimator< D > & estimator, edoSampler< D > & sampler, - eoReplacement< EOT > & replacor, - eoContinue< EOT > & pop_continuator, + eoReplacement< EOType > & replacor, + eoContinue< EOType > & pop_continuator, edoContinue< D > & distribution_continuator ) : + _distrib(distrib), _evaluator(evaluator), _selector(selector), _estimator(estimator), @@ -87,25 +99,29 @@ public: _distribution_continuator(distribution_continuator) {} - //! edoEDA constructor without an edoContinue + + //! constructor without an edoContinue /*! Takes algo operators, all are mandatory - \param evaluation Evaluate a population + \param distrib A distribution to use, if you want to update this parameter (e.gMA-ES) instead of replacing it (e.g. an EDA) + \param evaluator Evaluate a population \param selector Selection of the best candidate solutions in the population \param estimator Estimation of the distribution parameters \param sampler Generate feasible solutions using the distribution \param replacor Replace old solutions by new ones \param pop_continuator Stopping criterion based on the population features */ - edoEDA ( - eoPopEvalFunc < EOT > & evaluator, - eoSelect< EOT > & selector, + edoAlgoAdaptive ( + D & distrib, + eoPopEvalFunc < EOType > & evaluator, + eoSelect< EOType > & selector, edoEstimator< D > & estimator, edoSampler< D > & sampler, - eoReplacement< EOT > & replacor, - eoContinue< EOT > & pop_continuator + eoReplacement< EOType > & replacor, + eoContinue< EOType > & pop_continuator ) : + _distrib( distrib ), _evaluator(evaluator), _selector(selector), _estimator(estimator), @@ -116,43 +132,40 @@ public: _distribution_continuator( _dummy_continue ) {} - - /** A basic EDA algorithm that iterates over: - * selection, estimation, sampling, bounding, evaluation, replacement + /** Call the algorithm * * \param pop the population of candidate solutions * \return void */ - void operator ()(eoPop< EOT > & pop) + void operator ()(eoPop< EOType > & pop) { assert(pop.size() > 0); - eoPop< EOT > current_pop; - eoPop< EOT > selected_pop; + eoPop< EOType > current_pop; + eoPop< EOType > selected_pop; - // FIXME one must instanciate a first distrib here because there is no empty constructor, see if it is possible to instanciate Distributions without parameters - D distrib = _estimator(pop); + // update the extern distribution passed to the estimator (cf. CMA-ES) + // OR replace the dummy distribution for estimators that do not need extern distributions (cf. EDA) + _distrib = _estimator(pop); // Evaluating a first time the candidate solutions // The first pop is not supposed to be evaluated (@see eoPopLoopEval). - _evaluator( current_pop, pop ); + // _evaluator( current_pop, pop ); do { // (1) Selection of the best points in the population - //selected_pop.clear(); // FIXME is it necessary to clear? _selector(pop, selected_pop); assert( selected_pop.size() > 0 ); - // TODO: utiliser selected_pop ou pop ??? // (2) Estimation of the distribution parameters - distrib = _estimator(selected_pop); + _distrib = _estimator(selected_pop); // (3) sampling // The sampler produces feasible solutions (@see edoSampler that // encapsulate an edoBounder) current_pop.clear(); for( unsigned int i = 0; i < pop.size(); ++i ) { - current_pop.push_back( _sampler(distrib) ); + current_pop.push_back( _sampler(_distrib) ); } // (4) Evaluate new solutions @@ -161,35 +174,40 @@ public: // (5) Replace old solutions by new ones _replacor(pop, current_pop); // e.g. copy current_pop in pop - } while( _distribution_continuator( distrib ) && _pop_continuator( pop ) ); + } while( _distribution_continuator( _distrib ) && _pop_continuator( pop ) ); } // operator() -private: + +protected: + + //! The distribution that you want to update + D & _distrib; //! A full evaluation function. - eoPopEvalFunc < EOT > & _evaluator; + eoPopEvalFunc & _evaluator; - //! A EOT selector - eoSelect < EOT > & _selector; + //! A EOType selector + eoSelect & _selector; - //! A EOT estimator. It is going to estimate distribution parameters. - edoEstimator< D > & _estimator; + //! A EOType estimator. It is going to estimate distribution parameters. + edoEstimator & _estimator; //! A D sampler - edoSampler< D > & _sampler; + edoSampler & _sampler; - //! A EOT replacor - eoReplacement < EOT > & _replacor; + //! A EOType replacor + eoReplacement & _replacor; - //! A EOT population continuator - eoContinue < EOT > & _pop_continuator; + //! A EOType population continuator + eoContinue & _pop_continuator; //! A D continuator that always return true edoDummyContinue _dummy_continue; //! A D continuator - edoContinue < D > & _distribution_continuator; + edoContinue & _distribution_continuator; }; -#endif // !_edoEDA_h +#endif // !_edoAlgoAdaptive_h + diff --git a/edo/src/edoAlgoStateless.h b/edo/src/edoAlgoStateless.h new file mode 100644 index 00000000..a325ff24 --- /dev/null +++ b/edo/src/edoAlgoStateless.h @@ -0,0 +1,105 @@ +/* +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 + Pierre Savéant +*/ + +#ifndef _edoAlgoStateless_h +#define _edoAlgoStateless_h + +#include "edoAlgoAdaptive.h" + +/** A generic stochastic search template for algorithms that need a distribution parameter but replace it rather than update it + * + * This use a default dummy distribution, for algorithms willing to replace it instead of updating + * Thus we can instanciate _distrib on this and replace it at the first iteration with an estimator. + * This is why an edoDistrib must have an empty constructor. + * + * @ingroup Algorithms + */ +template < typename D > +class edoAlgoStateless : public edoAlgoAdaptive< D > +{ +public: + //! Alias for the type EOT + typedef typename D::EOType EOType; + + //! Alias for the atom type + typedef typename EOType::AtomType AtomType; + + //! Alias for the fitness + typedef typename EOType::Fitness Fitness; + +public: + + /** Full constructor + \param evaluator Evaluate a population + \param selector Selection of the best candidate solutions in the population + \param estimator Estimation of the distribution parameters + \param sampler Generate feasible solutions using the distribution + \param replacor Replace old solutions by new ones + \param pop_continuator Stopping criterion based on the population features + \param distribution_continuator Stopping criterion based on the distribution features + */ + edoAlgoStateless( + eoPopEvalFunc < EOType > & evaluator, + eoSelect< EOType > & selector, + edoEstimator< D > & estimator, + edoSampler< D > & sampler, + eoReplacement< EOType > & replacor, + eoContinue< EOType > & pop_continuator, + edoContinue< D > & distribution_continuator + ) : + edoAlgoAdaptive( *(new D), evaluator, selector, estimator, sampler, replacor, pop_continuator, distribution_continuator) + {} + + /** Constructor without an edoContinue + + \param evaluator Evaluate a population + \param selector Selection of the best candidate solutions in the population + \param estimator Estimation of the distribution parameters + \param sampler Generate feasible solutions using the distribution + \param replacor Replace old solutions by new ones + \param pop_continuator Stopping criterion based on the population features + */ + edoAlgoStateless ( + eoPopEvalFunc < EOType > & evaluator, + eoSelect< EOType > & selector, + edoEstimator< D > & estimator, + edoSampler< D > & sampler, + eoReplacement< EOType > & replacor, + eoContinue< EOType > & pop_continuator + ) : + edoAlgoAdaptive( *(new D), evaluator, selector, estimator, sampler, replacor, pop_continuator) + {} + + ~edoAlgoStateless() + { + // delete the temporary distrib allocated in constructors + delete &(this->_distrib); + } +}; + +#endif // !_edoAlgoStateless_h + diff --git a/edo/src/edoBounder.h b/edo/src/edoBounder.h index 8f418aa8..19b90b6b 100644 --- a/edo/src/edoBounder.h +++ b/edo/src/edoBounder.h @@ -34,6 +34,7 @@ Authors: * a given set of bounds (typically an hypercube). * * @ingroup Repairers + * @ingroup Core */ template < typename EOT > class edoBounder : public edoRepairer< EOT > diff --git a/edo/src/edoContinue.h b/edo/src/edoContinue.h index 4f680663..8089601e 100644 --- a/edo/src/edoContinue.h +++ b/edo/src/edoContinue.h @@ -31,8 +31,13 @@ Authors: #include #include -//! edoContinue< D > class fitted to Distribution Object library - +/** A continuator that check the state of an edoDistrib + * + * @see eoContinue + * + * @ingroup Continuators + * @ingroup Core + */ template < typename D > class edoContinue : public eoUF< const D&, bool >, public eoPersistent { diff --git a/edo/src/edoDistrib.h b/edo/src/edoDistrib.h index a6712a4b..57cb45b3 100644 --- a/edo/src/edoDistrib.h +++ b/edo/src/edoDistrib.h @@ -30,8 +30,24 @@ Authors: #include -//! edoDistrib< EOT > +/** @defgroup Core + * + * Core functors that made the basis of EDO. + */ +/** @defgroup Distributions Distributions + * + * A distribution is a data structure that holds sufficient informations to + * describe a probability density function by a set of parameters. + * + * It is passed across EDO operators and can be updated or manipulated by them. + */ + +/** Base class for distributions. This is really just an empty shell. + * + * @ingroup Distributions + * @ingroup Core + */ template < typename EOT > class edoDistrib : public eoFunctorBase { diff --git a/edo/src/edoEDASA.h b/edo/src/edoEDASA.h index b2f0fe70..1966d54d 100644 --- a/edo/src/edoEDASA.h +++ b/edo/src/edoEDASA.h @@ -29,7 +29,7 @@ Authors: #define _edoEDASA_h #include -#include +//#include #include @@ -46,13 +46,13 @@ class edoEDASA : public edoAlgo< D > { public: //! Alias for the type EOT - typedef typename D::EOType EOT; + typedef typename D::EOType EOType; //! Alias for the atom type - typedef typename EOT::AtomType AtomType; + typedef typename EOType::AtomType AtomType; //! Alias for the fitness - typedef typename EOT::Fitness Fitness; + typedef typename EOType::Fitness Fitness; public: @@ -73,18 +73,18 @@ public: \param initial_temperature The initial temperature. \param replacor Population replacor */ - edoEDASA (eoSelect< EOT > & selector, + edoEDASA (eoSelect< EOType > & selector, edoEstimator< D > & estimator, - eoSelectOne< EOT > & selectone, + eoSelectOne< EOType > & selectone, edoModifierMass< D > & modifier, edoSampler< D > & sampler, - eoContinue< EOT > & pop_continue, + eoContinue< EOType > & pop_continue, edoContinue< D > & distribution_continue, - eoEvalFunc < EOT > & evaluation, - moContinuator< moDummyNeighbor > & sa_continue, - moCoolingSchedule & cooling_schedule, + eoEvalFunc < EOType > & evaluation, + moContinuator< moDummyNeighbor > & sa_continue, + moCoolingSchedule & cooling_schedule, double initial_temperature, - eoReplacement< EOT > & replacor + eoReplacement< EOType > & replacor ) : _selector(selector), _estimator(estimator), @@ -108,15 +108,15 @@ public: \param pop A population to improve. \return TRUE. */ - void operator ()(eoPop< EOT > & pop) + void operator ()(eoPop< EOType > & pop) { assert(pop.size() > 0); double temperature = _initial_temperature; - eoPop< EOT > current_pop; + eoPop< EOType > current_pop; - eoPop< EOT > selected_pop; + eoPop< EOType > selected_pop; //------------------------------------------------------------- @@ -165,7 +165,7 @@ public: // Init of a variable contening a point with the bestest fitnesses //------------------------------------------------------------- - EOT current_solution = _selectone(selected_pop); + EOType current_solution = _selectone(selected_pop); //------------------------------------------------------------- @@ -200,7 +200,7 @@ public: do { - EOT candidate_solution = _sampler(distrib); + EOType candidate_solution = _sampler(distrib); _evaluation( candidate_solution ); // TODO: verifier le critere d'acceptation @@ -232,14 +232,14 @@ public: private: - //! A EOT selector - eoSelect < EOT > & _selector; + //! A EOType selector + eoSelect < EOType > & _selector; - //! A EOT estimator. It is going to estimate distribution parameters. + //! A EOType estimator. It is going to estimate distribution parameters. edoEstimator< D > & _estimator; //! SelectOne - eoSelectOne< EOT > & _selectone; + eoSelectOne< EOType > & _selectone; //! A D modifier edoModifierMass< D > & _modifier; @@ -247,26 +247,26 @@ private: //! A D sampler edoSampler< D > & _sampler; - //! A EOT population continuator - eoContinue < EOT > & _pop_continue; + //! A EOType population continuator + eoContinue < EOType > & _pop_continue; //! A D continuator edoContinue < D > & _distribution_continue; //! A full evaluation function. - eoEvalFunc < EOT > & _evaluation; + eoEvalFunc < EOType > & _evaluation; //! Stopping criterion before temperature update - moContinuator< moDummyNeighbor > & _sa_continue; + moContinuator< moDummyNeighbor > & _sa_continue; //! The cooling schedule - moCoolingSchedule & _cooling_schedule; + moCoolingSchedule & _cooling_schedule; //! Initial temperature double _initial_temperature; - //! A EOT replacor - eoReplacement < EOT > & _replacor; + //! A EOType replacor + eoReplacement < EOType > & _replacor; }; #endif // !_edoEDASA_h diff --git a/edo/src/edoEstimator.h b/edo/src/edoEstimator.h index ea70e496..7c9df6f2 100644 --- a/edo/src/edoEstimator.h +++ b/edo/src/edoEstimator.h @@ -31,8 +31,20 @@ Authors: #include #include -//! edoEstimator< D > +/** @defgroup Estimators Estimators + * + * Estimators takes an eoPop and estimates the parameters of a distributions + * (defined as an hypothesis) from it. + */ +/** Base class for estimators. + * + * Estimators takes an eoPop and estimates the parameters of a distributions + * (defined as an hypothesis) from it. + * + * @ingroup Estimators + * @ingroup Core + */ template < typename D > class edoEstimator : public eoUF< eoPop< typename D::EOType >&, D > { diff --git a/edo/src/edoEstimatorAdaptive.h b/edo/src/edoEstimatorAdaptive.h new file mode 100644 index 00000000..225e2e57 --- /dev/null +++ b/edo/src/edoEstimatorAdaptive.h @@ -0,0 +1,58 @@ +/* +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 + Pierre Savéant +*/ + +#ifndef _edoEstimatorAdaptive_h +#define _edoEstimatorAdaptive_h + +#include +#include + +#include "edoEstimator.h" + +/** An interface that explicits the needs for a permanent distribution + * that will be updated by operators. + * + * @ingroup Estimators + * @ingroup Core + */ +template < typename D > +class edoEstimatorAdaptive : public edoEstimator +{ +public: + typedef typename D::EOType EOType; + + edoEstimatorAdaptive( D& distrib ) : _distrib(distrib) {} + + // virtual D operator() ( eoPop< EOT >& )=0 (provided by eoUF< A1, R >) + + D & distribution() const { return _distrib; } + +protected: + D & _distrib; +}; + +#endif // !_edoEstimatorAdaptive_h diff --git a/edo/src/edoEstimatorNormalAdaptive.h b/edo/src/edoEstimatorNormalAdaptive.h new file mode 100644 index 00000000..f1adf723 --- /dev/null +++ b/edo/src/edoEstimatorNormalAdaptive.h @@ -0,0 +1,253 @@ +/* +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 + Pierre Savéant +*/ + + +#ifndef _edoEstimatorNormalAdaptive_h +#define _edoEstimatorNormalAdaptive_h + +#ifdef WITH_EIGEN + +#include + +#include + +#include "edoNormalAdaptive.h" +#include "edoEstimatorAdaptive.h" + +/** An estimator that works on adaptive normal distributions, basically the heart of the CMA-ES algorithm. + * + * @ingroup Estimators + * @ingroup CMAES + * @ingroup Adaptivenormal + */ +template< typename EOT, typename D = edoNormalAdaptive > +class edoEstimatorNormalAdaptive : public edoEstimatorAdaptive< D > +{ +public: + typedef typename EOT::AtomType AtomType; + typedef typename D::Vector Vector; // column vectors @see edoNormalAdaptive + typedef typename D::Matrix Matrix; + + edoEstimatorNormalAdaptive( D& distrib ) : + edoEstimatorAdaptive( distrib ), + _calls(0), + _eigeneval(0) + {} + +private: + Eigen::VectorXd edoCMAESweights( unsigned int pop_size ) + { + // compute recombination weights + Eigen::VectorXd weights( pop_size ); + double sum_w = 0; + for( unsigned int i = 0; i < pop_size; ++i ) { + double w_i = log( pop_size + 0.5 ) - log( i + 1 ); + weights(i) = w_i; + sum_w += w_i; + } + // normalization of weights + weights /= sum_w; + + assert( weights.size() == pop_size); + return weights; + } + +public: + void resetCalls() + { + _calls = 0; + } + + // update the distribution reference this->distribution() + edoNormalAdaptive operator()( eoPop& pop ) + { + + /********************************************************************** + * INITIALIZATION + *********************************************************************/ + + unsigned int N = pop[0].size(); // FIXME expliciter la dimension du pb ? + unsigned int lambda = pop.size(); + + // number of calls to the operator == number of generations + _calls++; + // number of "evaluations" until now + unsigned int counteval = _calls * lambda; + + // Here, if we are in canonical CMA-ES, + // pop is supposed to be the mu ranked better solutions, + // as the rank mu selection is supposed to have occured. + Matrix arx( N, lambda ); + + // copy the pop (most probably a vector of vectors) in a Eigen3 matrix + for( unsigned int d = 0; d < N; ++d ) { + for( unsigned int i = 0; i < lambda; ++i ) { + arx(d,i) = pop[i][d]; // NOTE: pop = arx.transpose() + } // dimensions + } // individuals + + // muXone array for weighted recombination + Eigen::VectorXd weights = edoCMAESweights( lambda ); + assert( weights.size() == lambda ); + + // FIXME exposer les constantes dans l'interface + + // variance-effectiveness of sum w_i x_i + double mueff = pow(weights.sum(), 2) / (weights.array().square()).sum(); + + // time constant for cumulation for C + double cc = (4+mueff/N) / (N+4 + 2*mueff/N); + + // t-const for cumulation for sigma control + double cs = (mueff+2) / (N+mueff+5); + + // learning rate for rank-one update of C + double c1 = 2 / (pow(N+1.3,2)+mueff); + + // and for rank-mu update + double cmu = 2 * (mueff-2+1/mueff) / ( pow(N+2,2)+mueff); + + // damping for sigma + double damps = 1 + 2*std::max(0.0, sqrt((mueff-1)/(N+1))-1) + cs; + + + // shortcut to the referenced distribution + D& d = this->distribution(); + + // C^-1/2 + Matrix invsqrtC = + d.coord_sys() * d.scaling().asDiagonal().inverse() + * d.coord_sys().transpose(); + assert( invsqrtC.innerSize() == d.coord_sys().innerSize() ); + assert( invsqrtC.outerSize() == d.coord_sys().outerSize() ); + + // expectation of ||N(0,I)|| == norm(randn(N,1)) + double chiN = sqrt(N)*(1-1/(4*N)+1/(21*pow(N,2))); + + + /********************************************************************** + * WEIGHTED MEAN + *********************************************************************/ + + // compute weighted mean into xmean + Vector xold = d.mean(); + assert( xold.size() == N ); + // xmean ( N, 1 ) = arx( N, lambda ) * weights( lambda, 1 ) + Vector xmean = arx * weights; + assert( xmean.size() == N ); + d.mean( xmean ); + + + /********************************************************************** + * CUMULATION: UPDATE EVOLUTION PATHS + *********************************************************************/ + + // cumulation for sigma + d.path_sigma( + (1.0-cs)*d.path_sigma() + sqrt(cs*(2.0-cs)*mueff)*invsqrtC*(xmean-xold)/d.sigma() + ); + + // sign of h + double hsig; + if( d.path_sigma().norm()/sqrt(1.0-pow((1.0-cs),(2.0*counteval/lambda)))/chiN + < 1.4 + 2.0/(N+1.0) + ) { + hsig = 1.0; + } else { + hsig = 0.0; + } + + // cumulation for the covariance matrix + d.path_covar( + (1.0-cc)*d.path_covar() + hsig*sqrt(cc*(2.0-cc)*mueff)*(xmean-xold) / d.sigma() + ); + + Matrix xmu( N, lambda); + xmu = xold.rowwise().replicate(lambda); + assert( xmu.innerSize() == N ); + assert( xmu.outerSize() == lambda ); + Matrix artmp = (1.0/d.sigma()) * (arx - xmu); + // Matrix artmp = (1.0/d.sigma()) * arx - xold.colwise().replicate(lambda); + assert( artmp.innerSize() == N && artmp.outerSize() == lambda ); + + + /********************************************************************** + * COVARIANCE MATRIX ADAPTATION + *********************************************************************/ + + d.covar( + (1-c1-cmu) * d.covar() // regard old matrix + + c1 * (d.path_covar()*d.path_covar().transpose() // plus rank one update + + (1-hsig) * cc*(2-cc) * d.covar()) // minor correction if hsig==0 + + cmu * artmp * weights.asDiagonal() * artmp.transpose() // plus rank mu update + ); + + // Adapt step size sigma + d.sigma( d.sigma() * exp((cs/damps)*(d.path_sigma().norm()/chiN - 1)) ); + + + + /********************************************************************** + * DECOMPOSITION OF THE COVARIANCE MATRIX + *********************************************************************/ + + // Decomposition of C into B*diag(D.^2)*B' (diagonalization) + if( counteval - _eigeneval > lambda/(c1+cmu)/N/10 ) { // to achieve O(N^2) + _eigeneval = counteval; + + // enforce symmetry of the covariance matrix + Matrix C = d.covar(); + // FIXME edoEstimatorNormalAdaptive.h:213:44: erreur: expected primary-expression before ‘)’ token + // copy the upper part in the lower one + //C.triangularView() = C.adjoint(); + // Matrix CS = C.triangularView() + C.triangularView().transpose(); + d.covar( C ); + + Eigen::SelfAdjointEigenSolver eigensolver( d.covar() ); // FIXME use JacobiSVD? + d.coord_sys( eigensolver.eigenvectors() ); + Matrix mD = eigensolver.eigenvalues().asDiagonal(); + assert( mD.innerSize() == N && mD.outerSize() == N ); + + // from variance to standard deviations + mD.cwiseSqrt(); + d.scaling( mD.diagonal() ); + } + + return d; + } // operator() + +protected: + + unsigned int _calls; + unsigned int _eigeneval; + + + // D & distribution() inherited from edoEstimatorAdaptive +}; +#endif // WITH_EIGEN + +#endif // !_edoEstimatorNormalAdaptive_h diff --git a/edo/src/edoEstimatorNormalMono.h b/edo/src/edoEstimatorNormalMono.h index c5ddade4..12db5188 100644 --- a/edo/src/edoEstimatorNormalMono.h +++ b/edo/src/edoEstimatorNormalMono.h @@ -31,8 +31,11 @@ Authors: #include "edoEstimator.h" #include "edoNormalMono.h" -//! edoEstimatorNormalMono< EOT > - +/** An estimator for edoNormalMono + * + * @ingroup Estimators + * @ingroup Mononormal + */ template < typename EOT > class edoEstimatorNormalMono : public edoEstimator< edoNormalMono< EOT > > { diff --git a/edo/src/edoEstimatorNormalMulti.h b/edo/src/edoEstimatorNormalMulti.h index cfd979fe..1298d8a5 100644 --- a/edo/src/edoEstimatorNormalMulti.h +++ b/edo/src/edoEstimatorNormalMulti.h @@ -29,107 +29,129 @@ Authors: #ifndef _edoEstimatorNormalMulti_h #define _edoEstimatorNormalMulti_h + #include "edoEstimator.h" #include "edoNormalMulti.h" -//! edoEstimatorNormalMulti< EOT > +#ifdef WITH_BOOST +#include +#include +namespace ublas = boost::numeric::ublas; +#else +#ifdef WITH_EIGEN +#include +#endif // WITH_EIGEN +#endif // WITH_BOOST -template < typename EOT > -class edoEstimatorNormalMulti : public edoEstimator< edoNormalMulti< EOT > > + +/** An estimator for edoNormalMulti + * + * Exists in two implementations, using either + * Boost::uBLAS (if compiled WITH_BOOST) + * or Eigen3 (WITH_EIGEN). + * + * @ingroup Estimators + * @ingroup EMNA + * @ingroup Multinormal + */ +template < typename EOT, typename D=edoNormalMulti > +class edoEstimatorNormalMulti : public edoEstimator { + +#ifdef WITH_BOOST 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 +159,98 @@ 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 + +public: + class CovMatrix + { + public: + typedef typename EOT::AtomType AtomType; + typedef typename D::Vector Vector; + typedef typename D::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 +}; // class edoNormalMulti + #endif // !_edoEstimatorNormalMulti_h diff --git a/edo/src/edoEstimatorUniform.h b/edo/src/edoEstimatorUniform.h index 4f24bcba..f799ac2f 100644 --- a/edo/src/edoEstimatorUniform.h +++ b/edo/src/edoEstimatorUniform.h @@ -31,42 +31,42 @@ Authors: #include "edoEstimator.h" #include "edoUniform.h" -// TODO: calcule de la moyenne + covariance dans une classe derivee - -//! edoEstimatorUniform - +/** An estimator for edoUniform + * + * @ingroup Estimators + */ template < typename EOT > class edoEstimatorUniform : public edoEstimator< edoUniform< EOT > > { public: edoUniform< EOT > operator()(eoPop& pop) { - unsigned int size = pop.size(); + unsigned int size = pop.size(); - assert(size > 0); + assert(size > 0); - EOT min = pop[0]; - EOT max = pop[0]; + EOT min = pop[0]; + EOT max = pop[0]; - for (unsigned int i = 1; i < size; ++i) - { - unsigned int size = pop[i].size(); + for (unsigned int i = 1; i < size; ++i) + { + unsigned int size = pop[i].size(); - assert(size > 0); + assert(size > 0); - // possibilité d'utiliser std::min_element et std::max_element mais exige 2 pass au lieu d'1. + // possibilité d'utiliser std::min_element et std::max_element mais exige 2 pass au lieu d'1. - for (unsigned int d = 0; d < size; ++d) - { - if (pop[i][d] < min[d]) - min[d] = pop[i][d]; + for (unsigned int d = 0; d < size; ++d) + { + if (pop[i][d] < min[d]) + min[d] = pop[i][d]; - if (pop[i][d] > max[d]) - max[d] = pop[i][d]; - } - } + if (pop[i][d] > max[d]) + max[d] = pop[i][d]; + } + } - return edoUniform< EOT >(min, max); + return edoUniform< EOT >(min, max); } }; diff --git a/edo/src/edoModifier.h b/edo/src/edoModifier.h index 12687aa8..2b1ef2cb 100644 --- a/edo/src/edoModifier.h +++ b/edo/src/edoModifier.h @@ -28,8 +28,16 @@ Authors: #ifndef _edoModifier_h #define _edoModifier_h -//! edoModifier< D > +/** @defgroup Modifiers + * + * A set of classes that arbitrarly modify a given distribution. + */ +/** A functor to arbitrarly modify a distribution + * + * @ingroup Core + * @ingroup Modifiers + */ template < typename D > class edoModifier { diff --git a/edo/src/edoModifierDispersion.h b/edo/src/edoModifierDispersion.h index a4a6e9ea..7636f67e 100644 --- a/edo/src/edoModifierDispersion.h +++ b/edo/src/edoModifierDispersion.h @@ -33,8 +33,10 @@ Authors: #include "edoModifier.h" -//! edoModifierDispersion< D > - +/** An semantic pseudo-interface for modifiers that updates dispersion parameters (like variance). + * + * @ingroup Modifiers + */ template < typename D > class edoModifierDispersion : public edoModifier< D >, public eoBF< D&, eoPop< typename D::EOType >&, void > { diff --git a/edo/src/edoModifierMass.h b/edo/src/edoModifierMass.h index db9ddcbf..aa90c55a 100644 --- a/edo/src/edoModifierMass.h +++ b/edo/src/edoModifierMass.h @@ -32,8 +32,11 @@ Authors: #include "edoModifier.h" -//! edoModifierMass< D > +/** An semantic pseudo-interface for modifiers that updates mass parameters (like mean). + * + * @ingroup Modifiers + */ template < typename D > class edoModifierMass : public edoModifier< D >, public eoBF< D&, typename D::EOType&, void > { diff --git a/edo/src/edoNormalAdaptive.h b/edo/src/edoNormalAdaptive.h new file mode 100644 index 00000000..3d409140 --- /dev/null +++ b/edo/src/edoNormalAdaptive.h @@ -0,0 +1,156 @@ + +/* +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 Dreo + Pierre Savéant +*/ + +#ifndef _edoNormalAdaptive_h +#define _edoNormalAdaptive_h + +#include "edoDistrib.h" + +#ifdef WITH_EIGEN + +#include + +/** @defgroup CMAES CMAES + * + * CMA-ES (Covariance Matrix Adaptation Evolution Strategy) is a stochastic, + * derivative-free methods for numerical optimization of non-linear or + * non-convex continuous optimization problems. + * + * @ingroup Algorithms + */ + +/** @defgroup Adaptivenormal Adaptive normal + * + * A multi-variate normal distribution that can be updated via several components. + * This is the data structure on which works the CMA-ES algorithm. + * + * @ingroup Distributions + */ + +/** A normal distribution that can be updated via several components. This is the data structure on which works the CMA-ES + * algorithm. + * + * This is *just* a data structure, the operators working on it are supposed to maintain its consistency (e.g. of the + * covariance matrix against its eigen vectors). + * + * The distribution is defined by its mean, its covariance matrix (which can be decomposed in its eigen vectors and + * values), a scaling factor (sigma) and the so-called evolution paths for the covariance and sigma. + * evolution paths. + * + * NOTE: this is only available as an Eigen3 implementation (built WITH_EIGEN). + * + * @ingroup Distributions + * @ingroup CMAES + * @ingroup Adaptivenormal + */ +template < typename EOT > +class edoNormalAdaptive : public edoDistrib< EOT > +{ +public: + //typedef EOT EOType; + typedef typename EOT::AtomType AtomType; + typedef Eigen::Matrix< AtomType, Eigen::Dynamic, 1> Vector; // column vectors ( n lines, 1 column) + typedef Eigen::Matrix< AtomType, Eigen::Dynamic, Eigen::Dynamic> Matrix; + + edoNormalAdaptive( unsigned int dim = 1 ) : + _dim(dim), + _mean( Vector::Zero(dim) ), + _C( Matrix::Identity(dim,dim) ), + _B( Matrix::Identity(dim,dim) ), + _D( Vector::Constant( dim, 1) ), + _sigma(1.0), + _p_c( Vector::Zero(dim) ), + _p_s( Vector::Zero(dim) ) + { + assert( _dim > 0); + } + + edoNormalAdaptive( unsigned int dim, + Vector mean, + Matrix C, + Matrix B, + Vector D, + double sigma, + Vector p_c, + Vector p_s + ) : + _mean( mean ), + _C( C ), + _B( B ), + _D( D ), + _sigma(sigma), + _p_c( p_c ), + _p_s( p_s ) + { + assert( dim > 0); + assert( _mean.innerSize() == dim ); + assert( _C.innerSize() == dim && _C.outerSize() == dim ); + assert( _B.innerSize() == dim && _B.outerSize() == dim ); + assert( _D.innerSize() == dim ); + assert( _sigma != 0.0 ); + assert( _p_c.innerSize() == dim ); + assert( _p_s.innerSize() == dim ); + } + + unsigned int size() + { + return _mean.innerSize(); + } + + Vector mean() const {return _mean;} + Matrix covar() const {return _C;} + Matrix coord_sys() const {return _B;} + Vector scaling() const {return _D;} + double sigma() const {return _sigma;} + Vector path_covar() const {return _p_c;} + Vector path_sigma() const {return _p_s;} + + void mean( Vector m ) { _mean = m; assert( m.size() == _dim ); } + void covar( Matrix c ) { _C = c; assert( c.innerSize() == _dim && c.outerSize() == _dim ); } + void coord_sys( Matrix b ) { _B = b; assert( b.innerSize() == _dim && b.outerSize() == _dim ); } + void scaling( Vector d ) { _D = d; assert( d.size() == _dim ); } + void sigma( double s ) { _sigma = s; assert( s != 0.0 );} + void path_covar( Vector p ) { _p_c = p; assert( p.size() == _dim ); } + void path_sigma( Vector p ) { _p_s = p; assert( p.size() == _dim ); } + +private: + unsigned int _dim; + Vector _mean; // mean vector + Matrix _C; // covariance matrix + Matrix _B; // eigen vectors / coordinates system + Vector _D; // eigen values / scaling + double _sigma; // absolute scaling of the distribution + Vector _p_c; // evolution path for C + Vector _p_s; // evolution path for sigma +}; + +#else +#pragma message "WARNING: there is no Boost::uBLAS implementation of edoNormalAdaptive, build WITH_EIGEN if you need it." +#endif // WITH_EIGEN + +#endif // !_edoNormalAdaptive_h diff --git a/edo/src/edoNormalMono.h b/edo/src/edoNormalMono.h index 4b015d12..12604468 100644 --- a/edo/src/edoNormalMono.h +++ b/edo/src/edoNormalMono.h @@ -30,23 +30,38 @@ Authors: #include "edoDistrib.h" -//! edoNormalMono< EOT > +/** @defgroup Mononormal Normal + * A normal (Gaussian) distribution that only model variances of variables. + * + * @ingroup Distributions + */ +/** A normal (Gaussian) distribution that only model variances of variables. + * + * This is basically a mean vector and a variances vector. Do not model co-variances. + * + * @ingroup Distributions + * @ingroup Mononormal + */ template < typename EOT > class edoNormalMono : public edoDistrib< EOT > { -public: +public: + edoNormalMono() + : _mean(EOT(1,0)), _variance(EOT(1,1)) + {} + edoNormalMono( const EOT& mean, const EOT& variance ) - : _mean(mean), _variance(variance) + : _mean(mean), _variance(variance) { - assert(_mean.size() > 0); - assert(_mean.size() == _variance.size()); + assert(_mean.size() > 0); + assert(_mean.size() == _variance.size()); } unsigned int size() { - assert(_mean.size() == _variance.size()); - return _mean.size(); + assert(_mean.size() == _variance.size()); + return _mean.size(); } EOT mean(){return _mean;} diff --git a/edo/src/edoNormalMonoCenter.h b/edo/src/edoNormalMonoCenter.h index 4b415dc0..9c31204b 100644 --- a/edo/src/edoNormalMonoCenter.h +++ b/edo/src/edoNormalMonoCenter.h @@ -31,8 +31,11 @@ Authors: #include "edoModifierMass.h" #include "edoNormalMono.h" -//! edoNormalMonoCenter< EOT > - +/** Change a distribution's mean for a given EOT + * + * @ingroup Modifiers + * @ingroup Mononormal + */ template < typename EOT > class edoNormalMonoCenter : public edoModifierMass< edoNormalMono< EOT > > { @@ -41,7 +44,7 @@ public: void operator() ( edoNormalMono< EOT >& distrib, EOT& mass ) { - distrib.mean() = mass; + distrib.mean() = mass; } }; diff --git a/edo/src/edoNormalMulti.h b/edo/src/edoNormalMulti.h index 463f0bc8..a64a9121 100644 --- a/edo/src/edoNormalMulti.h +++ b/edo/src/edoNormalMulti.h @@ -1,45 +1,108 @@ -// (c) Thales group, 2010 +/* +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 Dreo - Caner Candan + Johann Dreo + Caner Candan */ #ifndef _edoNormalMulti_h #define _edoNormalMulti_h -#include -#include - #include "edoDistrib.h" +#ifdef WITH_BOOST +#include +#include namespace ublas = boost::numeric::ublas; +#else +#ifdef WITH_EIGEN +#include +#endif // WITH_EIGEN +#endif // WITH_BOOST -//! edoNormalMulti< EOT > +/** @defgroup EMNA + * + * Estimation of Multivariate Normal Algorithm (EMNA) is a stochastic, + * derivative-free methods for numerical optimization of non-linear or + * non-convex continuous optimization problems. + * + * @ingroup Algorithms + */ +/** @defgroup Multinormal Multivariate normal + * + * Distribution that model co-variances between variables. + * + * @ingroup Distributions + */ + +/** A multi-normal distribution, that models co-variances. + * + * Defines a mean vector and a co-variances matrix. + * + * Exists in two implementations, using either + * Boost::uBLAS (if compiled WITH_BOOST) + * or Eigen3 (WITH_EIGEN). + * + * @ingroup Distributions + * @ingroup EMNA + * @ingroup Multinormal + */ template < typename EOT > class edoNormalMulti : public edoDistrib< EOT > { +#ifdef WITH_BOOST + + public: typedef typename EOT::AtomType AtomType; + edoNormalMulti( unsigned int dim = 1 ) : + _mean( const ublas::vector(0,dim) ), + _varcovar( const ublas::identity_matrix(dim) ) + { + assert(_mean.size() > 0); + assert(_mean.size() == _varcovar.size1()); + assert(_mean.size() == _varcovar.size2()); + } + edoNormalMulti ( 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;} @@ -48,6 +111,53 @@ public: private: ublas::vector< AtomType > _mean; ublas::symmetric_matrix< AtomType, ublas::lower > _varcovar; -}; + +#else +#ifdef WITH_EIGEN + + +public: + typedef typename EOT::AtomType AtomType; + typedef Eigen::Matrix< AtomType, Eigen::Dynamic, 1> Vector; + typedef Eigen::Matrix< AtomType, Eigen::Dynamic, Eigen::Dynamic> Matrix; + + edoNormalMulti( unsigned int dim = 1 ) : + _mean( Vector::Zero(dim) ), + _varcovar( Matrix::Identity(dim,dim) ) + { + assert(_mean.size() > 0); + assert(_mean.innerSize() == _varcovar.innerSize()); + assert(_mean.innerSize() == _varcovar.outerSize()); + } + + 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 + +}; // class edoNormalMulti #endif // !_edoNormalMulti_h diff --git a/edo/src/edoNormalMultiCenter.h b/edo/src/edoNormalMultiCenter.h index 199ded47..30510c60 100644 --- a/edo/src/edoNormalMultiCenter.h +++ b/edo/src/edoNormalMultiCenter.h @@ -31,8 +31,14 @@ Authors: #include "edoModifierMass.h" #include "edoNormalMulti.h" -//! edoNormalMultiCenter< EOT > +#ifdef WITH_BOOST +/** Changes a given distribution's mean by a given EOT. + * + * @ingroup Modifiers + * @ingroup EMNA + * @inngroup Multinormal + */ template < typename EOT > class edoNormalMultiCenter : public edoModifierMass< edoNormalMulti< EOT > > { @@ -41,10 +47,39 @@ 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 + +/** Changes a given distribution's mean by a given EOT. + * + * @ingroup Modifiers + */ +template < typename EOT, typename D = edoNormalMulti< EOT > > +class edoNormalMultiCenter : public edoModifierMass +{ +public: + typedef typename EOT::AtomType AtomType; + typedef typename D::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/edoRepairer.h b/edo/src/edoRepairer.h index 8ea2366a..a594bec4 100644 --- a/edo/src/edoRepairer.h +++ b/edo/src/edoRepairer.h @@ -30,11 +30,19 @@ Authors: #include +/** @defgroup Repairers + * + * A set of classes that modifies an unfeasible candidate + * solution so as to respect a given set of constraints and thus make a feasible + * solution. + */ + /** The interface of a set of classes that modifies an unfeasible candidate * solution so as to respect a given set of constraints and thus make a feasible * solution. * * @ingroup Repairers + * @ingroup Core */ template < typename EOT > class edoRepairer : public eoUF< EOT&, void > diff --git a/edo/src/edoRepairerApply.h b/edo/src/edoRepairerApply.h index ca46f344..49430050 100644 --- a/edo/src/edoRepairerApply.h +++ b/edo/src/edoRepairerApply.h @@ -31,7 +31,10 @@ Authors: #include "edoRepairer.h" - +/** Interface for applying an arbitrary unary function as a repairer on each item of the solution + * + * @ingroup Repairers + */ template < typename EOT, typename F = typename EOT::AtomType(typename EOT::AtomType) > class edoRepairerApply : public edoRepairer { diff --git a/edo/src/edoRepairerDispatcher.h b/edo/src/edoRepairerDispatcher.h index b2c0777b..33751813 100644 --- a/edo/src/edoRepairerDispatcher.h +++ b/edo/src/edoRepairerDispatcher.h @@ -175,7 +175,7 @@ public: } // for j } // context for k } // for ipair - + sol.invalidate(); } }; diff --git a/edo/src/edoRepairerModulo.h b/edo/src/edoRepairerModulo.h index 21367333..1bc7e768 100644 --- a/edo/src/edoRepairerModulo.h +++ b/edo/src/edoRepairerModulo.h @@ -31,7 +31,7 @@ Authors: #include "edoRepairerApply.h" -/** +/** Repair an EOT container by applying the standard modulo function on it. * * @ingroup Repairers */ diff --git a/edo/src/edoSampler.h b/edo/src/edoSampler.h index 745eac68..d2b1b431 100644 --- a/edo/src/edoSampler.h +++ b/edo/src/edoSampler.h @@ -33,8 +33,23 @@ Authors: #include "edoRepairer.h" #include "edoBounderNo.h" -//! edoSampler< D > +/** @defgroup Samplers + * + * Functors that draw and repair individuals according to a given distribution. + */ + +/** Base class for samplers + * + * The functor here is already implemented: it first sample an EOT from the + * given distribution, and then apply the given repairers (if set). + * + * Thus, the function that need to be overloaded is "sample", unlike most of EO + * functors. + * + * @ingroup Samplers + * @ingroup Core + */ template < typename D > class edoSampler : public eoUF< D&, typename D::EOType > { diff --git a/edo/src/edoSamplerNormalAdaptive.h b/edo/src/edoSamplerNormalAdaptive.h new file mode 100644 index 00000000..051e1483 --- /dev/null +++ b/edo/src/edoSamplerNormalAdaptive.h @@ -0,0 +1,91 @@ +/* +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 + Pierre Savéant +*/ + +#ifndef _edoSamplerNormalAdaptive_h +#define _edoSamplerNormalAdaptive_h + +#include +#include + +#include + +/** Sample points in a multi-normal law defined by a mean vector, a covariance matrix, a sigma scale factor and + * evolution paths. This is a step of the CMA-ES algorithm. + * + * @ingroup Samplers + * @ingroup CMAES + * @ingroup Adaptivenormal + */ +#ifdef WITH_EIGEN + +template< class EOT, typename D = edoNormalAdaptive< EOT > > +class edoSamplerNormalAdaptive : public edoSampler< D > +{ +public: + typedef typename EOT::AtomType AtomType; + + typedef typename D::Vector Vector; + typedef typename D::Matrix Matrix; + + edoSamplerNormalAdaptive( edoRepairer & repairer ) + : edoSampler< D >( repairer) + {} + + + EOT sample( D& distrib ) + { + unsigned int N = distrib.size(); + assert( N > 0); + + // T = vector of size elements drawn in N(0,1) + Vector T( N ); + for ( unsigned int i = 0; i < N; ++i ) { + T( i ) = rng.normal(); + } + assert(T.innerSize() == N ); + assert(T.outerSize() == 1); + + // mean(N,1) + sigma * B(N,N) * ( D(N,1) .* T(N,1) ) + Vector sol = distrib.mean() + + distrib.sigma() + * distrib.coord_sys() * (distrib.scaling().cwiseProduct(T) ); // C * T = B * (D .* T) + assert( sol.size() == N ); + /*Vector sol = distrib.mean() + distrib.sigma() + * distrib.coord_sys().dot( distrib.scaling().dot( T ) );*/ + + // copy in the EOT structure (more probably a vector) + EOT solution( N ); + for( unsigned int i = 0; i < N; i++ ) { + solution[i]= sol(i); + } + + return solution; + } +}; +#endif // WITH_EIGEN + +#endif // !_edoSamplerNormalAdaptive_h diff --git a/edo/src/edoSamplerNormalMono.h b/edo/src/edoSamplerNormalMono.h index b9340b17..f4bf7964 100644 --- a/edo/src/edoSamplerNormalMono.h +++ b/edo/src/edoSamplerNormalMono.h @@ -36,10 +36,10 @@ Authors: #include "edoNormalMono.h" #include "edoBounder.h" -/** - * edoSamplerNormalMono - * This class uses the NormalMono distribution parameters (bounds) to return - * a random position used for population sampling. +/** A sampler for edoNormalMono + * + * @ingroup Samplers + * @ingroup Mononormal */ template < typename EOT, typename D = edoNormalMono< EOT > > class edoSamplerNormalMono : public edoSampler< D > diff --git a/edo/src/edoSamplerNormalMulti.h b/edo/src/edoSamplerNormalMulti.h index b7e73c75..d6e3b9bc 100644 --- a/edo/src/edoSamplerNormalMulti.h +++ b/edo/src/edoSamplerNormalMulti.h @@ -32,9 +32,19 @@ Authors: #include #include + + +#ifdef WITH_BOOST #include #include #include +namespace ublas = boost::numeric::ublas; +#else +#ifdef WITH_EIGEN +#include +#endif // WITH_EIGEN +#endif // WITH_BOOST + /** Sample points in a multi-normal law defined by a mean vector and a covariance matrix. * @@ -42,19 +52,30 @@ Authors: * - draw a vector T in N(0,I) (i.e. each value is drawn in a normal law with mean=0 an stddev=1) * - compute the Cholesky decomposition L of V (i.e. such as V=LL*) * - return X = M + LT + * + * Exists in two implementations, using either + * Boost::uBLAS (if compiled WITH_BOOST) + * or Eigen3 (WITH_EIGEN). + * + * @ingroup Samplers + * @ingroup EMNA + * @ingroup Multinormal */ -template< class EOT, typename EOD = edoNormalMulti< EOT > > -class edoSamplerNormalMulti : public edoSampler< EOD > +template< typename EOT, typename D = edoNormalMulti< EOT > > +class edoSamplerNormalMulti : public edoSampler< D > { + +#ifdef WITH_BOOST + public: typedef typename EOT::AtomType AtomType; edoSamplerNormalMulti( edoRepairer & repairer ) - : edoSampler< EOD >( repairer) + : edoSampler< D >( repairer) {} - EOT sample( EOD& distrib ) + EOT sample( D& distrib ) { unsigned int size = distrib.size(); assert(size > 0); @@ -82,6 +103,84 @@ public: protected: cholesky::CholeskyLLT _cholesky; -}; + +#else +#ifdef WITH_EIGEN + +public: + typedef typename EOT::AtomType AtomType; + + typedef typename D::Vector Vector; + typedef typename D::Matrix Matrix; + + edoSamplerNormalMulti( edoRepairer & repairer ) + : edoSampler< D >( repairer) + {} + + + EOT sample( D& distrib ) + { + unsigned int size = distrib.size(); + assert(size > 0); + + // LsD = cholesky decomposition of varcovar + + // Computes L and mD such as V = L mD L^T + Eigen::LDLT cholesky( distrib.varcovar() ); + Matrix L = cholesky.matrixL(); + assert(L.innerSize() == size); + assert(L.outerSize() == size); + + Matrix mD = cholesky.vectorD().asDiagonal(); + assert(mD.innerSize() == size); + assert(mD.outerSize() == size); + + // now compute the final symetric matrix: LsD = L mD^1/2 + // remember that V = ( L mD^1/2) ( L mD^1/2)^T + // fortunately, the square root of a diagonal matrix is the square + // root of all its elements + Matrix sqrtD = mD.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 mD^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 +}; // class edoNormalMulti + #endif // !_edoSamplerNormalMulti_h diff --git a/edo/src/edoSamplerUniform.h b/edo/src/edoSamplerUniform.h index 4edf4323..334daf36 100644 --- a/edo/src/edoSamplerUniform.h +++ b/edo/src/edoSamplerUniform.h @@ -34,7 +34,6 @@ Authors: #include "edoUniform.h" /** - * edoSamplerUniform * This class uses the Uniform distribution parameters (bounds) to return * a random position used for population sampling. * @@ -43,6 +42,8 @@ Authors: * * Note: if the distribution given at call defines a min==max for one of the * variable, the result will be the same number. + * + * @ingroup Samplers */ template < typename EOT, class D = edoUniform > class edoSamplerUniform : public edoSampler< D > diff --git a/edo/src/edoUniform.h b/edo/src/edoUniform.h index 3317e1af..fa524d2d 100644 --- a/edo/src/edoUniform.h +++ b/edo/src/edoUniform.h @@ -31,8 +31,12 @@ Authors: #include "edoDistrib.h" #include "edoVectorBounds.h" -//! edoUniform< EOT > - +/** A uniform distribution. + * + * Defined by its bounds. + * + * @ingroup Distributions + */ template < typename EOT > class edoUniform : public edoDistrib< EOT >, public edoVectorBounds< EOT > { diff --git a/edo/src/edoUniformCenter.h b/edo/src/edoUniformCenter.h index 473be4b4..d6e646f3 100644 --- a/edo/src/edoUniformCenter.h +++ b/edo/src/edoUniformCenter.h @@ -31,8 +31,10 @@ Authors: #include "edoModifierMass.h" #include "edoUniform.h" -//! edoUniformCenter< EOT > - +/** Modify an edoUniform distribution by centering its bounds around a given EOT. + * + * @ingroup Modifiers + */ template < typename EOT > class edoUniformCenter : public edoModifierMass< edoUniform< EOT > > { @@ -41,16 +43,16 @@ public: void operator() ( edoUniform< EOT >& distrib, EOT& mass ) { - for (unsigned int i = 0, n = mass.size(); i < n; ++i) - { - AtomType& min = distrib.min()[i]; - AtomType& max = distrib.max()[i]; + for (unsigned int i = 0, n = mass.size(); i < n; ++i) + { + AtomType& min = distrib.min()[i]; + AtomType& max = distrib.max()[i]; - AtomType range = (max - min) / 2; + AtomType range = (max - min) / 2; - min = mass[i] - range; - max = mass[i] + range; - } + min = mass[i] - range; + max = mass[i] + range; + } } }; diff --git a/edo/src/edoVectorBounds.h b/edo/src/edoVectorBounds.h index 4fc64aa6..7d01bad4 100644 --- a/edo/src/edoVectorBounds.h +++ b/edo/src/edoVectorBounds.h @@ -28,8 +28,8 @@ Authors: #ifndef _edoVectorBounds_h #define _edoVectorBounds_h -//! edoVectorBounds< EOT > - +/** A class that holds min and max bounds vectors. + */ template < typename EOT > class edoVectorBounds { diff --git a/edo/src/utils/edoCholesky.h b/edo/src/utils/edoCholesky.h index e0437d00..fad06750 100644 --- a/edo/src/utils/edoCholesky.h +++ b/edo/src/utils/edoCholesky.h @@ -27,6 +27,9 @@ Authors: namespace cholesky { + +#ifdef WITH_BOOST + /** Cholesky decomposition, given a matrix V, return a matrix L * such as V = L L^T (L^T being the transposed of L). * @@ -282,4 +285,11 @@ public: } }; +#else +#ifdef WITH_EIGEN + +#endif // WITH_EIGEN +#endif // WITH_BOOST + + } // namespace cholesky diff --git a/edo/src/utils/edoStatNormalMulti.h b/edo/src/utils/edoStatNormalMulti.h index 3a653edc..961fd7cb 100644 --- a/edo/src/utils/edoStatNormalMulti.h +++ b/edo/src/utils/edoStatNormalMulti.h @@ -28,43 +28,55 @@ Authors: #ifndef _edoStatNormalMulti_h #define _edoStatNormalMulti_h -#include +#include #include "edoStat.h" -#include "edoNormalMulti.h" +#include "../edoNormalMulti.h" + +#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 > > { public: - typedef typename EOT::AtomType AtomType; + // typedef typename EOT::AtomType AtomType; using edoDistribStat< edoNormalMulti< EOT > >::value; edoStatNormalMulti( std::string desc = "" ) - : edoDistribStat< edoNormalMulti< EOT > >( desc ) + : edoDistribStat< edoNormalMulti< EOT > >( desc ) {} void operator()( const edoNormalMulti< EOT >& distrib ) { - value() = "\n# ====== multi normal distribution dump =====\n"; + value() = "\n# ====== multi normal distribution dump =====\n"; - std::ostringstream os; + std::ostringstream os; - os << distrib.mean() << " " << distrib.varcovar() << std::endl; + os << distrib.mean() << std::endl << std::endl << distrib.varcovar() << std::endl; - // ublas::vector< AtomType > mean = distrib.mean(); - // std::copy(mean.begin(), mean.end(), std::ostream_iterator< std::string >( os, " " )); + // ublas::vector< AtomType > mean = distrib.mean(); + // std::copy(mean.begin(), mean.end(), std::ostream_iterator< std::string >( os, " " )); - // ublas::symmetric_matrix< AtomType, ublas::lower > varcovar = distrib.varcovar(); - // std::copy(varcovar.begin(), varcovar.end(), std::ostream_iterator< std::string >( os, " " )); + // ublas::symmetric_matrix< AtomType, ublas::lower > varcovar = distrib.varcovar(); + // std::copy(varcovar.begin(), varcovar.end(), std::ostream_iterator< std::string >( os, " " )); - // os << std::endl; + // os << std::endl; - value() += os.str(); + value() += os.str(); } }; + #endif // !_edoStatNormalMulti_h diff --git a/edo/test/CMakeLists.txt b/edo/test/CMakeLists.txt index 1ceea4f3..7a3129a1 100644 --- a/edo/test/CMakeLists.txt +++ b/edo/test/CMakeLists.txt @@ -33,7 +33,7 @@ LINK_DIRECTORIES(${Boost_LIBRARY_DIRS}) INCLUDE_DIRECTORIES(${CMAKE_SOURCE_DIR}/application/common) SET(SOURCES - t-cholesky + #t-cholesky t-edoEstimatorNormalMulti t-mean-distance t-bounderno diff --git a/edo/test/t-edoEstimatorNormalMulti.cpp b/edo/test/t-edoEstimatorNormalMulti.cpp index 91d93296..5c47f5cf 100644 --- a/edo/test/t-edoEstimatorNormalMulti.cpp +++ b/edo/test/t-edoEstimatorNormalMulti.cpp @@ -29,7 +29,7 @@ Authors: #include #include -#include +//#include #include @@ -40,22 +40,29 @@ typedef eoReal< eoMinimizingFitness > EOT; typedef edoNormalMulti< EOT > Distrib; typedef EOT::AtomType AtomType; +#ifdef WITH_BOOST +#include +#include + typedef ublas::vector< AtomType > Vector; + typedef ublas::symmetric_matrix< AtomType, ublas::lower > Matrix; +#else +#ifdef WITH_EIGEN +#include + typedef typename edoNormalMulti::Vector Vector; + typedef typename edoNormalMulti::Matrix Matrix; +#endif +#endif + int main(int ac, char** av) { - //----------------------------------------------------- // (0) parser + eo routines - //----------------------------------------------------- - eoParser parser(ac, av); - std::string section("Algorithm parameters"); - - unsigned int p_size = parser.createParam((unsigned int)100, "popSize", "Population Size", 'P', section).value(); // P - - unsigned int s_size = parser.createParam((unsigned int)2, "dimension-size", "Dimension size", 'd', section).value(); // d - - AtomType mean_value = parser.createParam((AtomType)0, "mean", "Mean value", 'm', section).value(); // m + std::string section("Algorithm parameters"); + unsigned int p_size = parser.createParam((unsigned int)100, "popSize", "Population Size", 'P', section).value(); // P + unsigned int s_size = parser.createParam((unsigned int)2, "dimension-size", "Dimension size", 'd', section).value(); // d + AtomType mean_value = parser.createParam((AtomType)0, "mean", "Mean value", 'm', section).value(); // m AtomType covar1_value = parser.createParam((AtomType)1.0, "covar1", "Covar value 1", '1', section).value(); AtomType covar2_value = parser.createParam((AtomType)0.5, "covar2", "Covar value 2", '2', section).value(); AtomType covar3_value = parser.createParam((AtomType)1.0, "covar3", "Covar value 3", '3', section).value(); @@ -66,29 +73,20 @@ int main(int ac, char** av) << covar3_value << "_gen"; std::string gen_filename = ss.str(); - if (parser.userNeedsHelp()) - { - parser.printHelp(std::cout); - exit(1); - } + if( parser.userNeedsHelp() ) { + parser.printHelp(std::cout); + exit(1); + } make_verbose(parser); make_help(parser); - assert(p_size > 0); assert(s_size > 0); - eoState state; - //----------------------------------------------------- - - - //----------------------------------------------------- // (1) Population init and sampler - //----------------------------------------------------- - eoRndGenerator< double >* gen = new eoUniformGenerator< double >(-5, 5); state.storeFunctor(gen); @@ -99,18 +97,14 @@ int main(int ac, char** av) // fill population thanks to eoInit instance eoPop< EOT >& pop = state.takeOwnership( eoPop< EOT >( p_size, *init ) ); - //----------------------------------------------------- - - - //----------------------------------------------------------------------------- // (2) distribution initial parameters - //----------------------------------------------------------------------------- + Vector mean( s_size ); - ublas::vector< AtomType > mean( s_size ); + for (unsigned int i = 0; i < s_size; ++i) { + mean( i ) = mean_value; + } - for (unsigned int i = 0; i < s_size; ++i) { mean( i ) = mean_value; } - - ublas::symmetric_matrix< AtomType, ublas::lower > varcovar( s_size, s_size ); + Matrix varcovar( s_size, s_size ); varcovar( 0, 0 ) = covar1_value; varcovar( 0, 1 ) = covar2_value; @@ -118,13 +112,7 @@ int main(int ac, char** av) Distrib distrib( mean, varcovar ); - //----------------------------------------------------------------------------- - - - //----------------------------------------------------------------------------- // (3a) distribution output preparation - //----------------------------------------------------------------------------- - edoDummyContinue< Distrib >* distrib_dummy_continue = new edoDummyContinue< Distrib >(); state.storeFunctor(distrib_dummy_continue); @@ -141,60 +129,29 @@ int main(int ac, char** av) distrib_file_snapshot->add(*distrib_stat); distrib_continue->add(*distrib_file_snapshot); - //----------------------------------------------------------------------------- - - - //----------------------------------------------------------------------------- // (3b) distribution output - //----------------------------------------------------------------------------- - (*distrib_continue)( distrib ); - //----------------------------------------------------------------------------- - - - //----------------------------------------------------------------------------- // Prepare bounder class to set bounds of sampling. // This is used by edoSampler. - //----------------------------------------------------------------------------- - - edoBounder< EOT >* bounder = new edoBounderRng< EOT >(EOT(pop[0].size(), -5), - EOT(pop[0].size(), 5), - *gen); + edoBounder< EOT >* bounder = new edoBounderRng< EOT >( + EOT(pop[0].size(), -5), EOT(pop[0].size(), 5), *gen + ); state.storeFunctor(bounder); - //----------------------------------------------------------------------------- - - - //----------------------------------------------------------------------------- // Prepare sampler class with a specific distribution - //----------------------------------------------------------------------------- - edoSampler< Distrib >* sampler = new edoSamplerNormalMulti< EOT >( *bounder ); state.storeFunctor(sampler); - //----------------------------------------------------------------------------- - - - //----------------------------------------------------------------------------- // (4) sampling phase - //----------------------------------------------------------------------------- - pop.clear(); - for (unsigned int i = 0; i < p_size; ++i) - { - EOT candidate_solution = (*sampler)( distrib ); - pop.push_back( candidate_solution ); - } + for( unsigned int i = 0; i < p_size; ++i ) { + EOT candidate_solution = (*sampler)( distrib ); + pop.push_back( candidate_solution ); + } - //----------------------------------------------------------------------------- - - - //----------------------------------------------------------------------------- // (5) population output - //----------------------------------------------------------------------------- - eoContinue< EOT >* pop_cont = new eoGenContinue< EOT >( 2 ); // never reached fitness state.storeFunctor(pop_cont); @@ -212,53 +169,31 @@ int main(int ac, char** av) (*pop_continue)( pop ); - //----------------------------------------------------------------------------- - - - //----------------------------------------------------------------------------- // (6) estimation phase - //----------------------------------------------------------------------------- - edoEstimator< Distrib >* estimator = new edoEstimatorNormalMulti< EOT >(); state.storeFunctor(estimator); distrib = (*estimator)( pop ); - //----------------------------------------------------------------------------- - - - //----------------------------------------------------------------------------- // (7) distribution output - //----------------------------------------------------------------------------- - (*distrib_continue)( distrib ); - //----------------------------------------------------------------------------- - - - //----------------------------------------------------------------------------- // (8) euclidianne distance estimation - //----------------------------------------------------------------------------- - - ublas::vector< AtomType > new_mean = distrib.mean(); - ublas::symmetric_matrix< AtomType, ublas::lower > new_varcovar = distrib.varcovar(); + Vector new_mean = distrib.mean(); + Matrix new_varcovar = distrib.varcovar(); AtomType distance = 0; - - for ( unsigned int d = 0; d < s_size; ++d ) - { - distance += pow( mean[ d ] - new_mean[ d ], 2 ); - } + for( unsigned int d = 0; d < s_size; ++d ) { + distance += pow( mean[ d ] - new_mean[ d ], 2 ); + } distance = sqrt( distance ); eo::log << eo::logging - << "mean: " << mean << std::endl - << "new mean: " << new_mean << std::endl - << "distance: " << distance << std::endl - ; - - //----------------------------------------------------------------------------- + << "mean: " << mean << std::endl + << "new mean: " << new_mean << std::endl + << "distance: " << distance << std::endl + ; return 0; } diff --git a/edo/test/t-mean-distance.cpp b/edo/test/t-mean-distance.cpp index 8e62c378..4e184f5a 100644 --- a/edo/test/t-mean-distance.cpp +++ b/edo/test/t-mean-distance.cpp @@ -33,29 +33,37 @@ Authors: #include #include -#include +//#include #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/CMakeLists.txt b/eo/CMakeLists.txt index df128f13..31cd2cf4 100644 --- a/eo/CMakeLists.txt +++ b/eo/CMakeLists.txt @@ -1,3 +1,4 @@ +CMAKE_MINIMUM_REQUIRED(VERSION 2.6) ###################################################################################### ### 0) If you want to set your variables in eo-conf.cmake and avoid the cmd line diff --git a/eo/NEWS b/eo/NEWS index f4625d6c..6657f36b 100644 --- a/eo/NEWS +++ b/eo/NEWS @@ -1,4 +1,29 @@ -* current version +* current release: + +* release 1.3.1 (2012-07-27) + - the eo::mpi modules is no longer dependent from boost::mpi + - parallel multi-start example + - bugfix: an error is now thrown when accessing best_element of an empty population + +* release 1.3.0 (2012-07-24) + - features: + - delete the deprecated code parts (was marked as deprecated in the release 1.1) + - eoSignal: a class to handle signal with eoCheckpoint instances + - eoDetSingleBitFlip: bit flip mutation that changes exactly k bits while checking for duplicate + - eoFunctorStat: a wrapper to turn any stand-alone function and into an eoStat + - generilazed the output of an eoState: now you can change the format, comes with defaults formatting (latex and json) + - eoWrongParamTypeException: a new exception to handle cases where a wrong template is given to eoParser::valueOf + - added a getParam method to the eoParser, that raise an exception if the parameter has not been declared + - eoParserLogger features are now included in the default eoParser + - build system: + - improvements of the build architecture + - create PKGBUILD file for archlinux package manager + - a FindEO module for CMake + - bugfixes: + - fixed regression with gcc 4.7 + - fixed compilation issues in Microsoft Visual C++, related to time measurement + - added several asserts accross the framework (note: asserts are included only in debug mode) + - lot of small bugfixes :-) * release 1.2 (16. May. 2011) - fixed the incremental allocation issue in variation operators which were @@ -20,11 +45,11 @@ - GCC 4.3 compatibility - new versatile log system with several nested verbose levels - classes using intern verbose parameters marked as deprecated, please update your code accordingly if you use one of the following files: - eo/src/eoCombinedInit.h - eo/src/eoGenContinue.h - eo/src/eoProportionalCombinedOp.h - eo/src/utils/eoData.h - eo/src/utils/eoStdoutMonitor.h + eo/src/eoCombinedInit.h + eo/src/eoGenContinue.h + eo/src/eoProportionalCombinedOp.h + eo/src/utils/eoData.h + eo/src/utils/eoStdoutMonitor.h - an evaluator that throw an exception if a maximum eval numbers has been reached, independently of the number of generations - new monitor that can write on any ostream - new continuator that can catch POSIX system user signals diff --git a/eo/doc/index.h b/eo/doc/index.h index 52a5758c..d3ba1450 100644 --- a/eo/doc/index.h +++ b/eo/doc/index.h @@ -5,7 +5,7 @@ The best place to learn about the features and approaches of %EO with the help of examples is to look at the tutorial. -Once you have understand the @ref design of %EO, you could search for advanced features by browsing the modules page. diff --git a/eo/eo-conf.cmake b/eo/eo-conf.cmake index 13fd720a..7ccc9cee 100644 --- a/eo/eo-conf.cmake +++ b/eo/eo-conf.cmake @@ -2,9 +2,10 @@ # Current version SET(PROJECT_VERSION_MAJOR 1) SET(PROJECT_VERSION_MINOR 3) -SET(PROJECT_VERSION_PATCH 0) +SET(PROJECT_VERSION_PATCH 2) SET(PROJECT_VERSION_MISC "-edge") +# ADD_DEFINITIONS(-DDEPRECATED_MESSAGES) # disable warning deprecated function messages # If you plan to use OpenMP, put the following boolean to true : SET(WITH_OMP FALSE CACHE BOOL "Use OpenMP ?" FORCE) diff --git a/eo/install_symlink.py.cmake b/eo/install_symlink.py.cmake index 145d67a1..382c0b9f 100755 --- a/eo/install_symlink.py.cmake +++ b/eo/install_symlink.py.cmake @@ -9,8 +9,8 @@ PREFIX = "/usr" DATA = { 'dirs': [ "%s/share/%s" % (PREFIX, NAME) ], 'links': [ ("%s/src" % SOURCE, "%s/include/%s" % (PREFIX, NAME)), - ("%s/doc" % BINARY, "%s/share/%s/doc" % (PREFIX, NAME)), - ("%s/%s.pc" % (BINARY, NAME), "%s/lib/pkgconfig/%s.pc" % (PREFIX, NAME)), + ("%s/doc" % BINARY, "%s/share/%s/doc" % (PREFIX, NAME)), + ("%s/%s.pc" % (BINARY, NAME), "%s/lib/pkgconfig/%s.pc" % (PREFIX, NAME)), ] } @@ -21,19 +21,27 @@ import os, sys def isroot(): if os.getuid() != 0: - print '[WARNING] you have to be root' - return False + print('[WARNING] you have to be root') + return False return True def uninstall(): for dummy, link in DATA['links']: os.remove(link) for dirname in DATA['dirs']: os.rmdir(dirname) - print 'All symlinks have been removed.' + 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) - print 'All symlinks have been installed.' + 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(): from pprint import pprint @@ -41,11 +49,11 @@ def data(): if __name__ == '__main__': if not isroot(): - sys.exit() + sys.exit() if len(sys.argv) < 2: - print 'Usage: %s [install|uninstall|data]' % sys.argv[0] - sys.exit() + print(('Usage: %s [install|uninstall|data]' % sys.argv[0])) + sys.exit() if sys.argv[1] == 'install': install() elif sys.argv[1] == 'uninstall': uninstall() diff --git a/eo/src/CMakeLists.txt b/eo/src/CMakeLists.txt index 6509908a..317080f1 100644 --- a/eo/src/CMakeLists.txt +++ b/eo/src/CMakeLists.txt @@ -11,7 +11,8 @@ INCLUDE_DIRECTORIES(${CMAKE_CURRENT_SOURCE_DIR}) IF(WITH_MPI) MESSAGE("[EO] Compilation with MPI.") - SET(CMAKE_CXX_COMPILER "${MPI_DIR}/bin/mpicxx") + #SET(CMAKE_CXX_COMPILER "${MPI_DIR}/bin/mpicxx") + SET(CMAKE_CXX_COMPILER mpicxx) # headers location INCLUDE_DIRECTORIES(${MPI_DIR}/include) diff --git a/eo/src/apply.h b/eo/src/apply.h index 939e62bd..45c4cfc2 100644 --- a/eo/src/apply.h +++ b/eo/src/apply.h @@ -19,7 +19,7 @@ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA Contact: todos@geneura.ugr.es, http://geneura.ugr.es - mak@dhi.dk + mak@dhi.dk */ //----------------------------------------------------------------------------- @@ -31,7 +31,10 @@ #include #include #include + +#ifdef _OPENMP #include +#endif /** Applies a unary function to a std::vector of things. @@ -55,14 +58,26 @@ void apply(eoUF& _proc, std::vector& _pop) if (!eo::parallel.isDynamic()) { #pragma omp parallel for if(eo::parallel.isEnabled()) //default(none) shared(_proc, _pop, size) +#ifdef _MSC_VER + //Visual Studio supports only OpenMP version 2.0 in which + //an index variable must be of a signed integral type + for (long long i = 0; i < size; ++i) { _proc(_pop[i]); } +#else // _MSC_VER for (size_t i = 0; i < size; ++i) { _proc(_pop[i]); } +#endif } else { #pragma omp parallel for schedule(dynamic) if(eo::parallel.isEnabled()) +#ifdef _MSC_VER + //Visual Studio supports only OpenMP version 2.0 in which + //an index variable must be of a signed integral type + for (long long i = 0; i < size; ++i) { _proc(_pop[i]); } +#else // _MSC_VER //doesnot work with gcc 4.1.2 //default(none) shared(_proc, _pop, size) for (size_t i = 0; i < size; ++i) { _proc(_pop[i]); } +#endif } if ( eo::parallel.enableResults() ) @@ -94,7 +109,7 @@ void apply(eoUF& _proc, std::vector& _pop) // //default(none) shared(_proc, _pop, size) // for (size_t i = 0; i < size; ++i) // { -// _proc(_pop[i]); +// _proc(_pop[i]); // } // } @@ -112,7 +127,7 @@ void apply(eoUF& _proc, std::vector& _pop) // //default(none) shared(_proc, _pop, size) // for (size_t i = 0; i < size; ++i) // { -// _proc(_pop[i]); +// _proc(_pop[i]); // } // } diff --git a/eo/src/do/make_checkpoint.h b/eo/src/do/make_checkpoint.h index 7958ed5b..cc0746dd 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 33c7f720..f241667f 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 26463fab..27d050ad 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/eo b/eo/src/eo index 23df6ee5..fd660b7b 100644 --- a/eo/src/eo +++ b/eo/src/eo @@ -102,6 +102,7 @@ #include // Embedding truncation selection #include +#include // the batch selection - from an eoSelectOne #include diff --git a/eo/src/eoCombinedContinue.h b/eo/src/eoCombinedContinue.h index 5226e28d..5162ffaa 100644 --- a/eo/src/eoCombinedContinue.h +++ b/eo/src/eoCombinedContinue.h @@ -57,26 +57,35 @@ public: { } + /* FIXME remove in next release /// Ctor - for historical reasons ... should disspear some day eoCombinedContinue( eoContinue& _cont1, eoContinue& _cont2) : eoContinue(), std::vector* >() { +#ifndef DEPRECATED_MESSAGES #pragma message "The double continuators constructor of eocombinedContinue is deprecated and will be removed in the next release." +#endif // !DEPRECATED_MESSAGES 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 #pragma message "The removeLast method of eocombinedContinue is deprecated and will be removed in the next release, use pop_back instead." +#endif // !DEPRECATED_MESSAGES + 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 d41122d8..cc93620d 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 9bbcf9c0..e239f736 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/eoDetSelect.h b/eo/src/eoDetSelect.h index 4a0858b6..c89f41f6 100644 --- a/eo/src/eoDetSelect.h +++ b/eo/src/eoDetSelect.h @@ -34,7 +34,7 @@ #include //----------------------------------------------------------------------------- -/** eoDetSelect selects many individuals determinisctically +/** eoDetSelect selects many individuals deterministically * * @ingroup Selectors */ diff --git a/eo/src/eoEvalUserTimeThrowException.h b/eo/src/eoEvalUserTimeThrowException.h index 87e47ac5..2d9ccadd 100644 --- a/eo/src/eoEvalUserTimeThrowException.h +++ b/eo/src/eoEvalUserTimeThrowException.h @@ -21,27 +21,30 @@ Authors: Johann Dréo */ -#ifndef __unix__ -#warning "Warning: class 'eoEvalUserTimeThrowException' is only available under UNIX systems (defining 'rusage' in 'sys/resource.h'), contributions for other systems are welcomed." -#else +#if !defined(__unix__) && !defined(_WINDOWS) +#warning "Warning: class 'eoEvalUserTimeThrowException' is only available under UNIX (defining 'rusage' in 'sys/resource.h') or Win32 (defining 'GetProcessTimes' in 'WinBase.h') systems, contributions for other systems are welcomed." +#else //!defined(__unix__) && !defined(_WINDOWS) #ifndef __EOEVALUSERTIMETHROWEXCEPTION_H__ #define __EOEVALUSERTIMETHROWEXCEPTION_H__ -#include -#include - -#include - /** Check at each evaluation if a given CPU user time contract has been reached. * * Throw an eoMaxTimeException if the given max time has been reached. * Usefull if you want to end the search independently of generations. - * This class uses (almost-)POSIX headers. + * This class uses (almost-)POSIX or Win32 headers, depending on the platform. * It uses a computation of the user time used on the CPU. For a wallclock time measure, see eoEvalTimeThrowException * * @ingroup Evaluation */ + +#include + +#ifdef __unix__ + +#include +#include + template< class EOT > class eoEvalUserTimeThrowException : public eoEvalFuncCounter< EOT > { @@ -58,7 +61,7 @@ public: if( current >= _max ) { throw eoMaxTimeException( current ); } else { - func(eo); + this->func(eo); } } } @@ -68,5 +71,41 @@ protected: struct rusage _usage; }; +#else +#ifdef _WINDOWS +//here _WINDOWS is defined + +#include + +template< class EOT > +class eoEvalUserTimeThrowException : public eoEvalFuncCounter< EOT > +{ +public: + eoEvalUserTimeThrowException( eoEvalFunc & func, const long max ) : eoEvalFuncCounter( func, "CPU-user"), _max(max) {} + + virtual void operator() ( EOT & eo ) + { + if( eo.invalid() ) { + FILETIME dummy; + GetProcessTimes(GetCurrentProcess(), &dummy, &dummy, &dummy, &_usage); + + ULARGE_INTEGER current; + current.LowPart = _usage.dwLowDateTime; + current.HighPart = _usage.dwHighDateTime; + if( current.QuadPart >= _max ) { + throw eoMaxTimeException( current.QuadPart ); + } else { + func(eo); + } + } + } + +protected: + const long _max; + FILETIME _usage; +}; + +#endif // _WINDOWS +#endif //__unix__ #endif // __EOEVALUSERTIMETHROWEXCEPTION_H__ -#endif // __UNIX__ +#endif //!defined(__unix__) && !defined(_WINDOWS) diff --git a/eo/src/eoFunctorStore.h b/eo/src/eoFunctorStore.h index c609637b..051daf2a 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 b3cb5b99..6a2618d9 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 371fdfd0..eb6be46f 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,268 +84,297 @@ 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 - if( it == end() ) - throw std::runtime_error("eoPop: Empty population, when calling best_element()."); - return (*it); - } + if( it == end() ) + throw std::runtime_error("eoPop: Empty population, when calling best_element()."); + 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 4fea77e5..823ac79c 100644 --- a/eo/src/eoProportionalCombinedOp.h +++ b/eo/src/eoProportionalCombinedOp.h @@ -186,12 +186,17 @@ 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 #pragma message "The use of the verbose parameter in eoPropCombinedQuadOp::add is deprecated and will be removed in the next release." eo::log << eo::warnings << "WARNING: the use of the verbose parameter in eoPropCombinedQuadOp::add is deprecated and will be removed in the next release." << std::endl; +#endif // !DEPRECATED_MESSAGES + add(_op,_rate); } + */ // addition of a true operator virtual void add(eoQuadOp & _op, const double _rate) @@ -199,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/eoRankMuSelect.h b/eo/src/eoRankMuSelect.h new file mode 100644 index 00000000..6e0a737e --- /dev/null +++ b/eo/src/eoRankMuSelect.h @@ -0,0 +1,54 @@ +/* +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) 2012 Thales group +*/ +/* +Authors: + Johann Dréo +*/ + + +#ifndef _eoRankMuSelect_h +#define _eoRankMuSelect_h + +#include "eoDetSelect.h" + +/** Selects the "Mu" bests individuals. + * + * Note: sorts the population before trucating it. + * + * @ingroup Selectors +*/ +template +class eoRankMuSelect : public eoDetSelect +{ +public : + // false, because mu is not a rate + eoRankMuSelect( unsigned int mu ) : eoDetSelect( mu, false ) {} + + void operator()(const eoPop& source, eoPop& dest) + { + eoPop tmp( source ); + tmp.sort(); + eoDetSelect::operator()( tmp, dest ); + } +}; + +#endif // !_eoRankMuselect_h diff --git a/eo/src/eoReduceSplit.h b/eo/src/eoReduceSplit.h index ce22d027..4b21aa25 100644 --- a/eo/src/eoReduceSplit.h +++ b/eo/src/eoReduceSplit.h @@ -104,7 +104,7 @@ public: unsigned eliminated = howMany(popSize); if (!eliminated) // nothing to do return ; - unsigned newsize = popSize - eliminated; + long newsize = static_cast(popSize) - static_cast(eliminated); if (newsize < 0) throw std::logic_error("eoLinearTruncateSplit: Cannot truncate to a larger size!\n"); diff --git a/eo/src/eoScalarFitnessAssembled.h b/eo/src/eoScalarFitnessAssembled.h index 95168ec6..50e9038d 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/eoBitOp.h b/eo/src/ga/eoBitOp.h index d1247020..15d77434 100644 --- a/eo/src/ga/eoBitOp.h +++ b/eo/src/ga/eoBitOp.h @@ -56,7 +56,7 @@ template class eoOneBitFlip: public eoMonOp bool operator()(Chrom& chrom) { unsigned i = eo::rng.random(chrom.size()); - chrom[i] = (chrom[i]) ? false : true; + chrom[i] = !chrom[i]; return true; } }; @@ -85,11 +85,11 @@ template class eoDetBitFlip: public eoMonOp */ bool operator()(Chrom& chrom) { - // does not check for duplicate: if someone volunteers .... + // for duplicate checking see eoDetSingleBitFlip for (unsigned k=0; k class eoDetBitFlip: public eoMonOp }; +/** eoDetSingleBitFlip --> changes exactly k bits with checking for duplicate +\class eoDetSingleBitFlip eoBitOp.h ga/eoBitOp.h +\ingroup bitstring +*/ + +template class eoDetSingleBitFlip: public eoMonOp +{ + public: + /** + * (Default) Constructor. + * @param _num_bit The number of bits to change + * default is one - equivalent to eoOneBitFlip then + */ + eoDetSingleBitFlip(const unsigned& _num_bit = 1): num_bit(_num_bit) {} + + /// The class name. + virtual std::string className() const { return "eoDetSingleBitFlip"; } + + /** + * Change num_bit bits. + * @param chrom The cromosome which one bit is going to be changed. + */ + bool operator()(Chrom& chrom) + { + std::vector< unsigned > selected; + + // check for duplicate + for (unsigned k=0; k classical mutation \class eoBitMutation eoBitOp.h ga/eoBitOp.h \ingroup bitstring diff --git a/eo/src/ga/make_continue_ga.cpp b/eo/src/ga/make_continue_ga.cpp index 1b25a0c8..fb4662c3 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 ce594903..20609488 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 4f9e69ef..3344a8d8 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 ea1b2005..fad4f756 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 8c46549f..2035a4f8 100644 --- a/eo/src/ga/make_op.h +++ b/eo/src/ga/make_op.h @@ -115,11 +115,11 @@ eoGenOp & do_make_op(eoParser& _parser, eoState& _state, eoInit& _init throw std::runtime_error("Invalid uRate"); // minimum check - bool bCross = true; + // bool bCross = true; // not used ? if (onePointRateParam.value()+twoPointsRateParam.value()+uRateParam.value()==0) { std::cerr << "Warning: no crossover" << std::endl; - bCross = false; + // bCross = false; } // Create the CombinedQuadOp @@ -156,17 +156,29 @@ 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 - bool bMut = true; + 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) { std::cerr << "Warning: no mutation" << std::endl; - bMut = false; + // bMut = false; } // Create the CombinedMonOp @@ -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 11ec105e..88737d91 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/pyeo/test/run_tests.sh b/eo/src/pyeo/test/run_tests.sh index b06c61b0..8a2ebca1 100755 --- a/eo/src/pyeo/test/run_tests.sh +++ b/eo/src/pyeo/test/run_tests.sh @@ -2,6 +2,6 @@ for i in *.py do - python $i > /dev/null + python2 $i > /dev/null done diff --git a/eo/src/utils/CMakeLists.txt b/eo/src/utils/CMakeLists.txt index 010c6d41..5224f652 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 5d49e589..f7fd0e55 100644 --- a/eo/src/utils/checkpointing +++ b/eo/src/utils/checkpointing @@ -1,3 +1,29 @@ +/* + ----------------------------------------------------------------------------- + checkpointing + + (c) Maarten Keijzer (mak@dhi.dk) and GeNeura Team, 1999, 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 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 + */ + +#ifndef _CHECKPOINTING_ +#define _CHECKPOINTING_ + #include #include #include @@ -10,6 +36,7 @@ #include #endif #include +#include #include #include #include @@ -21,3 +48,9 @@ // and make_help - any better suggestion to include it? void make_help(eoParser & _parser); + +#endif // !_CHECKPOINTING_ + +// Local Variables: +// mode: C++ +// End: diff --git a/eo/src/utils/eoFuncPtrStat.h b/eo/src/utils/eoFuncPtrStat.h index 316b7f42..c7728157 100644 --- a/eo/src/utils/eoFuncPtrStat.h +++ b/eo/src/utils/eoFuncPtrStat.h @@ -4,6 +4,8 @@ #include #include + + /** Wrapper to turn any stand-alone function and into an eoStat. * * The function should take an eoPop as argument. @@ -41,4 +43,38 @@ eoFuncPtrStat& makeFuncPtrStat( T (*func)(const eoPop&), eoFunctorS ); } +/** Wrapper to turn any stand-alone function and into an eoStat. + * + * The function should take an eoPop as argument. + * + * @ingroup Stats + */ +template +class eoFunctorStat : public eoStat +{ +public : + eoFunctorStat(eoUF< const eoPop&, T >& f, std::string _description = "functor") + : eoStat(T(), _description), func(f) + {} + + using eoStat::value; + + void operator()(const eoPop& pop) { + value() = func(pop); + } + +private: + eoUF< const eoPop&, T >& func; +}; + +/** + * @ingroup Stats + */ +template +eoFunctorStat& makeFunctorStat( eoUF< const eoPop&, T >& func, eoFunctorStore& store, std::string description = "func") { + return store.storeFunctor( + new eoFunctorStat( func, description) + ); +} + #endif diff --git a/eo/src/utils/eoLogger.cpp b/eo/src/utils/eoLogger.cpp index e478ba09..f052d795 100644 --- a/eo/src/utils/eoLogger.cpp +++ b/eo/src/utils/eoLogger.cpp @@ -194,8 +194,7 @@ int eoLogger::outbuf::overflow(int_type c) { if (_fd >= 0 && c != EOF) { - size_t num; - num = ::write(_fd, &c, 1); + ::write(_fd, &c, 1); } } return c; diff --git a/eo/src/utils/eoOStreamMonitor.cpp b/eo/src/utils/eoOStreamMonitor.cpp index 3365301e..6836f337 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 cb4c476a..982c954f 100644 --- a/eo/src/utils/eoOStreamMonitor.h +++ b/eo/src/utils/eoOStreamMonitor.h @@ -44,13 +44,17 @@ Authors: class eoOStreamMonitor : public eoMonitor { public : + /* 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) { - (void)_verbose; +#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 b47d3f82..cae5e8c4 100644 --- a/eo/src/utils/eoParallel.cpp +++ b/eo/src/utils/eoParallel.cpp @@ -25,7 +25,9 @@ Authors: */ +#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 de6f06e6..00000000 --- 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 984e7627..78223c35 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 00000000..745d21bd --- /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 00000000..9a89cb19 --- /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 d9d06d99..c6d38500 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 53c3a83d..256dcd96 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 a1979b5d..d886aed3 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 e3a5a624..9bfc296b 100644 --- a/eo/test/CMakeLists.txt +++ b/eo/test/CMakeLists.txt @@ -26,7 +26,7 @@ LINK_DIRECTORIES(${EO_BINARY_DIR}/lib) IF(WITH_MPI) LINK_DIRECTORIES(${MPI_DIR}/lib) - SET(CMAKE_CXX_COMPILER "${MPI_DIR}/bin/mpicxx") + SET(CMAKE_CXX_COMPILER "mpicxx") ENDIF() ###################################################################################### diff --git a/eo/test/mpi/CMakeLists.txt b/eo/test/mpi/CMakeLists.txt index 22734d44..d89f3ab3 100644 --- a/eo/test/mpi/CMakeLists.txt +++ b/eo/test/mpi/CMakeLists.txt @@ -38,7 +38,7 @@ FOREACH (test ${TEST_LIST}) SET ("T_${test}_SOURCES" "${test}.cpp") ENDFOREACH (test) -SET(CMAKE_CXX_COMPILER "${MPI_DIR}/bin/mpicxx") +SET(CMAKE_CXX_COMPILER "mpicxx") ADD_DEFINITIONS(-DWITH_MPI) IF(ENABLE_CMAKE_TESTING) diff --git a/eo/test/t-MGE-control.cpp b/eo/test/t-MGE-control.cpp index 240dd368..d2d4d224 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 a122b5e7..275847e1 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 842f5cd7..6ef1c874 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 d857dd82..2a36d0ee 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 a1d68087..d2f4cf3b 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" //----------------------------------------------------------------------------- diff --git a/website/index.html b/website/index.html index 09481644..8f8de867 100644 --- a/website/index.html +++ b/website/index.html @@ -19,6 +19,7 @@ + @@ -170,7 +172,7 @@

If you need immediate support or have any question, the best way to get answers is to subscribe to the mailing list and send your email to eodev-main@lists.sourceforge.net

-

Alternatively, you can join us on the official chatroom. If your browser supports it, you can simply click on the button on the bottom of the current webpage and enter your nick. Else, you can try our webchat interface. If you already have an XMPP account (Jabber or Google Talk, for example), you can directly connect to the eo@chat.jabberfr.org multi-user chatroom with your favorite client.

+

Alternatively, you can join us on the official chatroom. You can try our webchat interface, or if you already use IRC, you can directly connect to the irc.freenode.org/#paradiseo multi-user chatroom with your favorite client.

If you want to know how to help us to improve EO, the easiest way is to click on the following button: