Salome HOME
Improving array/matrix treatment and correcting commentaries
[modules/adao.git] / src / daComposant / daAlgorithms / Blue.py
1 #-*-coding:iso-8859-1-*-
2 #
3 #  Copyright (C) 2008-2012 EDF R&D
4 #
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.
9 #
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.
14 #
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
18 #
19 #  See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
20 #
21
22 import logging
23 from daCore import BasicObjects, PlatformInfo
24 m = PlatformInfo.SystemUsage()
25
26 import numpy
27
28 # ==============================================================================
29 class ElementaryAlgorithm(BasicObjects.Algorithm):
30     def __init__(self):
31         BasicObjects.Algorithm.__init__(self, "BLUE")
32         self.defineRequiredParameter(
33             name     = "CalculateAPosterioriCovariance",
34             default  = False,
35             typecast = bool,
36             message  = "Calcul de la covariance a posteriori",
37             )
38
39     def run(self, Xb=None, Y=None, H=None, M=None, R=None, B=None, Q=None, Parameters=None):
40         """
41         Calcul de l'estimateur BLUE (ou Kalman simple, ou Interpolation Optimale)
42         """
43         logging.debug("%s Lancement"%self._name)
44         logging.debug("%s Taille mémoire utilisée de %.1f Mo"%(self._name, m.getUsedMemory("Mo")))
45         #
46         # Paramètres de pilotage
47         # ----------------------
48         self.setParameters(Parameters)
49         #
50         # Opérateur d'observation
51         # -----------------------
52         Hm = H["Direct"].asMatrix()
53         Ha = H["Adjoint"].asMatrix()
54         #
55         # Utilisation éventuelle d'un vecteur H(Xb) précalculé
56         # ----------------------------------------------------
57         if H["AppliedToX"] is not None and H["AppliedToX"].has_key("HXb"):
58             logging.debug("%s Utilisation de HXb"%self._name)
59             HXb = H["AppliedToX"]["HXb"]
60         else:
61             logging.debug("%s Calcul de Hm * Xb"%self._name)
62             HXb = Hm * Xb
63         HXb = numpy.asmatrix(HXb).flatten().T
64         #
65         # Précalcul des inversions de B et R
66         # ----------------------------------
67         if B is not None:
68             BI = B.I
69         elif self._parameters["B_scalar"] is not None:
70             BI = 1.0 / self._parameters["B_scalar"]
71             B = self._parameters["B_scalar"]
72         else:
73             raise ValueError("Background error covariance matrix has to be properly defined!")
74         #
75         if R is not None:
76             RI = R.I
77         elif self._parameters["R_scalar"] is not None:
78             RI = 1.0 / self._parameters["R_scalar"]
79         else:
80             raise ValueError("Observation error covariance matrix has to be properly defined!")
81         #
82         # Calcul de l'innovation
83         # ----------------------
84         if Y.size != HXb.size:
85             raise ValueError("The size %i of observations Y and %i of observed calculation H(X) are different, they have to be identical."%(Y.size,HXb.size))
86         if max(Y.shape) != max(HXb.shape):
87             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))
88         d  = Y - HXb
89         logging.debug("%s Innovation d = %s"%(self._name, d))
90         #
91         # Calcul de la matrice de gain et de l'analyse
92         # --------------------------------------------
93         if Y.size <= Xb.size:
94             if self._parameters["R_scalar"] is not None:
95                 R = self._parameters["R_scalar"] * numpy.eye(len(Y), dtype=numpy.float)
96             logging.debug("%s Calcul de K dans l'espace des observations"%self._name)
97             K  = B * Ha * (Hm * B * Ha + R).I
98         else:
99             logging.debug("%s Calcul de K dans l'espace d'ébauche"%self._name)
100             K = (Ha * RI * Hm + BI).I * Ha * RI
101         Xa = Xb + K*d
102         logging.debug("%s Analyse Xa = %s"%(self._name, Xa))
103         #
104         # Calcul de la fonction coût
105         # --------------------------
106         Jb  = 0.5 * (Xa - Xb).T * BI * (Xa - Xb)
107         Jo  = 0.5 * d.T * RI * d
108         J   = float( Jb ) + float( Jo )
109         logging.debug("%s CostFunction Jb = %s"%(self._name, Jb))
110         logging.debug("%s CostFunction Jo = %s"%(self._name, Jo))
111         logging.debug("%s CostFunction J  = %s"%(self._name, J))
112         #
113         self.StoredVariables["Analysis"].store( Xa.A1 )
114         self.StoredVariables["Innovation"].store( d.A1 )
115         self.StoredVariables["CostFunctionJb"].store( Jb )
116         self.StoredVariables["CostFunctionJo"].store( Jo )
117         self.StoredVariables["CostFunctionJ" ].store( J )
118         #
119         # Calcul de la covariance d'analyse
120         # ---------------------------------
121         if self._parameters["CalculateAPosterioriCovariance"]:
122             A = ( 1.0 -  K * Hm ) * B
123             self.StoredVariables["APosterioriCovariance"].store( A )
124         #
125         logging.debug("%s Taille mémoire utilisée de %.1f Mo"%(self._name, m.getUsedMemory("Mo")))
126         logging.debug("%s Terminé"%self._name)
127         #
128         return 0
129
130 # ==============================================================================
131 if __name__ == "__main__":
132     print '\n AUTODIAGNOSTIC \n'