00001 #ifndef INDII_ML_FILTER_KALMANSMOOTHER_HPP
00002 #define INDII_ML_FILTER_KALMANSMOOTHER_HPP
00003
00004 #include "TwoFilterSmoother.hpp"
00005 #include "KalmanSmootherModel.hpp"
00006
00007 namespace indii {
00008 namespace ml {
00009 namespace filter {
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037 template <class T>
00038 class KalmanSmoother : public TwoFilterSmoother<T> {
00039 public:
00040
00041
00042
00043
00044
00045
00046
00047
00048 KalmanSmoother(KalmanSmootherModel<T>* model,
00049 const T tT, const indii::ml::aux::GaussianPdf& p_xT);
00050
00051
00052
00053
00054 virtual ~KalmanSmoother();
00055
00056 virtual void smooth(const T tn, const indii::ml::aux::vector& ytn,
00057 const indii::ml::aux::GaussianPdf& p_xtn_ytn);
00058
00059 virtual indii::ml::aux::GaussianPdf backwardMeasure();
00060
00061 virtual indii::ml::aux::GaussianPdf smoothedMeasure();
00062
00063 private:
00064
00065
00066
00067 KalmanSmootherModel<T>* model;
00068
00069
00070
00071
00072 const unsigned int N;
00073 };
00074
00075 }
00076 }
00077 }
00078
00079 template <class T>
00080 indii::ml::filter::KalmanSmoother<T>::KalmanSmoother(
00081 KalmanSmootherModel<T>* model, const T tT,
00082 const indii::ml::aux::GaussianPdf& p_xT) :
00083 TwoFilterSmoother<T>(tT, p_xT), model(model), N(p_xT.getDimensions()) {
00084
00085 }
00086
00087 template <class T>
00088 indii::ml::filter::KalmanSmoother<T>::~KalmanSmoother() {
00089
00090 }
00091
00092 template <class T>
00093 void indii::ml::filter::KalmanSmoother<T>::smooth(const T tn,
00094 const indii::ml::aux::vector& ytn,
00095 const indii::ml::aux::GaussianPdf& p_xtn_ytn) {
00096 namespace aux = indii::ml::aux;
00097
00098
00099 assert (tn < this->tn);
00100
00101 T delta = this->tn - tn;
00102 this->tn = tn;
00103
00104
00105 aux::GaussianPdf p_xtn_ytnp1_b(model->p_xtnm1_ytn(this->p_xtn_ytn_b,
00106 delta));
00107 this->p_xtn_ytn_b = model->p_xtnm1_ytnm1(p_xtn_ytnp1_b, ytn, delta);
00108
00109
00110 const aux::symmetric_matrix& P_xtn_ytn = p_xtn_ytn.getCovariance();
00111 const aux::symmetric_matrix& P_xtn_ytnp1_b = p_xtn_ytnp1_b.getCovariance();
00112 aux::matrix PI_xtn_ytn(N,N);
00113 aux::matrix PI_xtn_ytnp1_b(N,N);
00114 aux::matrix X(N,N);
00115
00116
00117 noalias(X) = P_xtn_ytn;
00118 aux::inv(X, PI_xtn_ytn);
00119
00120 noalias(X) = P_xtn_ytnp1_b;
00121 aux::inv(X, PI_xtn_ytnp1_b);
00122
00123
00124 aux::symmetric_matrix P_xtn_ytT(N);
00125 aux::matrix Y(N,N);
00126 noalias(Y) = PI_xtn_ytn + PI_xtn_ytnp1_b;
00127
00128
00129
00130 aux::inv(Y, X);
00131 noalias(P_xtn_ytT) = X;
00132
00133
00134 const aux::vector& x_xtn_ytn = p_xtn_ytn.getExpectation();
00135 const aux::vector& x_xtn_ytnp1_b = p_xtn_ytnp1_b.getExpectation();
00136 aux::vector x_xtn_ytT(N);
00137
00138 noalias(x_xtn_ytT) = prod(PI_xtn_ytn, x_xtn_ytn);
00139 noalias(x_xtn_ytT) += prod(PI_xtn_ytnp1_b, x_xtn_ytnp1_b);
00140 x_xtn_ytT = prod(P_xtn_ytT, x_xtn_ytT);
00141
00142
00143 this->p_xtn_ytT.setExpectation(x_xtn_ytT);
00144 this->p_xtn_ytT.setCovariance(P_xtn_ytT);
00145
00146
00147 assert (this->tn == tn);
00148 }
00149
00150 template <class T>
00151 indii::ml::aux::GaussianPdf
00152 indii::ml::filter::KalmanSmoother<T>::smoothedMeasure() {
00153 return model->p_y_x(this->p_xtn_ytT);
00154 }
00155
00156 template <class T>
00157 indii::ml::aux::GaussianPdf
00158 indii::ml::filter::KalmanSmoother<T>::backwardMeasure() {
00159 return model->p_y_x(this->p_xtn_ytn_b);
00160 }
00161
00162 #endif