From: Jean-Philippe ARGAUD Date: Mon, 29 Jan 2018 20:16:25 +0000 (+0100) Subject: Minor source/doc coherency corrections for variable order and paths X-Git-Tag: V8_5_0rc1~20 X-Git-Url: http://git.salome-platform.org/gitweb/?a=commitdiff_plain;h=1d4fa19cd22d9b3cb8582e2fdf9313161f1b72e4;p=modules%2Fadao.git Minor source/doc coherency corrections for variable order and paths --- diff --git a/src/daComposant/Makefile.am b/src/daComposant/Makefile.am index 6516b38..5d5b2b2 100644 --- a/src/daComposant/Makefile.am +++ b/src/daComposant/Makefile.am @@ -22,7 +22,7 @@ include $(top_srcdir)/adm_local/make_common_starter.am -EXTRA_DIST = daCore daAlgorithms daDiagnostics daExternals daMatrices daNumerics +EXTRA_DIST = daCore daAlgorithms daDiagnostics daNumerics DIR = $(top_srcdir)/src/daComposant/ diff --git a/src/daComposant/daAlgorithms/mmqr.py b/src/daComposant/daAlgorithms/mmqr.py new file mode 100644 index 0000000..02fcc65 --- /dev/null +++ b/src/daComposant/daAlgorithms/mmqr.py @@ -0,0 +1,108 @@ +# -*- coding: utf-8 -*- +# +# Copyright (C) 2008-2018 EDF R&D +# +# 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. +# +# 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 +# +# See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com +# +# Author: Jean-Philippe Argaud, jean-philippe.argaud@edf.fr, EDF R&D + +__doc__ = """ + Implémentation informatique de l'algorithme MMQR, basée sur la publication : + David R. Hunter, Kenneth Lange, "Quantile Regression via an MM Algorithm", + Journal of Computational and Graphical Statistics, 9, 1, pp.60-77, 2000. +""" +__author__ = "Jean-Philippe ARGAUD" + +import sys, math +from numpy import array, matrix, asarray, asmatrix +from numpy import sum, dot, linalg, ravel, max, min, hstack, argmin, argmax + +# ============================================================================== +def mmqr( + func = None, + x0 = None, + fprime = None, + bounds = None, + quantile = 0.5, + maxfun = 15000, + toler = 1.e-06, + y = None, + ): + # + # Recuperation des donnees et informations initiales + # -------------------------------------------------- + variables = asmatrix(ravel( x0 )) + mesures = asmatrix(ravel( y )).T + increment = sys.float_info[0] + p = len(variables.flat) + n = len(mesures.flat) + quantile = float(quantile) + # + # Calcul des parametres du MM + # --------------------------- + tn = float(toler) / n + e0 = -tn / math.log(tn) + epsilon = (e0-tn)/(1+math.log(e0)) + # + # Calculs d'initialisation + # ------------------------ + residus = ravel( mesures - func( variables ) ) + poids = asarray( 1./(epsilon+abs(residus)) ) + veps = 1. - 2. * quantile - residus * poids + lastsurrogate = -sum(residus*veps) - (1.-2.*quantile)*sum(residus) + iteration = 0 + # + # Recherche iterative + # ------------------- + while (increment > toler) and (iteration < maxfun) : + iteration += 1 + # + Derivees = array(fprime(variables)) + Derivees = Derivees.reshape(n,p) # Necessaire pour remettre en place la matrice si elle passe par des tuyaux YACS + DeriveesT = array(matrix(Derivees).T) + M = dot( DeriveesT , (array(matrix(p*[poids,]).T)*Derivees) ) + SM = dot( DeriveesT , veps ).T + step = - linalg.lstsq( M, SM )[0] + # + variables = variables + step + if bounds is not None: + while( (variables < ravel(asmatrix(bounds)[:,0])).any() or (variables > ravel(asmatrix(bounds)[:,1])).any() ): + step = step/2. + variables = variables - step + residus = ravel( mesures - func(variables) ) + surrogate = sum(residus**2 * poids) + (4.*quantile-2.) * sum(residus) + # + while ( (surrogate > lastsurrogate) and ( max(list(abs(step))) > 1.e-16 ) ) : + step = step/2. + variables = variables - step + residus = ravel( mesures-func(variables) ) + surrogate = sum(residus**2 * poids) + (4.*quantile-2.) * sum(residus) + # + increment = lastsurrogate-surrogate + poids = 1./(epsilon+abs(residus)) + veps = 1. - 2. * quantile - residus * poids + lastsurrogate = -sum(residus * veps) - (1.-2.*quantile)*sum(residus) + # + # Mesure d'écart : q*Sum(residus)-sum(residus negatifs) + # ---------------- + Ecart = quantile * sum(residus) - sum( residus[residus<0] ) + # + return variables, Ecart, [n,p,iteration,increment,0] + +# ============================================================================== +if __name__ == "__main__": + print('\n AUTODIAGNOSTIC \n') diff --git a/src/daComposant/daCore/Aidsm.py b/src/daComposant/daCore/Aidsm.py index 369e263..c5f0da2 100644 --- a/src/daComposant/daCore/Aidsm.py +++ b/src/daComposant/daCore/Aidsm.py @@ -113,11 +113,11 @@ class Aidsm(object): try: if Concept in ("Background", "CheckingPoint", "ControlInput", "Observation", "Controls"): commande = getattr(self,"set"+Concept) - commande(Vector, VectorSerie, Script, Scheduler, Stored, Checked ) + commande(Vector, VectorSerie, Script, Stored, Scheduler, Checked ) elif Concept in ("BackgroundError", "ObservationError", "EvolutionError"): commande = getattr(self,"set"+Concept) commande(Matrix, ScalarSparseMatrix, DiagonalSparseMatrix, - ObjectMatrix, Script, Stored, Checked ) + Script, Stored, ObjectMatrix, Checked ) elif Concept == "AlgorithmParameters": self.setAlgorithmParameters( Algorithm, Parameters, Script ) elif Concept == "Debug": @@ -125,18 +125,18 @@ class Aidsm(object): elif Concept == "NoDebug": self.setNoDebug() elif Concept == "Observer": - self.setObserver( Variable, Template, String, Script, ObjectFunction, Scheduler, Info ) + self.setObserver( Variable, Template, String, Script, Info, ObjectFunction, Scheduler ) elif Concept == "Diagnostic": self.setDiagnostic( Diagnostic, Identifier, Parameters, Script, Unit, BaseType ) elif Concept == "ObservationOperator": self.setObservationOperator( Matrix, OneFunction, ThreeFunctions, AppliedInXb, - Parameters, Script, AvoidRC, Stored, Checked ) + Parameters, Script, Stored, AvoidRC, Checked ) elif Concept in ("EvolutionModel", "ControlModel"): commande = getattr(self,"set"+Concept) commande( Matrix, OneFunction, ThreeFunctions, - Parameters, Script, Scheduler, AvoidRC, Stored, Checked ) + Parameters, Script, Scheduler, Stored, AvoidRC, Checked ) else: raise ValueError("the variable named '%s' is not allowed."%str(Concept)) @@ -154,8 +154,8 @@ class Aidsm(object): Vector = None, VectorSerie = None, Script = None, - Scheduler = None, Stored = False, + Scheduler = None, Checked = False): "Definition d'un concept de calcul" Concept = "Background" @@ -176,8 +176,8 @@ class Aidsm(object): Vector = None, VectorSerie = None, Script = None, - Scheduler = None, Stored = False, + Scheduler = None, Checked = False): "Definition d'un concept de calcul" Concept = "CheckingPoint" @@ -198,8 +198,8 @@ class Aidsm(object): Vector = None, VectorSerie = None, Script = None, - Scheduler = None, Stored = False, + Scheduler = None, Checked = False): "Definition d'un concept de calcul" Concept = "ControlInput" @@ -220,8 +220,8 @@ class Aidsm(object): Vector = None, VectorSerie = None, Script = None, - Scheduler = None, Stored = False, + Scheduler = None, Checked = False): "Definition d'un concept de calcul" Concept = "Observation" @@ -242,8 +242,8 @@ class Aidsm(object): Vector = (), # Valeur par defaut pour un vecteur vide VectorSerie = None, Script = None, - Scheduler = None, Stored = False, + Scheduler = None, Checked = False): "Definition d'un concept de calcul" Concept = "Controls" @@ -264,9 +264,9 @@ class Aidsm(object): Matrix = None, ScalarSparseMatrix = None, DiagonalSparseMatrix = None, - ObjectMatrix = None, Script = None, Stored = False, + ObjectMatrix = None, Checked = False): "Definition d'un concept de calcul" Concept = "BackgroundError" @@ -288,9 +288,9 @@ class Aidsm(object): Matrix = None, ScalarSparseMatrix = None, DiagonalSparseMatrix = None, - ObjectMatrix = None, Script = None, Stored = False, + ObjectMatrix = None, Checked = False): "Definition d'un concept de calcul" Concept = "ObservationError" @@ -312,9 +312,9 @@ class Aidsm(object): Matrix = None, ScalarSparseMatrix = None, DiagonalSparseMatrix = None, - ObjectMatrix = None, Script = None, Stored = False, + ObjectMatrix = None, Checked = False): "Definition d'un concept de calcul" Concept = "EvolutionError" @@ -339,8 +339,8 @@ class Aidsm(object): AppliedInXb = None, Parameters = None, Script = None, - AvoidRC = True, Stored = False, + AvoidRC = True, Checked = False): "Definition d'un concept de calcul" Concept = "ObservationOperator" @@ -367,9 +367,9 @@ class Aidsm(object): ThreeFunctions = None, Parameters = None, Script = None, + Stored = False, Scheduler = None, AvoidRC = True, - Stored = False, Checked = False): "Definition d'un concept de calcul" Concept = "EvolutionModel" @@ -396,9 +396,9 @@ class Aidsm(object): ThreeFunctions = None, Parameters = None, Script = None, + Stored = False, Scheduler = None, AvoidRC = True, - Stored = False, Checked = False): "Definition d'un concept de calcul" Concept = "ControlModel" @@ -469,9 +469,9 @@ class Aidsm(object): Template = None, String = None, Script = None, + Info = None, ObjectFunction = None, - Scheduler = None, - Info = None): + Scheduler = None): "Definition d'un concept de calcul" Concept = "Observer" self.__case.register("set"+Concept, dir(), locals()) @@ -602,11 +602,15 @@ class Aidsm(object): """ files = [] for directory in sys.path: - if os.path.isdir(os.path.join(directory,"daAlgorithms")): - for fname in os.listdir(os.path.join(directory,"daAlgorithms")): - root, ext = os.path.splitext(fname) - if ext == '.py' and root != '__init__': - files.append(root) + trypath = os.path.join(directory,"daAlgorithms") + if os.path.isdir(trypath): + for fname in os.listdir(trypath): + if os.path.isfile(os.path.join(trypath,fname)): + fc = open(os.path.join(trypath,fname)).read() + iselal = bool("class ElementaryAlgorithm" in fc) + root, ext = os.path.splitext(fname) + if iselal and ext == '.py' and root != '__init__': + files.append(root) files.sort() return files diff --git a/src/daComposant/daCore/BasicObjects.py b/src/daComposant/daCore/BasicObjects.py index 427f4c4..62cc351 100644 --- a/src/daComposant/daCore/BasicObjects.py +++ b/src/daComposant/daCore/BasicObjects.py @@ -1068,8 +1068,7 @@ class AlgorithmAndParameters(object): """ Permet de sélectionner l'algorithme à utiliser pour mener à bien l'étude d'assimilation. L'argument est un champ caractère se rapportant au nom - d'un fichier contenu dans "../daAlgorithms" et réalisant l'opération - d'assimilation sur les arguments fixes. + d'un algorithme réalisant l'opération sur les arguments fixes. """ if choice is None: raise ValueError("Error: algorithm choice has to be given") @@ -1084,13 +1083,15 @@ class AlgorithmAndParameters(object): if os.path.isfile(os.path.join(directory, daDirectory, str(choice)+'.py')): module_path = os.path.abspath(os.path.join(directory, daDirectory)) if module_path is None: - raise ImportError("No algorithm module named \"%s\" was found in a \"%s\" subdirectory\n The search path is %s"%(choice, daDirectory, sys.path)) + raise ImportError("No algorithm module named \"%s\" has been found in the search path.\n The search path is %s"%(choice, sys.path)) # # Importe le fichier complet comme un module # ------------------------------------------ try: sys_path_tmp = sys.path ; sys.path.insert(0,module_path) self.__algorithmFile = __import__(str(choice), globals(), locals(), []) + if not hasattr(self.__algorithmFile, "ElementaryAlgorithm"): + raise ImportError("this module does not define a valid elementary algorithm.") self.__algorithmName = str(choice) sys.path = sys_path_tmp ; del sys_path_tmp except ImportError as e: @@ -2134,15 +2135,11 @@ class _YACSViewer(GenericCaseViewer): GenericCaseViewer.__init__(self, __name, __objname, __content) self.__internalSCD = _SCDViewer(__name, __objname, __content) self._append = self.__internalSCD._append - def dump(self, __filename=None): + def dump(self, __filename=None, __convertSCDinMemory=True): "Restitution normalisée des commandes" self.__internalSCD._finalize() # ----- - if __filename is not None: - __file = os.path.abspath(__filename) - __SCDfile = __file[:__file.rfind(".")] + '_SCD.py' - __SCDdump = self.__internalSCD.dump(__SCDfile) - else: + if __filename is None: raise ValueError("A file name has to be given for YACS XML output.") # ----- if not PlatformInfo.has_salome or \ @@ -2150,7 +2147,17 @@ class _YACSViewer(GenericCaseViewer): raise ImportError("\n\n"+\ "Unable to get SALOME or ADAO environnement variables.\n"+\ "Please load the right environnement before trying to use it.\n") + elif __convertSCDinMemory: + __file = os.path.abspath(__filename) + __SCDdump = self.__internalSCD.dump() + if os.path.isfile(__file) or os.path.islink(__file): + os.remove(__file) + from daYacsSchemaCreator.run import create_schema_from_content + create_schema_from_content(__SCDdump, __file) else: + __file = os.path.abspath(__filename) + __SCDfile = __file[:__file.rfind(".")] + '_SCD.py' + __SCDdump = self.__internalSCD.dump(__SCDfile) if os.path.isfile(__file) or os.path.islink(__file): os.remove(__file) __converterExe = os.path.join(os.environ["ADAO_ROOT_DIR"], "bin/salome", "AdaoYacsSchemaCreator.py") @@ -2158,15 +2165,19 @@ class _YACSViewer(GenericCaseViewer): import subprocess __p = subprocess.Popen(__args) (__stdoutdata, __stderrdata) = __p.communicate() - if not os.path.exists(__file): - __msg = "An error occured during the ADAO YACS Schema build.\n" - __msg += "Creator applied on the input file:\n" - __msg += " %s\n"%__SCDfile - __msg += "If SALOME GUI is launched by command line, see errors\n" - __msg += "details in your terminal.\n" - raise ValueError(__msg) + __p.terminate() os.remove(__SCDfile) # ----- + if not os.path.exists(__file): + # logging.debug("-- Error YacsSchemaCreator with convert SCD in memory=%s --"%__convertSCDinMemory) + # logging.debug("-- Content of the file : --") + # logging.debug(__SCDdump) + __msg = "An error occured during the ADAO YACS Schema build for\n" + __msg += "the target output file:\n" + __msg += " %s\n"%__file + __msg += "See errors details in your launching terminal log.\n" + raise ValueError(__msg) + # ----- __fid = open(__file,"r") __text = __fid.read() __fid.close() diff --git a/src/daComposant/daCore/PlatformInfo.py b/src/daComposant/daCore/PlatformInfo.py index 7f698e0..f401ab7 100644 --- a/src/daComposant/daCore/PlatformInfo.py +++ b/src/daComposant/daCore/PlatformInfo.py @@ -204,8 +204,6 @@ class PathManagement(object): "Déclaration des répertoires statiques" parent = os.path.abspath(os.path.join(os.path.dirname(__file__),"..")) self.__paths = {} - self.__paths["daExternals"] = os.path.join(parent,"daExternals") - self.__paths["daMatrices"] = os.path.join(parent,"daMatrices") self.__paths["daNumerics"] = os.path.join(parent,"daNumerics") # for v in self.__paths.values(): diff --git a/src/daComposant/daMatrices/__init__.py b/src/daComposant/daMatrices/__init__.py deleted file mode 100644 index 52ece7b..0000000 --- a/src/daComposant/daMatrices/__init__.py +++ /dev/null @@ -1,21 +0,0 @@ -# -*- coding: utf-8 -*- -# -# Copyright (C) 2008-2018 EDF R&D -# -# 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. -# -# 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 -# -# See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com -# -# Author: Jean-Philippe Argaud, jean-philippe.argaud@edf.fr, EDF R&D diff --git a/src/daComposant/daNumerics/mmqr.py b/src/daComposant/daNumerics/mmqr.py deleted file mode 100644 index 02fcc65..0000000 --- a/src/daComposant/daNumerics/mmqr.py +++ /dev/null @@ -1,108 +0,0 @@ -# -*- coding: utf-8 -*- -# -# Copyright (C) 2008-2018 EDF R&D -# -# 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. -# -# 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 -# -# See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com -# -# Author: Jean-Philippe Argaud, jean-philippe.argaud@edf.fr, EDF R&D - -__doc__ = """ - Implémentation informatique de l'algorithme MMQR, basée sur la publication : - David R. Hunter, Kenneth Lange, "Quantile Regression via an MM Algorithm", - Journal of Computational and Graphical Statistics, 9, 1, pp.60-77, 2000. -""" -__author__ = "Jean-Philippe ARGAUD" - -import sys, math -from numpy import array, matrix, asarray, asmatrix -from numpy import sum, dot, linalg, ravel, max, min, hstack, argmin, argmax - -# ============================================================================== -def mmqr( - func = None, - x0 = None, - fprime = None, - bounds = None, - quantile = 0.5, - maxfun = 15000, - toler = 1.e-06, - y = None, - ): - # - # Recuperation des donnees et informations initiales - # -------------------------------------------------- - variables = asmatrix(ravel( x0 )) - mesures = asmatrix(ravel( y )).T - increment = sys.float_info[0] - p = len(variables.flat) - n = len(mesures.flat) - quantile = float(quantile) - # - # Calcul des parametres du MM - # --------------------------- - tn = float(toler) / n - e0 = -tn / math.log(tn) - epsilon = (e0-tn)/(1+math.log(e0)) - # - # Calculs d'initialisation - # ------------------------ - residus = ravel( mesures - func( variables ) ) - poids = asarray( 1./(epsilon+abs(residus)) ) - veps = 1. - 2. * quantile - residus * poids - lastsurrogate = -sum(residus*veps) - (1.-2.*quantile)*sum(residus) - iteration = 0 - # - # Recherche iterative - # ------------------- - while (increment > toler) and (iteration < maxfun) : - iteration += 1 - # - Derivees = array(fprime(variables)) - Derivees = Derivees.reshape(n,p) # Necessaire pour remettre en place la matrice si elle passe par des tuyaux YACS - DeriveesT = array(matrix(Derivees).T) - M = dot( DeriveesT , (array(matrix(p*[poids,]).T)*Derivees) ) - SM = dot( DeriveesT , veps ).T - step = - linalg.lstsq( M, SM )[0] - # - variables = variables + step - if bounds is not None: - while( (variables < ravel(asmatrix(bounds)[:,0])).any() or (variables > ravel(asmatrix(bounds)[:,1])).any() ): - step = step/2. - variables = variables - step - residus = ravel( mesures - func(variables) ) - surrogate = sum(residus**2 * poids) + (4.*quantile-2.) * sum(residus) - # - while ( (surrogate > lastsurrogate) and ( max(list(abs(step))) > 1.e-16 ) ) : - step = step/2. - variables = variables - step - residus = ravel( mesures-func(variables) ) - surrogate = sum(residus**2 * poids) + (4.*quantile-2.) * sum(residus) - # - increment = lastsurrogate-surrogate - poids = 1./(epsilon+abs(residus)) - veps = 1. - 2. * quantile - residus * poids - lastsurrogate = -sum(residus * veps) - (1.-2.*quantile)*sum(residus) - # - # Mesure d'écart : q*Sum(residus)-sum(residus negatifs) - # ---------------- - Ecart = quantile * sum(residus) - sum( residus[residus<0] ) - # - return variables, Ecart, [n,p,iteration,increment,0] - -# ============================================================================== -if __name__ == "__main__": - print('\n AUTODIAGNOSTIC \n')