1 #-*-coding:iso-8859-1-*-
3 # Copyright (C) 2008-2010 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
22 Définit les outils généraux élémentaires.
24 Ce module est destiné à etre appelée par AssimilationStudy pour constituer
25 les objets élémentaires de l'algorithme.
27 __author__ = "Jean-Philippe ARGAUD - Mars 2008"
32 # ==============================================================================
35 Classe générale d'interface de type opérateur
37 def __init__(self, fromMethod=None, fromMatrix=None):
39 On construit un objet de ce type en fournissant à l'aide de l'un des
40 deux mots-clé, soit une fonction python, soit matrice.
42 - fromMethod : argument de type fonction Python
43 - fromMatrix : argument adapté au constructeur numpy.matrix
45 if fromMethod is not None:
46 self.__Method = fromMethod
48 elif fromMatrix is not None:
50 self.__Matrix = numpy.matrix( fromMatrix, numpy.float )
55 def appliedTo(self, xValue):
57 Permet de restituer le résultat de l'application de l'opérateur à un
58 argument xValue. Cette méthode se contente d'appliquer, son argument
59 devant a priori être du bon type.
61 - xValue : argument adapté pour appliquer l'opérateur
63 if self.__Matrix is not None:
64 return self.__Matrix * xValue
66 return self.__Method( xValue )
68 def appliedInXTo(self, (xNominal, xValue) ):
70 Permet de restituer le résultat de l'application de l'opérateur à un
71 argument xValue, sachant que l'opérateur est valable en xNominal.
72 Cette méthode se contente d'appliquer, son argument devant a priori
73 être du bon type. Si l'opérateur est linéaire car c'est une matrice,
74 alors il est valable en tout point nominal et il n'est pas nécessaire
76 Arguments : une liste contenant
77 - xNominal : argument permettant de donner le point où l'opérateur
78 est construit pour etre ensuite appliqué
79 - xValue : argument adapté pour appliquer l'opérateur
81 if self.__Matrix is not None:
82 return self.__Matrix * xValue
84 return self.__Method( (xNominal, xValue) )
88 Permet de renvoyer l'opérateur sous la forme d'une matrice
90 if self.__Matrix is not None:
93 raise ValueError("Matrix form of the operator is not available")
97 Renvoie la taille sous forme numpy si l'opérateur est disponible sous
98 la forme d'une matrice
100 if self.__Matrix is not None:
101 return self.__Matrix.shape
103 raise ValueError("Matrix form of the operator is not available, nor the shape")
105 # ==============================================================================
108 Classe générale d'interface de type algorithme
110 Elle donne un cadre pour l'écriture d'une classe élémentaire d'algorithme
111 d'assimilation, en fournissant un container (dictionnaire) de variables
112 persistantes initialisées, et des méthodes d'accès à ces variables stockées.
114 Une classe élémentaire d'algorithme doit implémenter la méthode "run".
118 L'initialisation présente permet de fabriquer des variables de stockage
119 disponibles de manière générique dans les algorithmes élémentaires. Ces
120 variables de stockage sont ensuite conservées dans un dictionnaire
121 interne à l'objet, mais auquel on accède par la méthode "get".
123 Les variables prévues sont :
124 - CostFunctionJ : fonction-cout globale, somme des deux parties suivantes
125 - CostFunctionJb : partie ébauche ou background de la fonction-cout
126 - CostFunctionJo : partie observations de la fonction-cout
127 - GradientOfCostFunctionJ : gradient de la fonction-cout globale
128 - GradientOfCostFunctionJb : gradient de la partie ébauche de la fonction-cout
129 - GradientOfCostFunctionJo : gradient de la partie observations de la fonction-cout
130 - CurrentState : état courant lors d'itérations
131 - Analysis : l'analyse
132 - Innovation : l'innovation : d = Y - H Xb
133 - SigmaObs2 : correction optimale des erreurs d'observation
134 - SigmaBck2 : correction optimale des erreurs d'ébauche
135 - OMA : Observation moins Analysis : Y - Xa
136 - OMB : Observation moins Background : Y - Xb
137 - AMB : Analysis moins Background : Xa - Xb
138 - CovarianceAPosteriori : matrice A
139 On peut rajouter des variables à stocker dans l'initialisation de
140 l'algorithme élémentaire qui va hériter de cette classe
143 self.StoredVariables = {}
145 self.StoredVariables["CostFunctionJ"] = Persistence.OneScalar(name = "CostFunctionJ")
146 self.StoredVariables["CostFunctionJb"] = Persistence.OneScalar(name = "CostFunctionJb")
147 self.StoredVariables["CostFunctionJo"] = Persistence.OneScalar(name = "CostFunctionJo")
148 self.StoredVariables["GradientOfCostFunctionJ"] = Persistence.OneVector(name = "GradientOfCostFunctionJ")
149 self.StoredVariables["GradientOfCostFunctionJb"] = Persistence.OneVector(name = "GradientOfCostFunctionJb")
150 self.StoredVariables["GradientOfCostFunctionJo"] = Persistence.OneVector(name = "GradientOfCostFunctionJo")
151 self.StoredVariables["CurrentState"] = Persistence.OneVector(name = "CurrentState")
152 self.StoredVariables["Analysis"] = Persistence.OneVector(name = "Analysis")
153 self.StoredVariables["Innovation"] = Persistence.OneVector(name = "Innovation")
154 self.StoredVariables["SigmaObs2"] = Persistence.OneScalar(name = "SigmaObs2")
155 self.StoredVariables["SigmaBck2"] = Persistence.OneScalar(name = "SigmaBck2")
156 self.StoredVariables["OMA"] = Persistence.OneVector(name = "OMA")
157 self.StoredVariables["OMB"] = Persistence.OneVector(name = "OMB")
158 self.StoredVariables["BMA"] = Persistence.OneVector(name = "BMA")
159 self.StoredVariables["CovarianceAPosteriori"] = Persistence.OneMatrix(name = "CovarianceAPosteriori")
161 def get(self, key=None):
163 Renvoie l'une des variables stockées identifiée par la clé, ou le
164 dictionnaire de l'ensemble des variables disponibles en l'absence de
165 clé. Ce sont directement les variables sous forme objet qui sont
166 renvoyées, donc les méthodes d'accès à l'objet individuel sont celles
167 des classes de persistance.
170 return self.StoredVariables[key]
172 return self.StoredVariables
174 def has_key(self, key=None):
176 Vérifie si l'une des variables stockées est identifiée par la clé.
178 return self.StoredVariables.has_key(key)
182 Renvoie la liste des clés de variables stockées.
184 return self.StoredVariables.keys()
186 def run(self, Xb=None, Y=None, H=None, M=None, R=None, B=None, Q=None, Parameters=None):
188 Doit implémenter l'opération élémentaire de calcul d'assimilation sous
189 sa forme mathématique la plus naturelle possible.
191 raise NotImplementedError("Mathematical assimilation calculation has not been implemented!")
193 # ==============================================================================
196 Classe générale d'interface de type diagnostic
198 Ce template s'utilise de la manière suivante : il sert de classe "patron" en
199 même temps que l'une des classes de persistance, comme "OneScalar" par
202 Une classe élémentaire de diagnostic doit implémenter ses deux méthodes, la
203 méthode "_formula" pour écrire explicitement et proprement la formule pour
204 l'écriture mathématique du calcul du diagnostic (méthode interne non
205 publique), et "calculate" pour activer la précédente tout en ayant vérifié
206 et préparé les données, et pour stocker les résultats à chaque pas (méthode
207 externe d'activation).
209 def __init__(self, name = "", parameters = {}):
210 self.name = str(name)
211 self.parameters = dict( parameters )
213 def _formula(self, *args):
215 Doit implémenter l'opération élémentaire de diagnostic sous sa forme
216 mathématique la plus naturelle possible.
218 raise NotImplementedError("Diagnostic mathematical formula has not been implemented!")
220 def calculate(self, *args):
222 Active la formule de calcul avec les arguments correctement rangés
224 raise NotImplementedError("Diagnostic activation method has not been implemented!")
226 # ==============================================================================
227 if __name__ == "__main__":
228 print '\n AUTODIAGNOSTIC \n'