Salome HOME
Minor source update for OM compatibility
[modules/adao.git] / src / daComposant / daAlgorithms / UnscentedKalmanFilter.py
1 # -*- coding: utf-8 -*-
2 #
3 # Copyright (C) 2008-2024 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 # Author: Jean-Philippe Argaud, jean-philippe.argaud@edf.fr, EDF R&D
22
23 from daCore import BasicObjects
24 from daAlgorithms.Atoms import ecwukf, ecw2ukf
25
26 # ==============================================================================
27 class ElementaryAlgorithm(BasicObjects.Algorithm):
28
29     def __init__(self):
30         BasicObjects.Algorithm.__init__(self, "UNSCENTEDKALMANFILTER")
31         self.defineRequiredParameter(
32             name     = "Variant",
33             default  = "2UKF",
34             typecast = str,
35             message  = "Variant ou formulation de la méthode",
36             listval  = [
37                 "UKF",
38                 "S3F",
39                 "CUKF", "2UKF",
40                 "CS3F", "2S3F",
41             ],
42             listadv  = [
43                 "UKF-Std",
44                 "MSS",
45                 "CMSS", "2MSS",
46                 "5OS",
47                 "C5OS", "25OS",
48             ],
49         )
50         self.defineRequiredParameter(
51             name     = "EstimationOf",
52             default  = "State",
53             typecast = str,
54             message  = "Estimation d'état ou de paramètres",
55             listval  = ["State", "Parameters"],
56         )
57         self.defineRequiredParameter(
58             name     = "ConstrainedBy",
59             default  = "EstimateProjection",
60             typecast = str,
61             message  = "Prise en compte des contraintes",
62             listval  = ["EstimateProjection"],
63         )
64         self.defineRequiredParameter(
65             name     = "Alpha",
66             default  = 1.e-2,
67             typecast = float,
68             message  = "Coefficient Alpha d'échelle",
69             minval   = 1.e-4,
70             maxval   = 1.,
71         )
72         self.defineRequiredParameter(
73             name     = "Beta",
74             default  = 2,
75             typecast = float,
76             message  = "Coefficient Beta d'information a priori sur la distribution",
77         )
78         self.defineRequiredParameter(
79             name     = "Kappa",
80             default  = 0,
81             typecast = int,
82             message  = "Coefficient Kappa secondaire d'échelle",
83             maxval   = 2,
84         )
85         self.defineRequiredParameter(
86             name     = "Reconditioner",
87             default  = 1.,
88             typecast = float,
89             message  = "Coefficient de reconditionnement",
90             minval   = 1.e-3,
91             maxval   = 1.e+1,
92         )
93         self.defineRequiredParameter(
94             name     = "StoreInternalVariables",
95             default  = False,
96             typecast = bool,
97             message  = "Stockage des variables internes ou intermédiaires du calcul",
98         )
99         self.defineRequiredParameter(
100             name     = "StoreSupplementaryCalculations",
101             default  = [],
102             typecast = tuple,
103             message  = "Liste de calculs supplémentaires à stocker et/ou effectuer",
104             listval  = [
105                 "Analysis",
106                 "APosterioriCorrelations",
107                 "APosterioriCovariance",
108                 "APosterioriStandardDeviations",
109                 "APosterioriVariances",
110                 "BMA",
111                 "CostFunctionJ",
112                 "CostFunctionJAtCurrentOptimum",
113                 "CostFunctionJb",
114                 "CostFunctionJbAtCurrentOptimum",
115                 "CostFunctionJo",
116                 "CostFunctionJoAtCurrentOptimum",
117                 "CurrentOptimum",
118                 "CurrentState",
119                 "ForecastCovariance",
120                 "ForecastState",
121                 "IndexOfOptimum",
122                 "InnovationAtCurrentAnalysis",
123                 "InnovationAtCurrentState",
124                 "SimulatedObservationAtCurrentAnalysis",
125                 "SimulatedObservationAtCurrentOptimum",
126                 "SimulatedObservationAtCurrentState",
127             ]
128         )
129         self.defineRequiredParameter(  # Pas de type
130             name     = "Bounds",
131             message  = "Liste des valeurs de bornes",
132         )
133         self.requireInputArguments(
134             mandatory= ("Xb", "Y", "HO", "R", "B"),
135             optional = ("U", "EM", "CM", "Q"),
136         )
137         self.setAttributes(
138             tags=(
139                 "DataAssimilation",
140                 "NonLinear",
141                 "Filter",
142                 "Ensemble",
143                 "Dynamic",
144                 "Reduction",
145             ),
146             features=(
147                 "LocalOptimization",
148                 "DerivativeFree",
149                 "ParallelAlgorithm",
150                 "ConvergenceOnStatic",
151             ),
152         )
153
154     def run(self, Xb=None, Y=None, U=None, HO=None, EM=None, CM=None, R=None, B=None, Q=None, Parameters=None):
155         self._pre_run(Parameters, Xb, Y, U, HO, EM, CM, R, B, Q)
156         #
157         # --------------------------
158         if self._parameters["Variant"] in ["UKF", "UKF-Std"]:
159             ecwukf.ecwukf(self, Xb, Y, U, HO, EM, CM, R, B, Q, "UKF")
160         #
161         elif self._parameters["Variant"] == "S3F":
162             ecwukf.ecwukf(self, Xb, Y, U, HO, EM, CM, R, B, Q, "S3F")
163         #
164         elif self._parameters["Variant"] == "MSS":
165             ecwukf.ecwukf(self, Xb, Y, U, HO, EM, CM, R, B, Q, "MSS")
166         #
167         elif self._parameters["Variant"] == "5OS":
168             ecwukf.ecwukf(self, Xb, Y, U, HO, EM, CM, R, B, Q, "5OS")
169         #
170         # --------------------------
171         elif self._parameters["Variant"] in ["CUKF", "2UKF"]:
172             ecw2ukf.ecw2ukf(self, Xb, Y, U, HO, EM, CM, R, B, Q, "UKF")
173         #
174         elif self._parameters["Variant"] in ["CS3F", "2S3F"]:
175             ecw2ukf.ecw2ukf(self, Xb, Y, U, HO, EM, CM, R, B, Q, "S3F")
176         #
177         elif self._parameters["Variant"] in ["CMSS", "2MSS"]:
178             ecw2ukf.ecw2ukf(self, Xb, Y, U, HO, EM, CM, R, B, Q, "MSS")
179         #
180         elif self._parameters["Variant"] in ["C5OS", "25OS"]:
181             ecw2ukf.ecw2ukf(self, Xb, Y, U, HO, EM, CM, R, B, Q, "5OS")
182         #
183         # --------------------------
184         else:
185             raise ValueError("Error in Variant name: %s"%self._parameters["Variant"])
186         #
187         self._post_run(HO, EM)
188         return 0
189
190 # ==============================================================================
191 if __name__ == "__main__":
192     print("\n AUTODIAGNOSTIC\n")