diff --git a/edo/src/edo b/edo/src/edo index 33c18b1c7..816ad4211 100644 --- a/edo/src/edo +++ b/edo/src/edo @@ -39,6 +39,7 @@ Authors: #include "edoNormalMulti.h" #include "edoNormalAdaptive.h" #include "edoBinomial.h" +#include "edoBinomialMulti.h" #include "edoEstimator.h" #include "edoEstimatorUniform.h" @@ -47,6 +48,7 @@ Authors: #include "edoEstimatorAdaptive.h" #include "edoEstimatorNormalAdaptive.h" #include "edoEstimatorBinomial.h" +#include "edoEstimatorBinomialMulti.h" #include "edoModifier.h" #include "edoModifierDispersion.h" @@ -61,6 +63,7 @@ Authors: #include "edoSamplerNormalMulti.h" #include "edoSamplerNormalAdaptive.h" #include "edoSamplerBinomial.h" +#include "edoSamplerBinomialMulti.h" #include "edoVectorBounds.h" diff --git a/edo/src/edoBinomialMulti.h b/edo/src/edoBinomialMulti.h new file mode 100644 index 000000000..2670ddfa3 --- /dev/null +++ b/edo/src/edoBinomialMulti.h @@ -0,0 +1,59 @@ +/* +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) 2013 Thales group +*/ +/* +Authors: + Johann Dréo +*/ + +#ifndef _edoBinomialMulti_h +#define _edoBinomialMulti_h + +#include "edoBinomial.h" + +#ifdef WITH_EIGEN // FIXME: provide an uBLAS implementation +#include + +/** A 2D binomial distribution modeled as a matrix. + * + * i.e. a container of binomial distribution. + * + * @ingroup Distributions + * @ingroup Binomial + */ +template +class edoBinomialMulti : public edoDistrib, public T +{ +public: + /** This constructor takes an initial matrix of probabilities. + * Use it if you have prior knowledge. + */ + edoBinomialMulti( T initial_probas ) + : T(initial_probas) {} + + /** Constructor without any assumption. + */ + edoBinomialMulti() {} +}; + +#endif // WITH_EIGEN +#endif // !_edoBinomialMulti_h + diff --git a/edo/src/edoEstimatorBinomialMulti.h b/edo/src/edoEstimatorBinomialMulti.h new file mode 100644 index 000000000..189d7f973 --- /dev/null +++ b/edo/src/edoEstimatorBinomialMulti.h @@ -0,0 +1,97 @@ +/* +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) 2013 Thales group +*/ +/* +Authors: + Johann Dréo +*/ + +#ifndef _edoEstimatorBinomialMulti_h +#define _edoEstimatorBinomialMulti_h + +#include "edoBinomialMulti.h" +#include "edoEstimator.h" + +#ifdef WITH_EIGEN +#include + +/** An estimator for edoBinomialMulti + * + * @ingroup Estimators + * @ingroup Binomial + */ +template< class EOT, class D = edoBinomialMulti > +class edoEstimatorBinomialMulti : public edoEstimator +{ + protected: + D eot2d( EOT from, unsigned int rows, unsigned int cols ) // FIXME maybe more elegant with Eigen::Map? + { + assert( rows > 0 ); + assert( from.size() == rows ); + assert( cols > 0 ); + + D to( Eigen::MatrixXd(rows, cols) ); + for( unsigned int i=0; i < rows; ++i ) { + assert( from[i].size() == cols ); + for( unsigned int j=0; j < cols; ++j ) { + to(i,j) = from[i][j]; + } + } + + return to; + } + + public: + /** The expected EOT interface is the same as an Eigen3::MatrixXd. + */ + D operator()( eoPop& pop ) + { + unsigned int popsize = pop.size(); + assert(popsize > 0); + + unsigned int rows = pop[0].size(); + assert( rows > 0 ); + unsigned int cols = pop[0][0].size(); + assert( cols > 0 ); + + D probas( D::Zero(rows, cols) ); + + // We still need a loop over pop, because it is an eoVector + for (unsigned int i = 0; i < popsize; ++i) { + D indiv = eot2d( pop[i], rows, cols ); + assert( indiv.rows() == rows && indiv.cols() == cols ); + + // the EOT matrix should be filled with 1 or 0 only + assert( indiv.sum() <= popsize ); + + probas += indiv / popsize; + + // sum and scalar product, no size pb expected + assert( probas.rows() == rows && probas.cols() == cols ); + } + + return probas; + } +}; + +#endif // WITH_EIGEN +#endif // !_edoEstimatorBinomialMulti_h + diff --git a/edo/src/edoSamplerBinomialMulti.h b/edo/src/edoSamplerBinomialMulti.h new file mode 100644 index 000000000..f0e73d699 --- /dev/null +++ b/edo/src/edoSamplerBinomialMulti.h @@ -0,0 +1,74 @@ +/* +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) 2013 Thales group +*/ +/* +Authors: + Johann Dréo +*/ + +#ifndef _edoSamplerBinomialMulti_h +#define _edoSamplerBinomialMulti_h + +#include + +#include "edoSampler.h" +#include "edoBinomialMulti.h" + +#ifdef WITH_EIGEN +#include + +/** A sampler for an edoBinomialMulti distribution. + * + * @ingroup Samplers + * @ingroup Binomial + */ +template< class EOT, class D = edoBinomialMulti > +class edoSamplerBinomialMulti : public edoSampler +{ +public: + EOT sample( D& distrib ) + { + unsigned int rows = distrib.rows(); + unsigned int cols = distrib.cols(); + assert(rows > 0); + assert(cols > 0); + + // The point we want to draw + // x = {x1, x2, ..., xn} + EOT solution; + + // Sampling all dimensions + for( unsigned int i = 0; i < rows; ++i ) { + typename EOT::AtomType vec; + for( unsigned int j = 0; j < cols; ++j ) { + // Toss a coin, biased by the proba of being 1. + vec.push_back( rng.flip( distrib(i,j) ) ); + } + solution.push_back( vec ); + } + + return solution; + } +}; + +#endif // WITH_EIGEN +#endif // !_edoSamplerBinomialMulti_h + diff --git a/edo/test/CMakeLists.txt b/edo/test/CMakeLists.txt index 577c0bd31..294a8e7f5 100644 --- a/edo/test/CMakeLists.txt +++ b/edo/test/CMakeLists.txt @@ -41,6 +41,7 @@ set(SOURCES # t-dispatcher-round t-repairer-modulo t-binomial + t-binomialmulti ) foreach(current ${SOURCES}) diff --git a/edo/test/t-binomialmulti.cpp b/edo/test/t-binomialmulti.cpp new file mode 100644 index 000000000..3c995e343 --- /dev/null +++ b/edo/test/t-binomialmulti.cpp @@ -0,0 +1,87 @@ +/* +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) 2013 Thales group +*/ +/* +Authors: + Johann Dréo +*/ + +#include +#include +#include +#include + +#include +#include +#include // for Bools + + +#ifdef WITH_EIGEN +#include + +// NOTE: a typedef on eoVector does not work, because of readFrom on a vector AtomType +// typedef eoVector > Bools; +class Bools : public std::vector >, public EO +{ + public: + typedef std::vector AtomType; +}; + +int main(int ac, char** av) +{ + eoParser parser(ac, av); + + std::string section("Algorithm parameters"); + unsigned int popsize = parser.createParam((unsigned int)100000, "popSize", "Population Size", 'P', section).value(); // P + unsigned int rows = parser.createParam((unsigned int)2, "lines", "Lines number", 'l', section).value(); // l + unsigned int cols = parser.createParam((unsigned int)3, "columns", "Columns number", 'c', section).value(); // c + double proba = parser.createParam((double)0.5, "proba", "Probability to estimate", 'b', section).value(); // b + + if( parser.userNeedsHelp() ) { + parser.printHelp(std::cout); + exit(1); + } + + make_help(parser); + + std::cout << "Init distrib" << std::endl; + Eigen::MatrixXd initd = Eigen::MatrixXd::Constant(rows,cols,proba); + edoBinomialMulti distrib( initd ); + std::cout << distrib << std::endl; + + edoEstimatorBinomialMulti estimate; + edoSamplerBinomialMulti sample; + + std::cout << "Sample a pop from the init distrib" << std::endl; + eoPop pop; pop.reserve(popsize); + for( unsigned int i=0; i < popsize; ++i ) { + pop.push_back( sample( distrib ) ); + } + + std::cout << "Estimate a distribution from the sampled pop" << std::endl; + distrib = estimate( pop ); + std::cout << distrib << std::endl; + + std::cout << "Estimated initial proba = " << distrib.mean() << std::endl; +} + + +#endif // WITH_EIGEN