diff --git a/edo/src/edo b/edo/src/edo index 1668a2ee2..a6a0861b5 100644 --- a/edo/src/edo +++ b/edo/src/edo @@ -78,6 +78,9 @@ Authors: #include "edoBounderUniform.h" #include "edoContinue.h" +#include "edoCombinedContinue.h" +#include "edoContAdaptiveIllCond.h" +#include "edoContAdaptiveFinite.h" #include "utils/edoCheckPoint.h" #include "utils/edoStat.h" diff --git a/edo/src/edoCombinedContinue.h b/edo/src/edoCombinedContinue.h new file mode 100644 index 000000000..54aacc143 --- /dev/null +++ b/edo/src/edoCombinedContinue.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) 2020 Thales group +*/ +/* +Authors: + Johann Dréo +*/ + +#ifndef _edoCombinedContinue_h +#define _edoCombinedContinue_h + +#include +#include + +/** Combine several EDO continuators in a single one. + * + * Return true if any of the managed continuator ask for a stop. + * + * @see edoContinue + * + * @ingroup Continuators + * @ingroup Core + */ +template +class edoCombinedContinue : public edoContinue, public std::vector*> +{ +public: + edoCombinedContinue( edoContinue& cont ) : + edoContinue(), + std::vector*>(1,&cont) + { } + + edoCombinedContinue( std::vector*> conts ) : + edoContinue(), + std::vector*>(conts) + { } + + void add( edoContinue& cont) + { + this->push_back(&cont); + } + + bool operator()(const D& distrib) + { + for(const auto cont : *this) { + if( not (*cont)(distrib)) { + return false; + } + } + return true; + } + + virtual std::string className() const { return "edoCombinedContinue"; } +}; + +#endif // !_edoCombinedContinue_h diff --git a/edo/src/edoContAdaptiveFinite.h b/edo/src/edoContAdaptiveFinite.h new file mode 100644 index 000000000..a01775759 --- /dev/null +++ b/edo/src/edoContAdaptiveFinite.h @@ -0,0 +1,95 @@ +/* +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) 2020 Thales group +*/ +/* +Authors: + Johann Dréo +*/ + +#ifndef _edoContAdaptiveFinite_h +#define _edoContAdaptiveFinite_h + +#include "edoContinue.h" + +/** A continuator that check if any element in the parameters + * of an edoNormalAdaptive distribution are finite + * + * If any element of any parameter is infinity or NaN (Not A Number), + * it will ask for a stop. + * + * @ingroup Continuators + */ +template +class edoContAdaptiveFinite : public edoContinue +{ +public: + using EOType = typename D::EOType; + using Matrix = typename D::Matrix; + using Vector = typename D::Vector; + + bool operator()(const D& d) + { + // Try to finite_check in most probably ill-conditioned order. + return finite_check(d.covar()) + and finite_check(d.path_covar()) + and finite_check(d.coord_sys()) + and finite_check(d.scaling()) + and finite_check(d.path_sigma()) + and finite_check(d.sigma()) + ; + } + + virtual std::string className() const { return "edoContAdaptiveFinite"; } + +protected: + bool finite_check(const Matrix& mat) const + { + for(long i=0; i +*/ + +#ifndef _edoContAdaptiveIllCond_h +#define _edoContAdaptiveIllCond_h + +#ifdef WITH_EIGEN + +#include + +#include "edoContinue.h" + +/** A continuator that check if any matrix among the parameters + * of an edoNormalAdaptive distribution are ill-conditioned. + * + * If the condition number of the covariance matrix + * or the coordinate system matrix are strictly greater + * than the threshold given at construction, it will ask for a stop. + * + * @ingroup Continuators + */ +template +class edoContAdaptiveIllCond : public edoContinue +{ +public: + using EOType = typename D::EOType; + using Matrix = typename D::Matrix; + using Vector = typename D::Vector; + + edoContAdaptiveIllCond( double threshold = 1e6) : + _threshold(threshold) + { } + + bool operator()(const D& d) + { + if( condition(d.covar()) > _threshold + or condition(d.coord_sys()) > _threshold ) { + return false; + } else { + return true; + } + } + + virtual std::string className() const { return "edoContAdaptiveIllCond"; } + +public: + // Public function in case someone would want to dimensionate the condition threshold. + //! Returns the condition number + bool condition(const Matrix& mat) const + { + Eigen::JacobiSVD svd(mat); + return svd.singularValues()(0) / svd.singularValues()(svd.singularValues().size()-1); + } + + const double _threshold; +}; + +#endif // WITH_EIGEN + +#endif diff --git a/edo/src/edoContinue.h b/edo/src/edoContinue.h index 8089601e2..6540b9b0b 100644 --- a/edo/src/edoContinue.h +++ b/edo/src/edoContinue.h @@ -25,8 +25,8 @@ Authors: Caner Candan */ -#ifndef _doContinue_h -#define _doContinue_h +#ifndef _edoContinue_h +#define _edoContinue_h #include #include @@ -44,20 +44,18 @@ class edoContinue : public eoUF< const D&, bool >, public eoPersistent public: virtual std::string className(void) const { return "edoContinue"; } - void readFrom(std::istream&) - { - /* It should be implemented by subclasses ! */ - } + // May be implemented by subclasses if persistent interface needed + virtual void readFrom(std::istream&) + { } - void printOn(std::ostream&) const - { - /* It should be implemented by subclasses ! */ - } + virtual void printOn(std::ostream&) const + { } }; template < typename D > class edoDummyContinue : public edoContinue< D > { +public: bool operator()(const D&){ return true; } virtual std::string className() const { return "edoDummyContinue"; }