From 78eb19b2eeb640089bd32af5f203ea4946398f1d Mon Sep 17 00:00:00 2001 From: Jean-Philippe ARGAUD Date: Thu, 8 Dec 2016 07:38:38 +0100 Subject: [PATCH] Documentation and DFO method corrections --- ...f_algorithm_DerivativeFreeOptimization.rst | 13 ++++---- ...f_algorithm_DerivativeFreeOptimization.rst | 12 ++++--- .../DerivativeFreeOptimization.py | 33 ++++++++++++++++++- 3 files changed, 46 insertions(+), 12 deletions(-) diff --git a/doc/en/ref_algorithm_DerivativeFreeOptimization.rst b/doc/en/ref_algorithm_DerivativeFreeOptimization.rst index 3971ee6..2415e41 100644 --- a/doc/en/ref_algorithm_DerivativeFreeOptimization.rst +++ b/doc/en/ref_algorithm_DerivativeFreeOptimization.rst @@ -111,12 +111,13 @@ The options of the algorithm are the following: This key allows to choose the optimization minimizer. The default choice is "POWELL", and the possible ones are "POWELL" (modified Powell unconstrained minimizer, see [Powell]_), "SIMPLEX" (simplex or Nelder-Mead unconstrained - minimizer, see [Nelder]_). It is recommended to stay with the default. - Remark: the default "POWELL" method perform a dual outer/inner loops - optimization, leading then to less control on the cost function evaluation - number because it is the outer loop limit than is controled. If precise - control on this cost function evaluation number is required, choose the - "SIMPLEX" one. + minimizer, see [Nelder]_), "COBYLA" (constrained optimization by linear + approximation). It is recommended to stay with the default when there is no + bounds, and to choose "COBYLA" when there are bounds. Remark: the default + "POWELL" method perform a dual outer/inner loops optimization, leading then + to less control on the cost function evaluation number because it is the + outer loop limit than is controled. If precise control on this cost function + evaluation number is required, choose the "SIMPLEX" or the "COBYLA" one. Example : ``{"Minimizer":"POWELL"}`` diff --git a/doc/fr/ref_algorithm_DerivativeFreeOptimization.rst b/doc/fr/ref_algorithm_DerivativeFreeOptimization.rst index bd12938..20e9ede 100644 --- a/doc/fr/ref_algorithm_DerivativeFreeOptimization.rst +++ b/doc/fr/ref_algorithm_DerivativeFreeOptimization.rst @@ -114,12 +114,14 @@ Les options de l'algorithme sont les suivantes: défaut est "POWELL", et les choix possibles sont "POWELL" (minimisation sans contraintes de type Powell modifiée, voir [Powell]_), "SIMPLEX" (minimisation sans contraintes de type simplexe ou Nelder-Mead, voir - [Nelder]_). Il est conseillé de conserver la valeur par défaut. Remarque : - la méthode par défaut "POWELL" effectue une optimisation par boucles - imbriquées interne/externe, conduisant ainsi à un contrôle relaché du nombre + [Nelder]_), "COBYLA" (minimisation avec contraintes par approximation + linéaire). Il est conseillé de conserver la valeur par défaut lorsqu'il n'y + a pas de bornes, et de passer à "COBYLA" en cas de bornes. Remarque : la + méthode par défaut "POWELL" effectue une optimisation par boucles imbriquées + interne/externe, conduisant ainsi à un contrôle relaché du nombre d'évaluations de la fonctionnelle à optimiser. Si un contrôle précis du - nombre d'évaluations de cette fonctionnelle est requis, il faut choisir le - "SIMPLEX". + nombre d'évaluations de cette fonctionnelle est requis, il faut choisir + "SIMPLEX" ou "COBYLA". Exemple : ``{"Minimizer":"POWELL"}`` diff --git a/src/daComposant/daAlgorithms/DerivativeFreeOptimization.py b/src/daComposant/daAlgorithms/DerivativeFreeOptimization.py index e927420..b3649ba 100644 --- a/src/daComposant/daAlgorithms/DerivativeFreeOptimization.py +++ b/src/daComposant/daAlgorithms/DerivativeFreeOptimization.py @@ -33,7 +33,7 @@ class ElementaryAlgorithm(BasicObjects.Algorithm): default = "POWELL", typecast = str, message = "Minimiseur utilisé", - listval = ["POWELL", "SIMPLEX"], + listval = ["POWELL", "SIMPLEX", "COBYLA"], ) self.defineRequiredParameter( name = "MaximumNumberOfSteps", @@ -85,6 +85,10 @@ class ElementaryAlgorithm(BasicObjects.Algorithm): message = "Liste de calculs supplémentaires à stocker et/ou effectuer", listval = ["CurrentState", "CostFunctionJ", "CostFunctionJb", "CostFunctionJo", "CostFunctionJAtCurrentOptimum", "CurrentOptimum", "IndexOfOptimum", "InnovationAtCurrentState", "BMA", "OMA", "OMB", "SimulatedObservationAtBackground", "SimulatedObservationAtCurrentOptimum", "SimulatedObservationAtCurrentState", "SimulatedObservationAtOptimum"] ) + self.defineRequiredParameter( # Pas de type + name = "Bounds", + message = "Liste des valeurs de bornes", + ) def run(self, Xb=None, Y=None, U=None, HO=None, EM=None, CM=None, R=None, B=None, Q=None, Parameters=None): self._pre_run() @@ -97,6 +101,12 @@ class ElementaryAlgorithm(BasicObjects.Algorithm): # ---------------------- self.setParameters(Parameters) # + if self._parameters.has_key("Bounds") and (type(self._parameters["Bounds"]) is type([]) or type(self._parameters["Bounds"]) is type(())) and (len(self._parameters["Bounds"]) > 0): + Bounds = self._parameters["Bounds"] + logging.debug("%s Prise en compte des bornes effectuee"%(self._name,)) + else: + Bounds = None + # # Opérateurs # ---------- Hm = HO["Direct"].appliedTo @@ -194,6 +204,27 @@ class ElementaryAlgorithm(BasicObjects.Algorithm): full_output = True, disp = self.__disp, ) + elif self._parameters["Minimizer"] == "COBYLA": + def make_constraints(bounds): + constraints = [] + for (i,(a,b)) in enumerate(bounds): + lower = lambda x: x[i] - a + upper = lambda x: b - x[i] + constraints = constraints + [lower] + [upper] + return constraints + if Bounds is None: + raise ValueError("Bounds have to be given for all axes as a list of lower/upper pairs!") + Minimum = scipy.optimize.fmin_cobyla( + func = CostFunction, + x0 = Xini, + cons = make_constraints( Bounds ), + consargs = (), # To avoid extra-args + maxfun = self._parameters["MaximumNumberOfFunctionEvaluations"]-1, + rhobeg = 1.0, + rhoend = self._parameters["StateVariationTolerance"], + catol = 2.*self._parameters["StateVariationTolerance"], + disp = self.__disp, + ) else: raise ValueError("Error in Minimizer name: %s"%self._parameters["Minimizer"]) # -- 2.39.2