]> SALOME platform Git repositories - modules/adao.git/commitdiff
Salome HOME
Documentation example extension
authorJean-Philippe ARGAUD <jean-philippe.argaud@edf.fr>
Tue, 15 Dec 2020 20:57:50 +0000 (21:57 +0100)
committerJean-Philippe ARGAUD <jean-philippe.argaud@edf.fr>
Tue, 15 Dec 2020 21:11:02 +0000 (22:11 +0100)
16 files changed:
doc/en/ref_algorithm_KalmanFilter.rst
doc/en/scripts/simple_KalmanFilter2.py
doc/en/scripts/simple_KalmanFilter2.res [new file with mode: 0644]
doc/en/scripts/simple_KalmanFilter2.rst
doc/en/scripts/simple_KalmanFilter2_state.png [new file with mode: 0644]
doc/en/scripts/simple_KalmanFilter2_variance.png [new file with mode: 0644]
doc/fr/ref_algorithm_KalmanFilter.rst
doc/fr/scripts/simple_KalmanFilter1_state.png
doc/fr/scripts/simple_KalmanFilter1_variance.png
doc/fr/scripts/simple_KalmanFilter2.py
doc/fr/scripts/simple_KalmanFilter2.res [new file with mode: 0644]
doc/fr/scripts/simple_KalmanFilter2.rst
doc/fr/scripts/simple_KalmanFilter2_state.png [new file with mode: 0644]
doc/fr/scripts/simple_KalmanFilter2_variance.png [new file with mode: 0644]
src/daComposant/daAlgorithms/ExtendedKalmanFilter.py
src/daComposant/daAlgorithms/KalmanFilter.py

index eb958fb09dbefa58774ab614474557df2e240b22..0535b08b2122ce6d08a5ed2c18a775217fb9a4b8 100644 (file)
@@ -200,6 +200,22 @@ StoreSupplementaryCalculations
 
 .. literalinclude:: scripts/simple_KalmanFilter2.py
 
+.. include:: snippets/Header2Algo10.rst
+
+.. literalinclude:: scripts/simple_KalmanFilter2.res
+
+.. include:: snippets/Header2Algo11.rst
+
+.. _simple_KalmanFilter2_state:
+.. image:: scripts/simple_KalmanFilter2_state.png
+  :align: center
+  :width: 90%
+
+.. _simple_KalmanFilter2_variance:
+.. image:: scripts/simple_KalmanFilter2_variance.png
+  :align: center
+  :width: 90%
+
 .. ------------------------------------ ..
 .. include:: snippets/Header2Algo06.rst
 
@@ -210,4 +226,5 @@ StoreSupplementaryCalculations
 .. ------------------------------------ ..
 .. include:: snippets/Header2Algo07.rst
 
+- [Welch06]_
 - [WikipediaKF]_
index d0acc805fc3830104ace6c03bed03052f177548a..dbd532ee4991a7ceb0d4b912ab85f43d3daed6d1 100644 (file)
@@ -29,6 +29,11 @@ case.setAlgorithmParameters(
             ],
         },
     )
+case.setObserver(
+    Info="  Analyzed state at current observation:",
+    Template='ValuePrinter',
+    Variable='Analysis',
+    )
 #
 XaStep, VaStep = 0., 1.
 for i in range(1,len(Yobs)):
@@ -45,3 +50,31 @@ Pa = case.get("APosterioriCovariance")
 print("")
 print("  Final a posteriori variance:",Pa[-1])
 print("")
+#
+#-------------------------------------------------------------------------------
+#
+Observations = array([yo[0]   for yo in Yobs])
+Estimates    = array([xa[0]   for xa in case.get("Analysis")])
+Variances    = array([pa[0,0] for pa in case.get("APosterioriCovariance")])
+#
+import matplotlib.pyplot as plt
+plt.rcParams['figure.figsize'] = (10, 4)
+#
+plt.figure()
+plt.plot(Observations,'kx',label='Noisy measurements')
+plt.plot(Estimates,'r-',label='Estimated state')
+plt.axhline(Xtrue,color='b',label='Truth value')
+plt.legend()
+plt.title('Estimate of the state', fontweight='bold')
+plt.xlabel('Observation step')
+plt.ylabel('Voltage')
+plt.savefig("simple_KalmanFilter2_state.png")
+#
+plt.figure()
+iobs = range(1,len(Observations))
+plt.plot(iobs,Variances[iobs],label='A posteriori error variance')
+plt.title('Estimate of the a posteriori error variance', fontweight='bold')
+plt.xlabel('Observation step')
+plt.ylabel('$(Voltage)^2$')
+plt.setp(plt.gca(),'ylim',[0,.01])
+plt.savefig("simple_KalmanFilter2_variance.png")
diff --git a/doc/en/scripts/simple_KalmanFilter2.res b/doc/en/scripts/simple_KalmanFilter2.res
new file mode 100644 (file)
index 0000000..b9aaf66
--- /dev/null
@@ -0,0 +1,58 @@
+Estimation of a constant variable by filtering
+----------------------------------------------
+  Noisy measurements acquired on 50 time steps
+
+  Analyzed state at current observation: [0.]
+  Analyzed state at current observation: [-0.41804504]
+  Analyzed state at current observation: [-0.3114053]
+  Analyzed state at current observation: [-0.31191336]
+  Analyzed state at current observation: [-0.32761493]
+  Analyzed state at current observation: [-0.33597167]
+  Analyzed state at current observation: [-0.35629573]
+  Analyzed state at current observation: [-0.36840289]
+  Analyzed state at current observation: [-0.37392713]
+  Analyzed state at current observation: [-0.36331937]
+  Analyzed state at current observation: [-0.35750362]
+  Analyzed state at current observation: [-0.37963052]
+  Analyzed state at current observation: [-0.37117993]
+  Analyzed state at current observation: [-0.36732985]
+  Analyzed state at current observation: [-0.37148382]
+  Analyzed state at current observation: [-0.36798059]
+  Analyzed state at current observation: [-0.37371077]
+  Analyzed state at current observation: [-0.3661228]
+  Analyzed state at current observation: [-0.36777529]
+  Analyzed state at current observation: [-0.37681677]
+  Analyzed state at current observation: [-0.37007654]
+  Analyzed state at current observation: [-0.37974517]
+  Analyzed state at current observation: [-0.37964703]
+  Analyzed state at current observation: [-0.37514278]
+  Analyzed state at current observation: [-0.38143128]
+  Analyzed state at current observation: [-0.38790654]
+  Analyzed state at current observation: [-0.38880008]
+  Analyzed state at current observation: [-0.38393577]
+  Analyzed state at current observation: [-0.3831028]
+  Analyzed state at current observation: [-0.37680097]
+  Analyzed state at current observation: [-0.37891813]
+  Analyzed state at current observation: [-0.38147782]
+  Analyzed state at current observation: [-0.37981569]
+  Analyzed state at current observation: [-0.38274266]
+  Analyzed state at current observation: [-0.38418507]
+  Analyzed state at current observation: [-0.38923054]
+  Analyzed state at current observation: [-0.38400006]
+  Analyzed state at current observation: [-0.38562502]
+  Analyzed state at current observation: [-0.3840503]
+  Analyzed state at current observation: [-0.38775222]
+  Analyzed state at current observation: [-0.37700787]
+  Analyzed state at current observation: [-0.37328191]
+  Analyzed state at current observation: [-0.38024181]
+  Analyzed state at current observation: [-0.3815806]
+  Analyzed state at current observation: [-0.38392063]
+  Analyzed state at current observation: [-0.38539266]
+  Analyzed state at current observation: [-0.37856929]
+  Analyzed state at current observation: [-0.37744505]
+  Analyzed state at current observation: [-0.37154554]
+  Analyzed state at current observation: [-0.37405773]
+  Analyzed state at current observation: [-0.37725236]
+
+  Final a posteriori variance: [[0.00033921]]
+
index bdd55aecf3b07626c60fbea61425ba8e58ce2a0b..117508f322d7d65bf7536c41642c4ae91701738c 100644 (file)
@@ -8,3 +8,7 @@ execution of a Kalman step at the arrival of each observation provided
 iteratively. The keyword "*nextStep*", included in the execution order, allows
 to not store the background in duplicate of the previous analysis.
 
+In a completely similar way to the reanalysis, the estimate is made in
+displaying intermediate results during iterative filtering. Thanks to these
+intermediate information, one can also obtain the graphs illustrating the
+estimation of the state and the associated *a posteriori* error covariance.
diff --git a/doc/en/scripts/simple_KalmanFilter2_state.png b/doc/en/scripts/simple_KalmanFilter2_state.png
new file mode 100644 (file)
index 0000000..fce0c7c
Binary files /dev/null and b/doc/en/scripts/simple_KalmanFilter2_state.png differ
diff --git a/doc/en/scripts/simple_KalmanFilter2_variance.png b/doc/en/scripts/simple_KalmanFilter2_variance.png
new file mode 100644 (file)
index 0000000..9b13815
Binary files /dev/null and b/doc/en/scripts/simple_KalmanFilter2_variance.png differ
index c84f906e1df03bc16deb04c85133a79e8e84e8c9..9692a5fac437d575b1b20ee5cc981ddb88d81446 100644 (file)
@@ -201,6 +201,22 @@ StoreSupplementaryCalculations
 
 .. literalinclude:: scripts/simple_KalmanFilter2.py
 
+.. include:: snippets/Header2Algo10.rst
+
+.. literalinclude:: scripts/simple_KalmanFilter2.res
+
+.. include:: snippets/Header2Algo11.rst
+
+.. _simple_KalmanFilter2_state:
+.. image:: scripts/simple_KalmanFilter2_state.png
+  :align: center
+  :width: 90%
+
+.. _simple_KalmanFilter2_variance:
+.. image:: scripts/simple_KalmanFilter2_variance.png
+  :align: center
+  :width: 90%
+
 .. ------------------------------------ ..
 .. include:: snippets/Header2Algo06.rst
 
@@ -211,4 +227,5 @@ StoreSupplementaryCalculations
 .. ------------------------------------ ..
 .. include:: snippets/Header2Algo07.rst
 
+- [Welch06]_
 - [WikipediaKF]_
index 101a565ae2eea36168f92db0b9ec7e37687f2b75..5379aff4b252458102ec26f0718862507e8b20b5 100644 (file)
Binary files a/doc/fr/scripts/simple_KalmanFilter1_state.png and b/doc/fr/scripts/simple_KalmanFilter1_state.png differ
index a2d7c49c9f6aabbc4eac11fcee343c9d86c19799..080c0cd661c3ed24b1dce63dde700bd1be5ef268 100644 (file)
Binary files a/doc/fr/scripts/simple_KalmanFilter1_variance.png and b/doc/fr/scripts/simple_KalmanFilter1_variance.png differ
index 3b2135c7365f006788b546b8b52a956617acd7e8..749f22e466195c6168e075833cf3b55d89d8ca72 100644 (file)
@@ -29,6 +29,11 @@ case.setAlgorithmParameters(
             ],
         },
     )
+case.setObserver(
+    Info="  État analysé à l'observation courante :",
+    Template='ValuePrinter',
+    Variable='Analysis',
+    )
 #
 XaStep, VaStep = 0., 1.
 for i in range(1,len(Yobs)):
@@ -45,3 +50,31 @@ Pa = case.get("APosterioriCovariance")
 print("")
 print("  Variance a posteriori finale :",Pa[-1])
 print("")
+#
+#-------------------------------------------------------------------------------
+#
+Observations = array([yo[0]   for yo in Yobs])
+Estimates    = array([xa[0]   for xa in case.get("Analysis")])
+Variances    = array([pa[0,0] for pa in case.get("APosterioriCovariance")])
+#
+import matplotlib.pyplot as plt
+plt.rcParams['figure.figsize'] = (10, 4)
+#
+plt.figure()
+plt.plot(Observations,'kx',label='Mesures bruitées')
+plt.plot(Estimates,'r-',label='État estimé')
+plt.axhline(Xtrue,color='b',label='Valeur vraie')
+plt.legend()
+plt.title('Estimation de l\'état', fontweight='bold')
+plt.xlabel('Pas d\'observation')
+plt.ylabel('Tension')
+plt.savefig("simple_KalmanFilter2_state.png")
+#
+plt.figure()
+iobs = range(1,len(Observations))
+plt.plot(iobs,Variances[iobs],label='Variance d\'erreur a posteriori')
+plt.title('Estimation de la variance d\'erreur a posteriori', fontweight='bold')
+plt.xlabel('Pas d\'observation')
+plt.ylabel('$(Tension)^2$')
+plt.setp(plt.gca(),'ylim',[0,.01])
+plt.savefig("simple_KalmanFilter2_variance.png")
diff --git a/doc/fr/scripts/simple_KalmanFilter2.res b/doc/fr/scripts/simple_KalmanFilter2.res
new file mode 100644 (file)
index 0000000..ab3621b
--- /dev/null
@@ -0,0 +1,58 @@
+Estimation par filtrage d'une variable constante
+------------------------------------------------
+  Observations bruitées acquises sur 50 pas de temps
+
+  État analysé à l'observation courante : [0.]
+  État analysé à l'observation courante : [-0.41804504]
+  État analysé à l'observation courante : [-0.3114053]
+  État analysé à l'observation courante : [-0.31191336]
+  État analysé à l'observation courante : [-0.32761493]
+  État analysé à l'observation courante : [-0.33597167]
+  État analysé à l'observation courante : [-0.35629573]
+  État analysé à l'observation courante : [-0.36840289]
+  État analysé à l'observation courante : [-0.37392713]
+  État analysé à l'observation courante : [-0.36331937]
+  État analysé à l'observation courante : [-0.35750362]
+  État analysé à l'observation courante : [-0.37963052]
+  État analysé à l'observation courante : [-0.37117993]
+  État analysé à l'observation courante : [-0.36732985]
+  État analysé à l'observation courante : [-0.37148382]
+  État analysé à l'observation courante : [-0.36798059]
+  État analysé à l'observation courante : [-0.37371077]
+  État analysé à l'observation courante : [-0.3661228]
+  État analysé à l'observation courante : [-0.36777529]
+  État analysé à l'observation courante : [-0.37681677]
+  État analysé à l'observation courante : [-0.37007654]
+  État analysé à l'observation courante : [-0.37974517]
+  État analysé à l'observation courante : [-0.37964703]
+  État analysé à l'observation courante : [-0.37514278]
+  État analysé à l'observation courante : [-0.38143128]
+  État analysé à l'observation courante : [-0.38790654]
+  État analysé à l'observation courante : [-0.38880008]
+  État analysé à l'observation courante : [-0.38393577]
+  État analysé à l'observation courante : [-0.3831028]
+  État analysé à l'observation courante : [-0.37680097]
+  État analysé à l'observation courante : [-0.37891813]
+  État analysé à l'observation courante : [-0.38147782]
+  État analysé à l'observation courante : [-0.37981569]
+  État analysé à l'observation courante : [-0.38274266]
+  État analysé à l'observation courante : [-0.38418507]
+  État analysé à l'observation courante : [-0.38923054]
+  État analysé à l'observation courante : [-0.38400006]
+  État analysé à l'observation courante : [-0.38562502]
+  État analysé à l'observation courante : [-0.3840503]
+  État analysé à l'observation courante : [-0.38775222]
+  État analysé à l'observation courante : [-0.37700787]
+  État analysé à l'observation courante : [-0.37328191]
+  État analysé à l'observation courante : [-0.38024181]
+  État analysé à l'observation courante : [-0.3815806]
+  État analysé à l'observation courante : [-0.38392063]
+  État analysé à l'observation courante : [-0.38539266]
+  État analysé à l'observation courante : [-0.37856929]
+  État analysé à l'observation courante : [-0.37744505]
+  État analysé à l'observation courante : [-0.37154554]
+  État analysé à l'observation courante : [-0.37405773]
+  État analysé à l'observation courante : [-0.37725236]
+
+  Variance a posteriori finale : [[0.00033921]]
+
index 21cc5a6d5f86ffd4f00be4300107649bd78b7245..29cf97d88636d98817581044dcc663dc567b2663 100644 (file)
@@ -8,3 +8,7 @@ l'exécution d'une étape de Kalman à l'arrivée de chaque observation fournie
 itérativement. Le mot-clé "*nextStep*", inclut dans l'ordre d'exécution, permet
 de ne pas stocker l'ébauche en double de l'analyse précédente.
 
+De manière entièrement similaire à la réanalyse, l'estimation s'effectue en
+affichant des résultats intermédiaires lors du filtrage itératif. Grâce à ces
+informations intermédiaires, on peut aussi obtenir les graphiques illustrant
+l'estimation de l'état et de la covariance d'erreur *a posteriori* associée.
diff --git a/doc/fr/scripts/simple_KalmanFilter2_state.png b/doc/fr/scripts/simple_KalmanFilter2_state.png
new file mode 100644 (file)
index 0000000..5379aff
Binary files /dev/null and b/doc/fr/scripts/simple_KalmanFilter2_state.png differ
diff --git a/doc/fr/scripts/simple_KalmanFilter2_variance.png b/doc/fr/scripts/simple_KalmanFilter2_variance.png
new file mode 100644 (file)
index 0000000..080c0cd
Binary files /dev/null and b/doc/fr/scripts/simple_KalmanFilter2_variance.png differ
index a2a39d608602e29f03dcfa195b5ec39322738336..b243668be28a119a5aaf8dee0c0e545b10a902d1 100644 (file)
@@ -196,18 +196,16 @@ class ElementaryAlgorithm(BasicObjects.Algorithm):
                 if Cm is not None and Un is not None: # Attention : si Cm est aussi dans H, doublon !
                     _Innovation = _Innovation - Cm * Un
             #
-            _A = R + numpy.dot(Ht, Pn_predicted * Ha)
-            _u = numpy.linalg.solve( _A , _Innovation )
-            Xn = Xn_predicted + Pn_predicted * Ha * _u
-            Kn = Pn_predicted * Ha * (R + numpy.dot(Ht, Pn_predicted * Ha)).I
+            Kn = Pn_predicted * Ha * numpy.linalg.inv(R + numpy.dot(Ht, Pn_predicted * Ha))
+            Xn = Xn_predicted + Kn * _Innovation
             Pn = Pn_predicted - Kn * Ht * Pn_predicted
-            Xa, _HXa = Xn, _HX # Pointeurs
+            Xa = Xn # Pointeurs
             #
             self.StoredVariables["CurrentIterationNumber"].store( len(self.StoredVariables["Analysis"]) )
             # ---> avec analysis
             self.StoredVariables["Analysis"].store( Xa )
             if self._toStore("SimulatedObservationAtCurrentAnalysis"):
-                self.StoredVariables["SimulatedObservationAtCurrentAnalysis"].store( _HXa )
+                self.StoredVariables["SimulatedObservationAtCurrentAnalysis"].store( Hm((Xn, None)) )
             if self._toStore("InnovationAtCurrentAnalysis"):
                 self.StoredVariables["InnovationAtCurrentAnalysis"].store( _Innovation )
             # ---> avec current state
index 2465136045de35c2213c99c28c38c841708f82f2..eadb0689450f03d41e2c45a047724287b62ef5cb 100644 (file)
@@ -171,18 +171,16 @@ class ElementaryAlgorithm(BasicObjects.Algorithm):
                 if Cm is not None and Un is not None: # Attention : si Cm est aussi dans H, doublon !
                     _Innovation = _Innovation - Cm * Un
             #
-            _A = R + numpy.dot(Ht, Pn_predicted * Ha)
-            _u = numpy.linalg.solve( _A , _Innovation )
-            Xn = Xn_predicted + Pn_predicted * Ha * _u
-            Kn = Pn_predicted * Ha * (R + numpy.dot(Ht, Pn_predicted * Ha)).I
+            Kn = Pn_predicted * Ha * numpy.linalg.inv(R + numpy.dot(Ht, Pn_predicted * Ha))
+            Xn = Xn_predicted + Kn * _Innovation
             Pn = Pn_predicted - Kn * Ht * Pn_predicted
-            Xa, _HXa = Xn, _HX # Pointeurs
+            Xa = Xn # Pointeurs
             #
             self.StoredVariables["CurrentIterationNumber"].store( len(self.StoredVariables["Analysis"]) )
             # ---> avec analysis
             self.StoredVariables["Analysis"].store( Xa )
             if self._toStore("SimulatedObservationAtCurrentAnalysis"):
-                self.StoredVariables["SimulatedObservationAtCurrentAnalysis"].store( _HXa )
+                self.StoredVariables["SimulatedObservationAtCurrentAnalysis"].store( Ht * Xn )
             if self._toStore("InnovationAtCurrentAnalysis"):
                 self.StoredVariables["InnovationAtCurrentAnalysis"].store( _Innovation )
             # ---> avec current state