Changeset 37 for bdm/estim

Show
Ignore:
Timestamp:
03/14/08 18:11:21 (16 years ago)
Author:
smidl
Message:

Matrix in Cholesky decomposition, Square-root Kalman and many bug fixes

Location:
bdm/estim
Files:
2 modified

Legend:

Unmodified
Added
Removed
  • bdm/estim/libKF.cpp

    r32 r37  
    2626        mu = mu0; 
    2727        P = P0; 
     28         
     29        ll = 0.0; 
     30        evalll=true; 
    2831} 
    2932 
     
    4346        P -= _K*C*P; // P = P -KCP; 
    4447        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        } 
    4554}; 
    4655 
     
    5059} 
    5160 
     61void 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 
     71void 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 
     103EKFCh::EKFCh ( RV rvx0, RV rvy0, RV rvu0 ) : KalmanCh ( rvx0,rvy0,rvu0 ) {} 
     104 
     105void 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 
     127void 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 
    52160void KFcondQR::condition ( const vec &QR ) { 
    53161        it_assert_debug ( QR.length() == ( rvc.count() ),"KFcondRQ: conditioning by incompatible vector" ); 
    54162 
    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 ) ); 
    57165}; 
    58166 
  • bdm/estim/libKF.h

    r33 r37  
    1717#include "../stat/libFN.h" 
    1818#include "../stat/libEF.h" 
    19  
     19#include "../math/chmat.h" 
    2020 
    2121using namespace itpp; 
     
    3838        mat P; 
    3939 
     40        bool evalll; 
     41        double ll; 
    4042public: 
    4143        //! Full constructor 
     
    124126}; 
    125127 
     128/*! \brief Kalman filter in square root form 
     129*/ 
     130class KalmanCh : public Kalman<chmat>{ 
     131protected: 
     132//! pre array (triangular matrix) 
     133mat preA; 
     134//! post array (triangular matrix) 
     135mat postA; 
     136 
     137public: 
     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} 
     151R^{0.5}\\ 
     152P_{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} 
     154R_{y}^{0.5} & KA'\\ 
     155 & P_{t+1|t}^{0.5}\\ 
     156\\\end{array}\right]\f] 
     157 
     158Thus this objevt evaluates only predictors! Not filtering densities. 
     159        */ 
     160        void bayes ( const vec &dt ); 
     161}; 
     162 
    126163/*! 
    127164\brief Extended Kalman Filter 
     
    130167*/ 
    131168template<class sq_T> 
    132  
    133169class EKF : public Kalman<ldmat> { 
    134170        //! Internal Model f(x,u) 
     
    146182 
    147183/*! 
     184\brief Extended Kalman Filter in Square roor 
     185 
     186An approximation of the exact Bayesian filter with Gaussian noices and non-linear evolutions of their mean. 
     187*/ 
     188 
     189class EKFCh : public KalmanCh { 
     190        //! Internal Model f(x,u) 
     191        diffbifn* pfxu; 
     192        //! Observation Model h(x,u) 
     193        diffbifn* phxu; 
     194public: 
     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/*! 
    148204\brief Kalman Filter with conditional diagonal matrices R and Q. 
    149205*/ 
     
    176232Kalman<sq_T>::Kalman ( const Kalman<sq_T> &K0 ) : BM ( K0.rv ),rvy ( K0.rvy ),rvu ( K0.rvu ), 
    177233                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 ) { 
    179237 
    180238        this->set_parameters ( K0.A, K0.B, K0.C, K0.D, K0.R, K0.Q ); 
     
    188246        fy._R ( _Ry,_iRy ); 
    189247 
    190 //reset copy values in pointers 
     248// copy values in pointers 
    191249        *_mu = *K0._mu; 
    192250        *_P = *K0._P; 
     
    272330 
    273331template<class sq_T> 
    274 EKF<sq_T>::EKF ( RV rvx0, RV rvy0, RV rvu0 ) : Kalman<ldmat> ( rvx0,rvy0,rvu0 ) {} 
     332EKF<sq_T>::EKF ( RV rvx0, RV rvy0, RV rvu0 ) : Kalman<sq_T> ( rvx0,rvy0,rvu0 ) {} 
    275333 
    276334template<class sq_T>