1 #-*-coding:iso-8859-1-*-
3 # Copyright (C) 2008-2012 EDF R&D
5 # This library is free software; you can redistribute it and/or
6 # modify it under the terms of the GNU Lesser General Public
7 # License as published by the Free Software Foundation; either
8 # version 2.1 of the License.
10 # This library is distributed in the hope that it will be useful,
11 # but WITHOUT ANY WARRANTY; without even the implied warranty of
12 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 # Lesser General Public License for more details.
15 # You should have received a copy of the GNU Lesser General Public
16 # License along with this library; if not, write to the Free Software
17 # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
19 # See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
21 # Author: Jean-Philippe Argaud, jean-philippe.argaud@edf.fr, EDF R&D
24 Définit les outils généraux élémentaires.
26 Ce module est destiné à etre appelée par AssimilationStudy pour constituer
27 les objets élémentaires de l'algorithme.
29 __author__ = "Jean-Philippe ARGAUD"
34 # ==============================================================================
37 Classe générale d'interface de type opérateur
39 def __init__(self, fromMethod=None, fromMatrix=None):
41 On construit un objet de ce type en fournissant à l'aide de l'un des
42 deux mots-clé, soit une fonction python, soit matrice.
44 - fromMethod : argument de type fonction Python
45 - fromMatrix : argument adapté au constructeur numpy.matrix
47 if fromMethod is not None:
48 self.__Method = fromMethod
50 elif fromMatrix is not None:
52 self.__Matrix = numpy.matrix( fromMatrix, numpy.float )
57 def appliedTo(self, xValue):
59 Permet de restituer le résultat de l'application de l'opérateur à un
60 argument xValue. Cette méthode se contente d'appliquer, son argument
61 devant a priori être du bon type.
63 - xValue : argument adapté pour appliquer l'opérateur
65 if self.__Matrix is not None:
66 return self.__Matrix * xValue
68 return self.__Method( xValue )
70 def appliedInXTo(self, (xNominal, xValue) ):
72 Permet de restituer le résultat de l'application de l'opérateur à un
73 argument xValue, sachant que l'opérateur est valable en xNominal.
74 Cette méthode se contente d'appliquer, son argument devant a priori
75 être du bon type. Si l'opérateur est linéaire car c'est une matrice,
76 alors il est valable en tout point nominal et il n'est pas nécessaire
78 Arguments : une liste contenant
79 - xNominal : argument permettant de donner le point où l'opérateur
80 est construit pour etre ensuite appliqué
81 - xValue : argument adapté pour appliquer l'opérateur
83 if self.__Matrix is not None:
84 return self.__Matrix * xValue
86 return self.__Method( (xNominal, xValue) )
88 def asMatrix(self, ValueForMethodForm = None):
90 Permet de renvoyer l'opérateur sous la forme d'une matrice
92 if self.__Matrix is not None:
94 elif ValueForMethodForm is not None:
95 return self.__Method( ValueForMethodForm )
97 raise ValueError("Matrix form of the operator defined as a function/method requires to give an operating point.")
101 Renvoie la taille sous forme numpy si l'opérateur est disponible sous
102 la forme d'une matrice
104 if self.__Matrix is not None:
105 return self.__Matrix.shape
107 raise ValueError("Matrix form of the operator is not available, nor the shape")
109 # ==============================================================================
112 Classe générale d'interface de type algorithme
114 Elle donne un cadre pour l'écriture d'une classe élémentaire d'algorithme
115 d'assimilation, en fournissant un container (dictionnaire) de variables
116 persistantes initialisées, et des méthodes d'accès à ces variables stockées.
118 Une classe élémentaire d'algorithme doit implémenter la méthode "run".
122 L'initialisation présente permet de fabriquer des variables de stockage
123 disponibles de manière générique dans les algorithmes élémentaires. Ces
124 variables de stockage sont ensuite conservées dans un dictionnaire
125 interne à l'objet, mais auquel on accède par la méthode "get".
127 Les variables prévues sont :
128 - CostFunctionJ : fonction-cout globale, somme des deux parties suivantes
129 - CostFunctionJb : partie ébauche ou background de la fonction-cout
130 - CostFunctionJo : partie observations de la fonction-cout
131 - GradientOfCostFunctionJ : gradient de la fonction-cout globale
132 - GradientOfCostFunctionJb : gradient de la partie ébauche de la fonction-cout
133 - GradientOfCostFunctionJo : gradient de la partie observations de la fonction-cout
134 - CurrentState : état courant lors d'itérations
135 - Analysis : l'analyse
136 - Innovation : l'innovation : d = Y - H Xb
137 - SigmaObs2 : correction optimale des erreurs d'observation
138 - SigmaBck2 : correction optimale des erreurs d'ébauche
139 - OMA : Observation moins Analysis : Y - Xa
140 - OMB : Observation moins Background : Y - Xb
141 - AMB : Analysis moins Background : Xa - Xb
142 - APosterioriCovariance : matrice A
143 On peut rajouter des variables à stocker dans l'initialisation de
144 l'algorithme élémentaire qui va hériter de cette classe
147 self.StoredVariables = {}
149 self.StoredVariables["CostFunctionJ"] = Persistence.OneScalar(name = "CostFunctionJ")
150 self.StoredVariables["CostFunctionJb"] = Persistence.OneScalar(name = "CostFunctionJb")
151 self.StoredVariables["CostFunctionJo"] = Persistence.OneScalar(name = "CostFunctionJo")
152 self.StoredVariables["GradientOfCostFunctionJ"] = Persistence.OneVector(name = "GradientOfCostFunctionJ")
153 self.StoredVariables["GradientOfCostFunctionJb"] = Persistence.OneVector(name = "GradientOfCostFunctionJb")
154 self.StoredVariables["GradientOfCostFunctionJo"] = Persistence.OneVector(name = "GradientOfCostFunctionJo")
155 self.StoredVariables["CurrentState"] = Persistence.OneVector(name = "CurrentState")
156 self.StoredVariables["Analysis"] = Persistence.OneVector(name = "Analysis")
157 self.StoredVariables["Innovation"] = Persistence.OneVector(name = "Innovation")
158 self.StoredVariables["SigmaObs2"] = Persistence.OneScalar(name = "SigmaObs2")
159 self.StoredVariables["SigmaBck2"] = Persistence.OneScalar(name = "SigmaBck2")
160 self.StoredVariables["OMA"] = Persistence.OneVector(name = "OMA")
161 self.StoredVariables["OMB"] = Persistence.OneVector(name = "OMB")
162 self.StoredVariables["BMA"] = Persistence.OneVector(name = "BMA")
163 self.StoredVariables["APosterioriCovariance"] = Persistence.OneMatrix(name = "APosterioriCovariance")
165 def get(self, key=None):
167 Renvoie l'une des variables stockées identifiée par la clé, ou le
168 dictionnaire de l'ensemble des variables disponibles en l'absence de
169 clé. Ce sont directement les variables sous forme objet qui sont
170 renvoyées, donc les méthodes d'accès à l'objet individuel sont celles
171 des classes de persistance.
174 return self.StoredVariables[key]
176 return self.StoredVariables
178 def has_key(self, key=None):
180 Vérifie si l'une des variables stockées est identifiée par la clé.
182 return self.StoredVariables.has_key(key)
186 Renvoie la liste des clés de variables stockées.
188 return self.StoredVariables.keys()
190 def run(self, Xb=None, Y=None, H=None, M=None, R=None, B=None, Q=None, Parameters=None):
192 Doit implémenter l'opération élémentaire de calcul d'assimilation sous
193 sa forme mathématique la plus naturelle possible.
195 raise NotImplementedError("Mathematical assimilation calculation has not been implemented!")
197 # ==============================================================================
200 Classe générale d'interface de type diagnostic
202 Ce template s'utilise de la manière suivante : il sert de classe "patron" en
203 même temps que l'une des classes de persistance, comme "OneScalar" par
206 Une classe élémentaire de diagnostic doit implémenter ses deux méthodes, la
207 méthode "_formula" pour écrire explicitement et proprement la formule pour
208 l'écriture mathématique du calcul du diagnostic (méthode interne non
209 publique), et "calculate" pour activer la précédente tout en ayant vérifié
210 et préparé les données, et pour stocker les résultats à chaque pas (méthode
211 externe d'activation).
213 def __init__(self, name = "", parameters = {}):
214 self.name = str(name)
215 self.parameters = dict( parameters )
217 def _formula(self, *args):
219 Doit implémenter l'opération élémentaire de diagnostic sous sa forme
220 mathématique la plus naturelle possible.
222 raise NotImplementedError("Diagnostic mathematical formula has not been implemented!")
224 def calculate(self, *args):
226 Active la formule de calcul avec les arguments correctement rangés
228 raise NotImplementedError("Diagnostic activation method has not been implemented!")
230 # ==============================================================================
231 if __name__ == "__main__":
232 print '\n AUTODIAGNOSTIC \n'