Changeset 583 for library/bdm/estim/kalman.cpp
- Timestamp:
- 08/27/09 15:39:31 (15 years ago)
- Files:
-
- 1 modified
Legend:
- Unmodified
- Added
- Removed
-
library/bdm/estim/kalman.cpp
r565 r583 6 6 using std::endl; 7 7 8 KalmanFull::KalmanFull ( mat A0, mat B0, mat C0, mat D0, mat Q0, mat R0, mat P0, vec mu0 ) { 9 dimx = A0.rows(); 10 dimu = B0.cols(); 11 dimy = C0.rows(); 12 13 bdm_assert_debug ( A0.cols() == dimx, "KalmanFull: A is not square" ); 14 bdm_assert_debug ( B0.rows() == dimx, "KalmanFull: B is not compatible" ); 15 bdm_assert_debug ( C0.cols() == dimx, "KalmanFull: C is not square" ); 16 bdm_assert_debug ( ( D0.rows() == dimy ) || ( D0.cols() == dimu ), "KalmanFull: D is not compatible" ); 17 bdm_assert_debug ( ( Q0.cols() == dimx ) || ( Q0.rows() == dimx ), "KalmanFull: Q is not compatible" ); 18 bdm_assert_debug ( ( R0.cols() == dimy ) || ( R0.rows() == dimy ), "KalmanFull: R is not compatible" ); 19 20 A = A0; 21 B = B0; 22 C = C0; 23 D = D0; 24 R = R0; 25 Q = Q0; 26 mu = mu0; 27 P = P0; 28 29 ll = 0.0; 30 evalll = true; 31 } 8 32 9 33 10 void KalmanFull::bayes ( const vec &dt ) { … … 36 13 vec u = dt.get ( dimy, dimy + dimu - 1 ); 37 14 vec y = dt.get ( 0, dimy - 1 ); 15 vec& mu = est->_mu(); 16 mat &P = est->_R(); 17 mat& _Ry = fy._R(); 38 18 //Time update 39 19 mu = A * mu + B * u; 40 P = A * P * A.transpose() + Q;20 P = A * P * A.transpose() + (mat)Q; 41 21 42 22 //Data update 43 _Ry = C * P * C.transpose() + R; 44 _iRy = inv ( _Ry ); 45 _K = P * C.transpose() * _iRy; 23 _Ry = C * P * C.transpose() + (mat)R; 24 _K = P * C.transpose() * inv ( _Ry ); 46 25 P -= _K * C * P; // P = P -KCP; 47 26 mu += _K * ( y - C * mu - D * u ); 48 27 49 28 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 ) ); 29 ll=est->evallog(y); 53 30 } 54 31 }; 55 32 56 std::ostream &operator<< ( std::ostream &os, const KalmanFull &kf ) {57 os << "mu:" << kf.mu << endl << "P:" << kf.P << endl;58 return os;59 }60 61 33 62 34 63 35 /////////////////////////////// EKFS 64 EKFfull::EKFfull ( ) : BM (), E() {};36 EKFfull::EKFfull ( ) : KalmanFull () {}; 65 37 66 38 void EKFfull::set_parameters ( const shared_ptr<diffbifn> &pfxu0, const shared_ptr<diffbifn> &phxu0, const mat Q0, const mat R0 ) { … … 71 43 dimy = phxu0->dimension(); 72 44 dimu = pfxu0->_dimu(); 73 E.epdf::set_parameters ( dimx);45 est->set_parameters( zeros(dimx), eye(dimx) ); 74 46 75 47 A.set_size ( dimx, dimx ); 76 48 C.set_size ( dimy, dimx ); 77 49 //initialize matrices A C, later, these will be only updated! 78 pfxu->dfdx_cond ( mu, zeros ( dimu ), A, true );50 pfxu->dfdx_cond ( est->_mu(), zeros ( dimu ), A, true ); 79 51 B.clear(); 80 phxu->dfdx_cond ( mu, zeros ( dimu ), C, true );52 phxu->dfdx_cond ( est->_mu(), zeros ( dimu ), C, true ); 81 53 D.clear(); 82 54 … … 90 62 vec u = dt.get ( dimy, dimy + dimu - 1 ); 91 63 vec y = dt.get ( 0, dimy - 1 ); 92 64 vec &mu = est->_mu(); 65 mat &P = est->_R(); 66 mat& _Ry = fy._R(); 67 93 68 pfxu->dfdx_cond ( mu, zeros ( dimu ), A, true ); 94 69 phxu->dfdx_cond ( mu, zeros ( dimu ), C, true ); … … 96 71 //Time update 97 72 mu = pfxu->eval ( mu, u );// A*mu + B*u; 98 P = A * P * A.transpose() + Q;73 P = A * P * A.transpose() + (mat)Q; 99 74 100 75 //Data update 101 _Ry = C * P * C.transpose() + R; 102 _iRy = inv ( _Ry ); 103 _K = P * C.transpose() * _iRy; 76 _Ry = C * P * C.transpose() + (mat)R; 77 _K = P * C.transpose() * inv ( _Ry ); 104 78 P -= _K * C * P; // P = P -KCP; 105 79 vec yp = phxu->eval ( mu, u ); 106 80 mu += _K * ( y - yp ); 107 81 108 E.set_mu ( mu );109 110 82 if ( BM::evalll ) { 111 //from enorm 112 vec x = y - yp; 113 BM::ll = -0.5 * ( R.cols() * 1.83787706640935 + log ( det ( _Ry ) ) + x * ( _iRy * x ) ); 83 ll=fy.evallog(y); 114 84 } 115 85 }; … … 119 89 void KalmanCh::set_parameters ( const mat &A0, const mat &B0, const mat &C0, const mat &D0, const chmat &Q0, const chmat &R0 ) { 120 90 121 ( ( Kalman<chmat>* ) this )->set_parameters ( A0, B0, C0, D0, Q0, R0 ); 91 ( ( StateSpace<chmat>* ) this )->set_parameters ( A0, B0, C0, D0, Q0, R0 ); 92 93 _K=zeros(dimx,dimy); 122 94 // Cholesky special! 95 initialize(); 96 } 97 98 void KalmanCh::initialize(){ 123 99 preA = zeros ( dimy + dimx + dimx, dimy + dimx ); 124 100 // preA.clear(); … … 127 103 } 128 104 129 130 105 void KalmanCh::bayes ( const vec &dt ) { 131 106 … … 134 109 vec pom ( dimy ); 135 110 111 chmat &_P=est->_R(); 112 vec &_mu = est->_mu(); 113 mat _K(dimx,dimy); 114 chmat &_Ry=fy._R(); 115 vec &_yp = fy._mu(); 136 116 //TODO get rid of Q in qr()! 137 117 // mat Q; … … 174 154 dimy = phxu0->dimension(); 175 155 dimu = pfxu0->_dimu(); 156 157 vec &_mu = est->_mu(); 176 158 // if mu is not set, set it to zeros, just for constant terms of A and C 177 if ( _mu.length() != dimx ) _mu = zeros ( dimx ); 159 if ( _mu.length() != dimx ) _mu = zeros ( dimx ); 178 160 A = zeros ( dimx, dimx ); 179 161 C = zeros ( dimy, dimx ); … … 203 185 vec u = dt.get ( dimy, dimy + dimu - 1 ); 204 186 vec y = dt.get ( 0, dimy - 1 ); 205 187 vec &_mu = est->_mu(); 188 chmat &_P = est->_R(); 189 chmat &_Ry = fy._R(); 190 vec &_yp = fy._mu(); 191 206 192 pfxu->dfdx_cond ( _mu, u, A, false ); //update A by a derivative of fx 207 193 phxu->dfdx_cond ( _mu, u, C, false ); //update A by a derivative of fx