From 0660c0c3cd99c431551df863270afe2100d7b6b2 Mon Sep 17 00:00:00 2001 From: Jean-Philippe ARGAUD Date: Thu, 23 Aug 2012 10:32:43 +0200 Subject: [PATCH] Unified management of supplementary variables to calculate or store --- src/daComposant/daAlgorithms/3DVAR.py | 34 +++++++++---- src/daComposant/daAlgorithms/Blue.py | 48 +++++++++++++++---- .../daAlgorithms/LinearLeastSquares.py | 24 ++++++++-- .../daAlgorithms/NonLinearLeastSquares.py | 24 ++++++++-- src/daComposant/daCore/AssimilationStudy.py | 1 - src/daComposant/daCore/BasicObjects.py | 13 +++-- 6 files changed, 111 insertions(+), 33 deletions(-) diff --git a/src/daComposant/daAlgorithms/3DVAR.py b/src/daComposant/daAlgorithms/3DVAR.py index 8997f3a..4178c85 100644 --- a/src/daComposant/daAlgorithms/3DVAR.py +++ b/src/daComposant/daAlgorithms/3DVAR.py @@ -18,6 +18,7 @@ # # See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com # +# Author: Jean-Philippe Argaud, jean-philippe.argaud@edf.fr, EDF R&D import logging from daCore import BasicObjects, PlatformInfo @@ -72,25 +73,26 @@ class ElementaryAlgorithm(BasicObjects.Algorithm): typecast = float, message = "Maximum des composantes du gradient lors de l'arrêt", ) - self.defineRequiredParameter( - name = "CalculateAPosterioriCovariance", - default = False, - typecast = bool, - message = "Calcul de la covariance a posteriori", - ) self.defineRequiredParameter( name = "StoreInternalVariables", default = False, typecast = bool, message = "Stockage des variables internes ou intermédiaires du calcul", ) + self.defineRequiredParameter( + name = "StoreSupplementaryCalculations", + default = [], + typecast = tuple, + message = "Liste de calculs supplémentaires à stocker et/ou effectuer", + listval = ["APosterioriCovariance", "BMA", "OMA", "OMB", "Innovation", "SigmaObs2"] + ) def run(self, Xb=None, Y=None, H=None, M=None, R=None, B=None, Q=None, Parameters=None): """ Calcul de l'estimateur 3D-VAR """ logging.debug("%s Lancement"%self._name) - logging.debug("%s Taille mémoire utilisée de %.1f Mo"%(self._name, m.getUsedMemory("Mo"))) + logging.debug("%s Taille mémoire utilisée de %.1f Mo"%(self._name, m.getUsedMemory("M"))) # # Paramètres de pilotage # ---------------------- @@ -271,11 +273,10 @@ class ElementaryAlgorithm(BasicObjects.Algorithm): logging.debug("%s Analyse Xa = %s"%(self._name, Xa)) # self.StoredVariables["Analysis"].store( Xa.A1 ) - self.StoredVariables["Innovation"].store( d.A1 ) # # Calcul de la covariance d'analyse # --------------------------------- - if self._parameters["CalculateAPosterioriCovariance"]: + if "APosterioriCovariance" in self._parameters["StoreSupplementaryCalculations"]: HessienneI = [] nb = len(Xini) for i in range(nb): @@ -293,7 +294,20 @@ class ElementaryAlgorithm(BasicObjects.Algorithm): raise ValueError("The 3DVAR a posteriori covariance matrix A is not symmetric positive-definite. Check your B and R a priori covariances.") self.StoredVariables["APosterioriCovariance"].store( A ) # - logging.debug("%s Taille mémoire utilisée de %.1f Mo"%(self._name, m.getUsedMemory("MB"))) + # Calculs et/ou stockages supplémentaires + # --------------------------------------- + if "Innovation" in self._parameters["StoreSupplementaryCalculations"]: + self.StoredVariables["Innovation"].store( numpy.asmatrix(d).flatten().A1 ) + if "BMA" in self._parameters["StoreSupplementaryCalculations"]: + self.StoredVariables["BMA"].store( numpy.asmatrix(Xb - Xa).flatten().A1 ) + if "OMA" in self._parameters["StoreSupplementaryCalculations"]: + self.StoredVariables["OMA"].store( numpy.asmatrix(Y - Hm(Xa)).flatten().A1 ) + if "OMB" in self._parameters["StoreSupplementaryCalculations"]: + self.StoredVariables["OMB"].store( numpy.asmatrix(d).flatten().A1 ) + if "SigmaObs2" in self._parameters["StoreSupplementaryCalculations"]: + self.StoredVariables["SigmaObs2"].store( float( (d.T * (Y-Hm(Xa))) / R.trace() ) ) + # + logging.debug("%s Taille mémoire utilisée de %.1f Mo"%(self._name, m.getUsedMemory("M"))) logging.debug("%s Terminé"%self._name) # return 0 diff --git a/src/daComposant/daAlgorithms/Blue.py b/src/daComposant/daAlgorithms/Blue.py index b155611..906989f 100644 --- a/src/daComposant/daAlgorithms/Blue.py +++ b/src/daComposant/daAlgorithms/Blue.py @@ -18,6 +18,7 @@ # # See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com # +# Author: Jean-Philippe Argaud, jean-philippe.argaud@edf.fr, EDF R&D import logging from daCore import BasicObjects, PlatformInfo @@ -30,10 +31,11 @@ class ElementaryAlgorithm(BasicObjects.Algorithm): def __init__(self): BasicObjects.Algorithm.__init__(self, "BLUE") self.defineRequiredParameter( - name = "CalculateAPosterioriCovariance", - default = False, - typecast = bool, - message = "Calcul de la covariance a posteriori", + name = "StoreSupplementaryCalculations", + default = [], + typecast = tuple, + message = "Liste de calculs supplémentaires à stocker et/ou effectuer", + listval = ["APosterioriCovariance", "BMA", "OMA", "OMB", "Innovation", "SigmaBck2", "SigmaObs2"] ) def run(self, Xb=None, Y=None, H=None, M=None, R=None, B=None, Q=None, Parameters=None): @@ -41,7 +43,7 @@ class ElementaryAlgorithm(BasicObjects.Algorithm): Calcul de l'estimateur BLUE (ou Kalman simple, ou Interpolation Optimale) """ logging.debug("%s Lancement"%self._name) - logging.debug("%s Taille mémoire utilisée de %.1f Mo"%(self._name, m.getUsedMemory("Mo"))) + logging.debug("%s Taille mémoire utilisée de %.1f Mo"%(self._name, m.getUsedMemory("M"))) # # Paramètres de pilotage # ---------------------- @@ -86,7 +88,17 @@ class ElementaryAlgorithm(BasicObjects.Algorithm): if max(Y.shape) != max(HXb.shape): raise ValueError("The shapes %s of observations Y and %s of observed calculation H(X) are different, they have to be identical."%(Y.shape,HXb.shape)) d = Y - HXb - logging.debug("%s Innovation d = %s"%(self._name, d)) + Jb = 0. + Jo = 0.5 * d.T * RI * d + J = float( Jb ) + float( Jo ) + logging.debug("%s Innovation d = %s"%(self._name, d)) + logging.debug("%s CostFunction Jb = %s"%(self._name, Jb)) + logging.debug("%s CostFunction Jo = %s"%(self._name, Jo)) + logging.debug("%s CostFunction J = %s"%(self._name, J)) + # + self.StoredVariables["CostFunctionJb"].store( Jb ) + self.StoredVariables["CostFunctionJo"].store( Jo ) + self.StoredVariables["CostFunctionJ" ].store( J ) # # Calcul de la matrice de gain et de l'analyse # -------------------------------------------- @@ -103,22 +115,23 @@ class ElementaryAlgorithm(BasicObjects.Algorithm): # # Calcul de la fonction coût # -------------------------- + oma = Y - Hm * Xa Jb = 0.5 * (Xa - Xb).T * BI * (Xa - Xb) - Jo = 0.5 * d.T * RI * d + Jo = 0.5 * oma.T * RI * oma J = float( Jb ) + float( Jo ) + logging.debug("%s OMA = %s"%(self._name, oma)) logging.debug("%s CostFunction Jb = %s"%(self._name, Jb)) logging.debug("%s CostFunction Jo = %s"%(self._name, Jo)) logging.debug("%s CostFunction J = %s"%(self._name, J)) # self.StoredVariables["Analysis"].store( Xa.A1 ) - self.StoredVariables["Innovation"].store( d.A1 ) self.StoredVariables["CostFunctionJb"].store( Jb ) self.StoredVariables["CostFunctionJo"].store( Jo ) self.StoredVariables["CostFunctionJ" ].store( J ) # # Calcul de la covariance d'analyse # --------------------------------- - if self._parameters["CalculateAPosterioriCovariance"]: + if "APosterioriCovariance" in self._parameters["StoreSupplementaryCalculations"]: A = B - K * Hm * B if logging.getLogger().level < logging.WARNING: # La verification n'a lieu qu'en debug try: @@ -127,7 +140,22 @@ class ElementaryAlgorithm(BasicObjects.Algorithm): raise ValueError("The BLUE a posteriori covariance matrix A is not symmetric positive-definite. Check your B and R a priori covariances.") self.StoredVariables["APosterioriCovariance"].store( A ) # - logging.debug("%s Taille mémoire utilisée de %.1f Mo"%(self._name, m.getUsedMemory("Mo"))) + # Calculs et/ou stockages supplémentaires + # --------------------------------------- + if "Innovation" in self._parameters["StoreSupplementaryCalculations"]: + self.StoredVariables["Innovation"].store( numpy.asmatrix(d).flatten().A1 ) + if "BMA" in self._parameters["StoreSupplementaryCalculations"]: + self.StoredVariables["BMA"].store( numpy.asmatrix(Xb - Xa).flatten().A1 ) + if "OMA" in self._parameters["StoreSupplementaryCalculations"]: + self.StoredVariables["OMA"].store( numpy.asmatrix(oma).flatten().A1 ) + if "OMB" in self._parameters["StoreSupplementaryCalculations"]: + self.StoredVariables["OMB"].store( numpy.asmatrix(d).flatten().A1 ) + if "SigmaObs2" in self._parameters["StoreSupplementaryCalculations"]: + self.StoredVariables["SigmaObs2"].store( float( (d.T * (Y-Hm*Xa)) / R.trace() ) ) + if "SigmaBck2" in self._parameters["StoreSupplementaryCalculations"]: + self.StoredVariables["SigmaBck2"].store( float( (d.T * Hm * (Xa - Xb))/(Hm * B * Hm.T).trace() ) ) + # + logging.debug("%s Taille mémoire utilisée de %.1f Mo"%(self._name, m.getUsedMemory("M"))) logging.debug("%s Terminé"%self._name) # return 0 diff --git a/src/daComposant/daAlgorithms/LinearLeastSquares.py b/src/daComposant/daAlgorithms/LinearLeastSquares.py index 0b07c5b..1a8ea25 100644 --- a/src/daComposant/daAlgorithms/LinearLeastSquares.py +++ b/src/daComposant/daAlgorithms/LinearLeastSquares.py @@ -18,15 +18,25 @@ # # See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com # +# Author: Jean-Philippe Argaud, jean-philippe.argaud@edf.fr, EDF R&D import logging from daCore import BasicObjects, PlatformInfo m = PlatformInfo.SystemUsage() +import numpy + # ============================================================================== class ElementaryAlgorithm(BasicObjects.Algorithm): def __init__(self): BasicObjects.Algorithm.__init__(self, "LINEARLEASTSQUARES") + self.defineRequiredParameter( + name = "StoreSupplementaryCalculations", + default = [], + typecast = tuple, + message = "Liste de calculs supplémentaires à stocker et/ou effectuer", + listval = ["OMA"] + ) def run(self, Xb=None, Y=None, H=None, M=None, R=None, B=None, Q=None, Parameters=None): """ @@ -34,7 +44,7 @@ class ElementaryAlgorithm(BasicObjects.Algorithm): (assimilation variationnelle sans ébauche) """ logging.debug("%s Lancement"%self._name) - logging.debug("%s Taille mémoire utilisée de %.1f Mo"%(self._name, m.getUsedMemory("Mo"))) + logging.debug("%s Taille mémoire utilisée de %.1f Mo"%(self._name, m.getUsedMemory("M"))) # # Paramètres de pilotage # ---------------------- @@ -60,21 +70,25 @@ class ElementaryAlgorithm(BasicObjects.Algorithm): # # Calcul de la fonction coût # -------------------------- - d = Y - Hm * Xa + oma = Y - Hm * Xa Jb = 0. - Jo = 0.5 * d.T * RI * d + Jo = 0.5 * oma.T * RI * oma J = float( Jb ) + float( Jo ) logging.debug("%s CostFunction Jb = %s"%(self._name, Jb)) logging.debug("%s CostFunction Jo = %s"%(self._name, Jo)) logging.debug("%s CostFunction J = %s"%(self._name, J)) # self.StoredVariables["Analysis"].store( Xa.A1 ) - self.StoredVariables["Innovation"].store( d.A1 ) self.StoredVariables["CostFunctionJb"].store( Jb ) self.StoredVariables["CostFunctionJo"].store( Jo ) self.StoredVariables["CostFunctionJ" ].store( J ) # - logging.debug("%s Taille mémoire utilisée de %.1f Mo"%(self._name, m.getUsedMemory("Mo"))) + # Calculs et/ou stockages supplémentaires + # --------------------------------------- + if "OMA" in self._parameters["StoreSupplementaryCalculations"]: + self.StoredVariables["OMA"].store( numpy.asmatrix(oma).flatten().A1 ) + # + logging.debug("%s Taille mémoire utilisée de %.1f Mo"%(self._name, m.getUsedMemory("M"))) logging.debug("%s Terminé"%self._name) # return 0 diff --git a/src/daComposant/daAlgorithms/NonLinearLeastSquares.py b/src/daComposant/daAlgorithms/NonLinearLeastSquares.py index cee9082..f64fdc9 100644 --- a/src/daComposant/daAlgorithms/NonLinearLeastSquares.py +++ b/src/daComposant/daAlgorithms/NonLinearLeastSquares.py @@ -18,6 +18,7 @@ # # See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com # +# Author: Jean-Philippe Argaud, jean-philippe.argaud@edf.fr, EDF R&D import logging from daCore import BasicObjects, PlatformInfo @@ -78,6 +79,13 @@ class ElementaryAlgorithm(BasicObjects.Algorithm): typecast = bool, message = "Stockage des variables internes ou intermédiaires du calcul", ) + self.defineRequiredParameter( + name = "StoreSupplementaryCalculations", + default = [], + typecast = tuple, + message = "Liste de calculs supplémentaires à stocker et/ou effectuer", + listval = ["BMA", "OMA", "OMB", "Innovation"] + ) def run(self, Xb=None, Y=None, H=None, M=None, R=None, B=None, Q=None, Parameters=None): """ @@ -85,7 +93,7 @@ class ElementaryAlgorithm(BasicObjects.Algorithm): (assimilation variationnelle sans ébauche) """ logging.debug("%s Lancement"%self._name) - logging.debug("%s Taille mémoire utilisée de %.1f Mo"%(self._name, m.getUsedMemory("Mo"))) + logging.debug("%s Taille mémoire utilisée de %.1f Mo"%(self._name, m.getUsedMemory("M"))) # # Paramètres de pilotage # ---------------------- @@ -266,9 +274,19 @@ class ElementaryAlgorithm(BasicObjects.Algorithm): logging.debug("%s Analyse Xa = %s"%(self._name, Xa)) # self.StoredVariables["Analysis"].store( Xa.A1 ) - self.StoredVariables["Innovation"].store( d.A1 ) # - logging.debug("%s Taille mémoire utilisée de %.1f Mo"%(self._name, m.getUsedMemory("MB"))) + # Calculs et/ou stockages supplémentaires + # --------------------------------------- + if "Innovation" in self._parameters["StoreSupplementaryCalculations"]: + self.StoredVariables["Innovation"].store( numpy.asmatrix(d).flatten().A1 ) + if "BMA" in self._parameters["StoreSupplementaryCalculations"]: + self.StoredVariables["BMA"].store( numpy.asmatrix(Xb - Xa).flatten().A1 ) + if "OMA" in self._parameters["StoreSupplementaryCalculations"]: + self.StoredVariables["OMA"].store( numpy.asmatrix(Y - Hm(Xa)).flatten().A1 ) + if "OMB" in self._parameters["StoreSupplementaryCalculations"]: + self.StoredVariables["OMB"].store( numpy.asmatrix(d).flatten().A1 ) + # + logging.debug("%s Taille mémoire utilisée de %.1f Mo"%(self._name, m.getUsedMemory("M"))) logging.debug("%s Terminé"%self._name) # return 0 diff --git a/src/daComposant/daCore/AssimilationStudy.py b/src/daComposant/daCore/AssimilationStudy.py index 3f573de..371a28e 100644 --- a/src/daComposant/daCore/AssimilationStudy.py +++ b/src/daComposant/daCore/AssimilationStudy.py @@ -908,7 +908,6 @@ if __name__ == "__main__": print "Demi-somme :", list((numpy.array([0, 1, 2])+numpy.array([0.5, 1.5, 2.5]))/2) print " qui doit être identique à :" print "Analyse résultante :", ADD.get("Analysis").valueserie(0) - print "Innovation :", ADD.get("Innovation").valueserie(0) print print "Algorithmes disponibles.......................:", ADD.get_available_algorithms() diff --git a/src/daComposant/daCore/BasicObjects.py b/src/daComposant/daCore/BasicObjects.py index 0c15f3d..274482a 100644 --- a/src/daComposant/daCore/BasicObjects.py +++ b/src/daComposant/daCore/BasicObjects.py @@ -254,11 +254,16 @@ class Algorithm: else: __val = typecast( value ) # if minval is not None and __val < minval: - raise ValueError("The parameter named \"%s\" of value %s can not be less than %s."%(name, __val, minval)) + raise ValueError("The parameter named \"%s\" of value \"%s\" can not be less than %s."%(name, __val, minval)) if maxval is not None and __val > maxval: - raise ValueError("The parameter named \"%s\" of value %s can not be greater than %s."%(name, __val, maxval)) - if listval is not None and __val not in listval: - raise ValueError("The parameter named \"%s\" of value %s has to be in the list %s."%(name, __val, listval)) + raise ValueError("The parameter named \"%s\" of value \"%s\" can not be greater than %s."%(name, __val, maxval)) + if listval is not None: + if typecast is list or typecast is tuple or type(__val) is list or type(__val) is tuple: + for v in __val: + if v not in listval: + raise ValueError("The value \"%s\" of the parameter named \"%s\" is not allowed, it has to be in the list %s."%(v, name, listval)) + elif __val not in listval: + raise ValueError("The value \"%s\" of the parameter named \"%s\" is not allowed, it has to be in the list %s."%( __val, name,listval)) return __val def setParameters(self, fromDico={}): -- 2.39.2