work/mixpp/bdm/estim/libKF.h

Go to the documentation of this file.
00001 
00013 #ifndef KF_H
00014 #define KF_H
00015 
00016 #include <itpp/itbase.h>
00017 #include "../stat/libFN.h"
00018 #include "../math/libDC.h"
00019 
00020 
00021 using namespace itpp;
00022 
00026 class KalmanFull : public BM { 
00027         int dimx, dimy, dimu;
00028         mat A, B, C, D, R, Q;
00029         
00030         //cache 
00031         mat _Pp, _Ry, _iRy, _K;
00032 public:
00033         //posterior 
00035         vec mu;
00037         mat P;
00038 
00039 public:
00041         KalmanFull ( mat A, mat B, mat C, mat D, mat R, mat Q, mat P0, vec mu0);
00043         void bayes(const vec &dt, bool evalll=true); 
00044 
00045         friend std::ostream &operator<< ( std::ostream &os, const KalmanFull &kf );
00046 
00047 };
00048 
00049 
00053 template<class sq_T>
00054 class Kalman : public BM { 
00055 protected:
00056         int dimx, dimy, dimu;
00057         mat A, B, C, D;
00058         sq_T R, Q;
00059         
00060         //cache
00061         mat _K;
00062         vec _yp;
00063         sq_T _Ry,_iRy;
00064 public:
00065         //posterior 
00067         vec mu;
00069         sq_T P;
00070 
00071 public:
00073         Kalman (int dimx, int dimu, int dimy);
00075         Kalman ( mat A0, mat B0, mat C0, mat D0, sq_T R0, sq_T Q0, sq_T P0, vec mu0 );
00077         void bayes(const vec &dt, bool evalll=true); 
00078 
00079         friend std::ostream &operator<< ( std::ostream &os, const KalmanFull &kf );
00080 
00081 };
00082 
00088 template<class sq_T>
00089 class EKF : public Kalman<fsqmat> {
00091         diffbifn* pfxu;
00093         diffbifn* phxu;
00094 public: 
00096         EKF (diffbifn* pfxu, diffbifn* phxu, sq_T Q0, sq_T R0, vec mu0, mat P0);
00098         void bayes(const vec &dt, bool evalll=true);    
00099 };
00100 
00102 
00103 template<class sq_T>
00104 Kalman<sq_T>::Kalman( int dx, int du, int dy): BM(), dimx(dx),dimy(dy),dimu(du){
00105         A = mat(dimx,dimx);
00106         B = mat(dimx,dimu);
00107         C = mat(dimy,dimx);
00108         D = mat(dimy,dimu);
00109 
00110         mu = vec(dimx);
00111         //TODO Initialize the rest?
00112 };
00113 
00114 template<class sq_T>
00115 Kalman<sq_T>::Kalman(const  mat A0,const  mat B0, const mat C0, const mat D0, const sq_T R0, const sq_T Q0, const sq_T P0, const vec mu0 ): BM() {
00116         dimx = A0.rows();
00117         dimu = B0.cols();
00118         dimy = C0.rows();
00119 
00120         it_assert_debug( A0.cols()==dimx, "Kalman: A is not square" );
00121         it_assert_debug( B0.rows()==dimx, "Kalman: B is not compatible" );
00122         it_assert_debug( C0.cols()==dimx, "Kalman: C is not square" );
00123         it_assert_debug(( D0.rows()==dimy ) || ( D0.cols()==dimu ),     "Kalman: D is not compatible" );
00124         it_assert_debug(( R0.cols()==dimy ) || ( R0.rows()==dimy ), "Kalman: R is not compatible" );
00125         it_assert_debug(( Q0.cols()==dimx ) || ( Q0.rows()==dimx ), "Kalman: Q is not compatible" );
00126 
00127         A = A0;
00128         B = B0;
00129         C = C0;
00130         D = D0;
00131         R = R0;
00132         Q = Q0;
00133         mu = mu0;
00134         P = P0;
00135 
00136 //Fixme should we assign cache??
00137         _iRy = eye(dimy); // needed in inv(_iRy)
00138         _Ry = eye(dimy); // needed in inv(_iRy)
00139 }
00140 
00141 template<class sq_T>
00142 void Kalman<sq_T>::bayes( const vec &dt , bool evalll) {
00143         it_assert_debug( dt.length()==( dimy+dimu ),"KalmanFull::bayes wrong size of dt" );
00144 
00145         vec u = dt.get( dimy,dimy+dimu-1 );
00146         vec y = dt.get( 0,dimy-1 );
00147         //Time update
00148         mu = A*mu + B*u;
00149         //P  = A*P*A.transpose() + Q; in sq_T
00150         P.mult_sym( A );
00151         P+=Q;
00152 
00153         //Data update
00154         //_Ry = C*P*C.transpose() + R; in sq_T
00155         P.mult_sym( C, _Ry);
00156         _Ry+=R;
00157 
00158         mat Pfull = P.to_mat();
00159         
00160         _Ry.inv( _iRy ); // result is in _iRy;
00161         _K = Pfull*C.transpose()*(_iRy.to_mat());
00162         P -= _K*C*Pfull; // P = P -KCP;
00163         _yp = y-C*mu-D*u; //y prediction
00164         mu += _K*( _yp );
00165         
00166         if (evalll==true) {
00167         ll+= -0.5*(_Ry.cols()*0.79817986835811504957 \
00168         +_Ry.logdet() +_iRy.qform(_yp));
00169         }
00170 };
00171 
00172 //TODO why not const pointer??
00173 
00174 template<class sq_T>
00175 EKF<sq_T>::EKF( diffbifn* pfxu0,  diffbifn* phxu0, sq_T Q0, sq_T R0, vec mu0, mat P0): pfxu(pfxu0), phxu(phxu0), Kalman<fsqmat>(pfxu0->_dimx(),pfxu0->_dimu(),phxu0->_dimy()) {
00176                 
00177                 //initialize matrices A C, later, these will be only updated!
00178                 pfxu->dfdx_cond(mu,zeros(dimu),A,true);
00179                 pfxu->dfdu_cond(mu,zeros(dimu),B,true);
00180                 phxu->dfdx_cond(mu,zeros(dimu),C,true);
00181                 phxu->dfdu_cond(mu,zeros(dimu),D,true);
00182                 
00183 
00184                 R = R0;
00185                 Q = Q0;
00186                 mu = mu0;
00187                 P = P0;
00188 
00189         using std::cout;
00190         cout<<A<<std::endl;
00191         cout<<B<<std::endl;
00192         cout<<C<<std::endl;
00193         cout<<D<<std::endl;
00194 
00195 }
00196 
00197 template<class sq_T>
00198 void EKF<sq_T>::bayes( const vec &dt , bool evalll) {
00199         it_assert_debug( dt.length()==( dimy+dimu ),"KalmanFull::bayes wrong size of dt" );
00200 
00201         vec u = dt.get( dimy,dimy+dimu-1 );
00202         vec y = dt.get( 0,dimy-1 );
00203         //Time update
00204         mu = pfxu->eval(mu, u);
00205         pfxu->dfdx_cond(mu,u,A,false); //update A by a derivative of fx
00206         
00207         //P  = A*P*A.transpose() + Q; in sq_T
00208         P.mult_sym( A );
00209         P+=Q;
00210 
00211         //Data update
00212         phxu->dfdx_cond(mu,u,C,false); //update C by a derivative hx
00213         //_Ry = C*P*C.transpose() + R; in sq_T
00214         P.mult_sym( C, _Ry);
00215         _Ry+=R;
00216 
00217         mat Pfull = P.to_mat();
00218         
00219         _Ry.inv( _iRy ); // result is in _iRy;
00220         _K = Pfull*C.transpose()*(_iRy.to_mat());
00221         P -= _K*C*Pfull; // P = P -KCP;
00222         _yp = y-phxu->eval(mu,u); //y prediction
00223         mu += _K*( _yp );
00224         
00225         if (evalll==true) {
00226         ll+= -0.5*(_Ry.cols()*0.79817986835811504957 \
00227         +_Ry.logdet() +_iRy.qform(_yp));
00228         }
00229 };
00230 
00231 
00232 #endif // KF_H
00233 
00234 

Generated on Mon Feb 18 21:48:39 2008 for mixpp by  doxygen 1.5.3