Legend:
- Unmodified
- Added
- Removed
-
bdm/estim/libKF.cpp
r32 r37 26 26 mu = mu0; 27 27 P = P0; 28 29 ll = 0.0; 30 evalll=true; 28 31 } 29 32 … … 43 46 P -= _K*C*P; // P = P -KCP; 44 47 mu += _K* ( y-C*mu-D*u ); 48 49 if ( evalll ) { 50 //from enorm 51 vec x=y-C*mu-D*u; 52 ll = -0.5* ( R.cols() * 1.83787706640935 +log ( det ( _Ry ) ) +x* ( _iRy*x ) ); 53 } 45 54 }; 46 55 … … 50 59 } 51 60 61 void KalmanCh::set_parameters ( const mat &A0,const mat &B0,const mat &C0,const mat &D0,const chmat &R0,const chmat &Q0 ) { 62 63 ( ( Kalman<chmat>* ) this )->set_parameters ( A0,B0,C0,D0,R0,Q0 ); 64 // Cholesky special! 65 preA.clear(); 66 preA.set_submatrix ( 0,0,R._Ch() ); 67 preA.set_submatrix ( dimy+dimx,dimy,Q._Ch() ); 68 } 69 70 71 void KalmanCh::bayes ( const vec &dt ) { 72 73 vec u = dt.get ( dimy,dimy+dimu-1 ); 74 vec y = dt.get ( 0,dimy-1 ); 75 76 //TODO get rid of Q in qr()! 77 // mat Q; 78 79 //R and Q are already set in set_parameters() 80 preA.set_submatrix ( dimy,0, ( _P->_Ch() ) *C.T() ); 81 //Fixme can be more efficient if .T() is not used 82 preA.set_submatrix ( dimy,dimy, ( _P->_Ch() ) *A.T() ); 83 84 // if ( !qr ( preA,Q,postA ) ) it_warning ( "QR in kalman unstable!" ); 85 if ( !qr ( preA,postA ) ) it_warning ( "QR in kalman unstable!" ); 86 87 ( _Ry->_Ch() ) =postA ( 0,dimy-1, 0,dimy-1 ); 88 _K = ( postA ( 0,dimy-1 ,dimy,dimy+dimx-1 ) ).T(); 89 ( _P->_Ch() ) = postA ( dimy,dimy+dimx-1,dimy,dimy+dimx-1 ); 90 _Ry->inv ( *_iRy ); 91 fy._cached ( true ); 92 *_mu = A* ( *_mu ) + B*u + ( _K ) * ( _iRy->_Ch() ).T() * ( y-C* ( *_mu )-D*u ); 93 94 /* cout << "P:" <<_P->to_mat() <<endl; 95 cout << "Ry:" <<_Ry->to_mat() <<endl; 96 cout << "iRy:" <<_iRy->to_mat() <<endl;*/ 97 if ( evalll==true ) { //likelihood of observation y 98 ll=fy.evalpdflog ( y ); 99 } 100 } 101 102 103 EKFCh::EKFCh ( RV rvx0, RV rvy0, RV rvu0 ) : KalmanCh ( rvx0,rvy0,rvu0 ) {} 104 105 void EKFCh::set_parameters ( diffbifn* pfxu0, diffbifn* phxu0,const chmat Q0,const chmat R0 ) { 106 pfxu = pfxu0; 107 phxu = phxu0; 108 109 //initialize matrices A C, later, these will be only updated! 110 pfxu->dfdx_cond ( *_mu,zeros ( dimu ),A,true ); 111 // pfxu->dfdu_cond ( *_mu,zeros ( dimu ),B,true ); 112 B.clear(); 113 phxu->dfdx_cond ( *_mu,zeros ( dimu ),C,true ); 114 // phxu->dfdu_cond ( *_mu,zeros ( dimu ),D,true ); 115 D.clear(); 116 117 R = R0; 118 Q = Q0; 119 120 // Cholesky special! 121 preA.clear(); 122 preA.set_submatrix ( 0,0,R._Ch() ); 123 preA.set_submatrix ( dimy+dimx,dimy,Q._Ch() ); 124 } 125 126 127 void EKFCh::bayes ( const vec &dt ) { 128 129 vec u = dt.get ( dimy,dimy+dimu-1 ); 130 vec y = dt.get ( 0,dimy-1 ); 131 132 //TODO get rid of Q in qr()! 133 // mat Q; 134 135 //R and Q are already set in set_parameters() 136 preA.set_submatrix ( dimy,0, ( _P->_Ch() ) *C.T() ); 137 //Fixme can be more efficient if .T() is not used 138 preA.set_submatrix ( dimy,dimy, ( _P->_Ch() ) *A.T() ); 139 140 // if ( !qr ( preA,Q,postA ) ) it_warning ( "QR in kalman unstable!" ); 141 if ( !qr ( preA,postA ) ) it_warning ( "QR in kalman unstable!" ); 142 143 ( _Ry->_Ch() ) =postA ( 0,dimy-1, 0,dimy-1 ); 144 _K = ( postA ( 0,dimy-1 ,dimy,dimy+dimx-1 ) ).T(); 145 ( _P->_Ch() ) = postA ( dimy,dimy+dimx-1,dimy,dimy+dimx-1 ); 146 _Ry->inv ( *_iRy ); 147 fy._cached ( true ); 148 *_yp = phxu->eval ( *_mu,u ); 149 *_mu = pfxu->eval ( *_mu ,u ) + ( _K ) * ( _iRy->_Ch() ).T() * ( y-*_yp ); 150 151 /* cout << "P:" <<_P->to_mat() <<endl; 152 cout << "Ry:" <<_Ry->to_mat() <<endl; 153 cout << "iRy:" <<_iRy->to_mat() <<endl;*/ 154 155 if ( evalll==true ) { //likelihood of observation y 156 ll=fy.evalpdflog ( y ); 157 } 158 } 159 52 160 void KFcondQR::condition ( const vec &QR ) { 53 161 it_assert_debug ( QR.length() == ( rvc.count() ),"KFcondRQ: conditioning by incompatible vector" ); 54 162 55 Q.setD ( QR ( 0, dimx-1 ) );56 R.setD ( QR ( dimx, -1 ) );163 Q.setD ( QR ( 0, dimx-1 ) ); 164 R.setD ( QR ( dimx, -1 ) ); 57 165 }; 58 166 -
bdm/estim/libKF.h
r33 r37 17 17 #include "../stat/libFN.h" 18 18 #include "../stat/libEF.h" 19 19 #include "../math/chmat.h" 20 20 21 21 using namespace itpp; … … 38 38 mat P; 39 39 40 bool evalll; 41 double ll; 40 42 public: 41 43 //! Full constructor … … 124 126 }; 125 127 128 /*! \brief Kalman filter in square root form 129 */ 130 class KalmanCh : public Kalman<chmat>{ 131 protected: 132 //! pre array (triangular matrix) 133 mat preA; 134 //! post array (triangular matrix) 135 mat postA; 136 137 public: 138 //! Default constructor 139 KalmanCh ( RV rvx0, RV rvy0, RV rvu0 ):Kalman<chmat>(rvx0,rvy0,rvu0),preA(dimy+dimx+dimx,dimy+dimx),postA(dimy+dimx,dimy+dimx){}; 140 //! Set parameters with check of relevance 141 void set_parameters ( const mat &A0,const mat &B0,const mat &C0,const mat &D0,const chmat &R0,const chmat &Q0 ); 142 void set_est ( const vec &mu0, const chmat &P0 ) { 143 est.set_parameters ( mu0,P0 ); 144 }; 145 146 147 /*!\brief Here dt = [yt;ut] of appropriate dimensions 148 149 The following equality hold::\f[ 150 \left[\begin{array}{cc} 151 R^{0.5}\\ 152 P_{t|t-1}^{0.5}C' & P_{t|t-1}^{0.5}CA'\\ 153 & Q^{0.5}\end{array}\right]<\mathrm{orth.oper.}>=\left[\begin{array}{cc} 154 R_{y}^{0.5} & KA'\\ 155 & P_{t+1|t}^{0.5}\\ 156 \\\end{array}\right]\f] 157 158 Thus this objevt evaluates only predictors! Not filtering densities. 159 */ 160 void bayes ( const vec &dt ); 161 }; 162 126 163 /*! 127 164 \brief Extended Kalman Filter … … 130 167 */ 131 168 template<class sq_T> 132 133 169 class EKF : public Kalman<ldmat> { 134 170 //! Internal Model f(x,u) … … 146 182 147 183 /*! 184 \brief Extended Kalman Filter in Square roor 185 186 An approximation of the exact Bayesian filter with Gaussian noices and non-linear evolutions of their mean. 187 */ 188 189 class EKFCh : public KalmanCh { 190 //! Internal Model f(x,u) 191 diffbifn* pfxu; 192 //! Observation Model h(x,u) 193 diffbifn* phxu; 194 public: 195 //! Default constructor 196 EKFCh ( RV rvx, RV rvy, RV rvu ); 197 //! Set nonlinear functions for mean values and covariance matrices. 198 void set_parameters ( diffbifn* pfxu, diffbifn* phxu, const chmat Q0, const chmat R0 ); 199 //! Here dt = [yt;ut] of appropriate dimensions 200 void bayes ( const vec &dt ); 201 }; 202 203 /*! 148 204 \brief Kalman Filter with conditional diagonal matrices R and Q. 149 205 */ … … 176 232 Kalman<sq_T>::Kalman ( const Kalman<sq_T> &K0 ) : BM ( K0.rv ),rvy ( K0.rvy ),rvu ( K0.rvu ), 177 233 dimx ( rv.count() ), dimy ( rvy.count() ),dimu ( rvu.count() ), 178 A ( dimx,dimx ), B ( dimx,dimu ), C ( dimy,dimx ), D ( dimy,dimu ),est ( rv ), fy ( rvy ) { 234 A ( dimx,dimx ), B ( dimx,dimu ), C ( dimy,dimx ), D ( dimy,dimu ), 235 Q(dimx), R(dimy), 236 est ( rv ), fy ( rvy ) { 179 237 180 238 this->set_parameters ( K0.A, K0.B, K0.C, K0.D, K0.R, K0.Q ); … … 188 246 fy._R ( _Ry,_iRy ); 189 247 190 // resetcopy values in pointers248 // copy values in pointers 191 249 *_mu = *K0._mu; 192 250 *_P = *K0._P; … … 272 330 273 331 template<class sq_T> 274 EKF<sq_T>::EKF ( RV rvx0, RV rvy0, RV rvu0 ) : Kalman< ldmat> ( rvx0,rvy0,rvu0 ) {}332 EKF<sq_T>::EKF ( RV rvx0, RV rvy0, RV rvu0 ) : Kalman<sq_T> ( rvx0,rvy0,rvu0 ) {} 275 333 276 334 template<class sq_T>