From: Jean-Philippe ARGAUD Date: Tue, 15 Dec 2020 20:57:50 +0000 (+0100) Subject: Documentation example extension X-Git-Tag: V9_7_0b1~62 X-Git-Url: http://git.salome-platform.org/gitweb/?a=commitdiff_plain;h=93fa2bb0b4360ca43e9a451d2f806bad18365a9d;p=modules%2Fadao.git Documentation example extension --- diff --git a/doc/en/ref_algorithm_KalmanFilter.rst b/doc/en/ref_algorithm_KalmanFilter.rst index eb958fb..0535b08 100644 --- a/doc/en/ref_algorithm_KalmanFilter.rst +++ b/doc/en/ref_algorithm_KalmanFilter.rst @@ -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]_ diff --git a/doc/en/scripts/simple_KalmanFilter2.py b/doc/en/scripts/simple_KalmanFilter2.py index d0acc80..dbd532e 100644 --- a/doc/en/scripts/simple_KalmanFilter2.py +++ b/doc/en/scripts/simple_KalmanFilter2.py @@ -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 index 0000000..b9aaf66 --- /dev/null +++ b/doc/en/scripts/simple_KalmanFilter2.res @@ -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]] + diff --git a/doc/en/scripts/simple_KalmanFilter2.rst b/doc/en/scripts/simple_KalmanFilter2.rst index bdd55ae..117508f 100644 --- a/doc/en/scripts/simple_KalmanFilter2.rst +++ b/doc/en/scripts/simple_KalmanFilter2.rst @@ -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 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 index 0000000..9b13815 Binary files /dev/null and b/doc/en/scripts/simple_KalmanFilter2_variance.png differ diff --git a/doc/fr/ref_algorithm_KalmanFilter.rst b/doc/fr/ref_algorithm_KalmanFilter.rst index c84f906..9692a5f 100644 --- a/doc/fr/ref_algorithm_KalmanFilter.rst +++ b/doc/fr/ref_algorithm_KalmanFilter.rst @@ -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]_ diff --git a/doc/fr/scripts/simple_KalmanFilter1_state.png b/doc/fr/scripts/simple_KalmanFilter1_state.png index 101a565..5379aff 100644 Binary files a/doc/fr/scripts/simple_KalmanFilter1_state.png and b/doc/fr/scripts/simple_KalmanFilter1_state.png differ diff --git a/doc/fr/scripts/simple_KalmanFilter1_variance.png b/doc/fr/scripts/simple_KalmanFilter1_variance.png index a2d7c49..080c0cd 100644 Binary files a/doc/fr/scripts/simple_KalmanFilter1_variance.png and b/doc/fr/scripts/simple_KalmanFilter1_variance.png differ diff --git a/doc/fr/scripts/simple_KalmanFilter2.py b/doc/fr/scripts/simple_KalmanFilter2.py index 3b2135c..749f22e 100644 --- a/doc/fr/scripts/simple_KalmanFilter2.py +++ b/doc/fr/scripts/simple_KalmanFilter2.py @@ -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 index 0000000..ab3621b --- /dev/null +++ b/doc/fr/scripts/simple_KalmanFilter2.res @@ -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]] + diff --git a/doc/fr/scripts/simple_KalmanFilter2.rst b/doc/fr/scripts/simple_KalmanFilter2.rst index 21cc5a6..29cf97d 100644 --- a/doc/fr/scripts/simple_KalmanFilter2.rst +++ b/doc/fr/scripts/simple_KalmanFilter2.rst @@ -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 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 index 0000000..080c0cd Binary files /dev/null and b/doc/fr/scripts/simple_KalmanFilter2_variance.png differ diff --git a/src/daComposant/daAlgorithms/ExtendedKalmanFilter.py b/src/daComposant/daAlgorithms/ExtendedKalmanFilter.py index a2a39d6..b243668 100644 --- a/src/daComposant/daAlgorithms/ExtendedKalmanFilter.py +++ b/src/daComposant/daAlgorithms/ExtendedKalmanFilter.py @@ -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 diff --git a/src/daComposant/daAlgorithms/KalmanFilter.py b/src/daComposant/daAlgorithms/KalmanFilter.py index 2465136..eadb068 100644 --- a/src/daComposant/daAlgorithms/KalmanFilter.py +++ b/src/daComposant/daAlgorithms/KalmanFilter.py @@ -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