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) )
90 Permet de renvoyer l'opérateur sous la forme d'une matrice
92 if self.__Matrix is not None:
95 raise ValueError("Matrix form of the operator is not available")
99 Renvoie la taille sous forme numpy si l'opérateur est disponible sous
100 la forme d'une matrice
102 if self.__Matrix is not None:
103 return self.__Matrix.shape
105 raise ValueError("Matrix form of the operator is not available, nor the shape")
107 # ==============================================================================
110 Classe générale d'interface de type algorithme
112 Elle donne un cadre pour l'écriture d'une classe élémentaire d'algorithme
113 d'assimilation, en fournissant un container (dictionnaire) de variables
114 persistantes initialisées, et des méthodes d'accès à ces variables stockées.
116 Une classe élémentaire d'algorithme doit implémenter la méthode "run".
120 L'initialisation présente permet de fabriquer des variables de stockage
121 disponibles de manière générique dans les algorithmes élémentaires. Ces
122 variables de stockage sont ensuite conservées dans un dictionnaire
123 interne à l'objet, mais auquel on accède par la méthode "get".
125 Les variables prévues sont :
126 - CostFunctionJ : fonction-cout globale, somme des deux parties suivantes
127 - CostFunctionJb : partie ébauche ou background de la fonction-cout
128 - CostFunctionJo : partie observations de la fonction-cout
129 - GradientOfCostFunctionJ : gradient de la fonction-cout globale
130 - GradientOfCostFunctionJb : gradient de la partie ébauche de la fonction-cout
131 - GradientOfCostFunctionJo : gradient de la partie observations de la fonction-cout
132 - CurrentState : état courant lors d'itérations
133 - Analysis : l'analyse
134 - Innovation : l'innovation : d = Y - H Xb
135 - SigmaObs2 : correction optimale des erreurs d'observation
136 - SigmaBck2 : correction optimale des erreurs d'ébauche
137 - OMA : Observation moins Analysis : Y - Xa
138 - OMB : Observation moins Background : Y - Xb
139 - AMB : Analysis moins Background : Xa - Xb
140 - APosterioriCovariance : matrice A
141 On peut rajouter des variables à stocker dans l'initialisation de
142 l'algorithme élémentaire qui va hériter de cette classe
145 self.StoredVariables = {}
147 self.StoredVariables["CostFunctionJ"] = Persistence.OneScalar(name = "CostFunctionJ")
148 self.StoredVariables["CostFunctionJb"] = Persistence.OneScalar(name = "CostFunctionJb")
149 self.StoredVariables["CostFunctionJo"] = Persistence.OneScalar(name = "CostFunctionJo")
150 self.StoredVariables["GradientOfCostFunctionJ"] = Persistence.OneVector(name = "GradientOfCostFunctionJ")
151 self.StoredVariables["GradientOfCostFunctionJb"] = Persistence.OneVector(name = "GradientOfCostFunctionJb")
152 self.StoredVariables["GradientOfCostFunctionJo"] = Persistence.OneVector(name = "GradientOfCostFunctionJo")
153 self.StoredVariables["CurrentState"] = Persistence.OneVector(name = "CurrentState")
154 self.StoredVariables["Analysis"] = Persistence.OneVector(name = "Analysis")
155 self.StoredVariables["Innovation"] = Persistence.OneVector(name = "Innovation")
156 self.StoredVariables["SigmaObs2"] = Persistence.OneScalar(name = "SigmaObs2")
157 self.StoredVariables["SigmaBck2"] = Persistence.OneScalar(name = "SigmaBck2")
158 self.StoredVariables["OMA"] = Persistence.OneVector(name = "OMA")
159 self.StoredVariables["OMB"] = Persistence.OneVector(name = "OMB")
160 self.StoredVariables["BMA"] = Persistence.OneVector(name = "BMA")
161 self.StoredVariables["APosterioriCovariance"] = Persistence.OneMatrix(name = "APosterioriCovariance")
163 def get(self, key=None):
165 Renvoie l'une des variables stockées identifiée par la clé, ou le
166 dictionnaire de l'ensemble des variables disponibles en l'absence de
167 clé. Ce sont directement les variables sous forme objet qui sont
168 renvoyées, donc les méthodes d'accès à l'objet individuel sont celles
169 des classes de persistance.
172 return self.StoredVariables[key]
174 return self.StoredVariables
176 def has_key(self, key=None):
178 Vérifie si l'une des variables stockées est identifiée par la clé.
180 return self.StoredVariables.has_key(key)
184 Renvoie la liste des clés de variables stockées.
186 return self.StoredVariables.keys()
188 def run(self, Xb=None, Y=None, H=None, M=None, R=None, B=None, Q=None, Parameters=None):
190 Doit implémenter l'opération élémentaire de calcul d'assimilation sous
191 sa forme mathématique la plus naturelle possible.
193 raise NotImplementedError("Mathematical assimilation calculation has not been implemented!")
195 # ==============================================================================
198 Classe générale d'interface de type diagnostic
200 Ce template s'utilise de la manière suivante : il sert de classe "patron" en
201 même temps que l'une des classes de persistance, comme "OneScalar" par
204 Une classe élémentaire de diagnostic doit implémenter ses deux méthodes, la
205 méthode "_formula" pour écrire explicitement et proprement la formule pour
206 l'écriture mathématique du calcul du diagnostic (méthode interne non
207 publique), et "calculate" pour activer la précédente tout en ayant vérifié
208 et préparé les données, et pour stocker les résultats à chaque pas (méthode
209 externe d'activation).
211 def __init__(self, name = "", parameters = {}):
212 self.name = str(name)
213 self.parameters = dict( parameters )
215 def _formula(self, *args):
217 Doit implémenter l'opération élémentaire de diagnostic sous sa forme
218 mathématique la plus naturelle possible.
220 raise NotImplementedError("Diagnostic mathematical formula has not been implemented!")
222 def calculate(self, *args):
224 Active la formule de calcul avec les arguments correctement rangés
226 raise NotImplementedError("Diagnostic activation method has not been implemented!")
228 # ==============================================================================
229 if __name__ == "__main__":
230 print '\n AUTODIAGNOSTIC \n'