Changeset 32 for bdm/estim

Show
Ignore:
Timestamp:
03/03/08 13:00:32 (17 years ago)
Author:
smidl
Message:

test KF : estimation of R in KF is not possible! Likelihood of y_t is growing when R -> 0

Location:
bdm/estim
Files:
4 modified

Legend:

Unmodified
Added
Removed
  • bdm/estim/libKF.cpp

    r28 r32  
    66using std::endl; 
    77 
    8 KalmanFull::KalmanFull( mat A0, mat B0, mat C0, mat D0, mat R0, mat Q0, mat P0, vec mu0 ) { 
     8KalmanFull::KalmanFull ( mat A0, mat B0, mat C0, mat D0, mat R0, mat Q0, mat P0, vec mu0 ) { 
    99        dimx = A0.rows(); 
    1010        dimu = B0.cols(); 
    1111        dimy = C0.rows(); 
    1212 
    13         it_assert_debug( A0.cols()==dimx, "KalmanFull: A is not square" ); 
    14         it_assert_debug( B0.rows()==dimx, "KalmanFull: B is not compatible" ); 
    15         it_assert_debug( C0.cols()==dimx, "KalmanFull: C is not square" ); 
    16         it_assert_debug(( D0.rows()==dimy ) || ( D0.cols()==dimu ),     "KalmanFull: D is not compatible" ); 
    17         it_assert_debug(( R0.cols()==dimy ) || ( R0.rows()==dimy ), "KalmanFull: R is not compatible" ); 
    18         it_assert_debug(( Q0.cols()==dimx ) || ( Q0.rows()==dimx ), "KalmanFull: Q is not compatible" ); 
     13        it_assert_debug ( A0.cols() ==dimx, "KalmanFull: A is not square" ); 
     14        it_assert_debug ( B0.rows() ==dimx, "KalmanFull: B is not compatible" ); 
     15        it_assert_debug ( C0.cols() ==dimx, "KalmanFull: C is not square" ); 
     16        it_assert_debug ( ( D0.rows() ==dimy ) || ( D0.cols() ==dimu ), "KalmanFull: D is not compatible" ); 
     17        it_assert_debug ( ( R0.cols() ==dimy ) || ( R0.rows() ==dimy ), "KalmanFull: R is not compatible" ); 
     18        it_assert_debug ( ( Q0.cols() ==dimx ) || ( Q0.rows() ==dimx ), "KalmanFull: Q is not compatible" ); 
    1919 
    2020        A = A0; 
     
    2828} 
    2929 
    30 void KalmanFull::bayes( const vec &dt) { 
    31         it_assert_debug( dt.length()==( dimy+dimu ),"KalmanFull::bayes wrong size of dt" ); 
     30void KalmanFull::bayes ( const vec &dt ) { 
     31        it_assert_debug ( dt.length() == ( dimy+dimu ),"KalmanFull::bayes wrong size of dt" ); 
    3232 
    33         vec u = dt.get( dimy,dimy+dimu-1 ); 
    34         vec y = dt.get( 0,dimy-1 ); 
     33        vec u = dt.get ( dimy,dimy+dimu-1 ); 
     34        vec y = dt.get ( 0,dimy-1 ); 
    3535        //Time update 
    3636        mu = A*mu + B*u; 
     
    3939        //Data update 
    4040        _Ry = C*P*C.transpose() + R; 
    41         _iRy = inv( _Ry ); 
    42         _K = P*C.transpose()*_iRy; 
     41        _iRy = inv ( _Ry ); 
     42        _K = P*C.transpose() *_iRy; 
    4343        P -= _K*C*P; // P = P -KCP; 
    44         mu += _K*( y-C*mu-D*u ); 
     44        mu += _K* ( y-C*mu-D*u ); 
    4545}; 
    4646 
     
    5050} 
    5151 
     52void KFcondQR::condition ( const vec &QR ) { 
     53        it_assert_debug ( QR.length() == ( rvc.count() ),"KFcondRQ: conditioning by incompatible vector" ); 
     54 
     55        Q.setD ( QR ( 0, dimx-1 )); 
     56        R.setD ( QR ( dimx, -1 )); 
     57}; 
     58 
     59void KFcondR::condition ( const vec &R0 ) { 
     60        it_assert_debug ( R0.length() == ( rvc.count() ),"KFcondR: conditioning by incompatible vector" ); 
     61 
     62        R.setD ( R0 ); 
     63}; 
  • bdm/estim/libKF.h

    r28 r32  
    2424* \brief Basic Kalman filter with full matrices (education purpose only)! Will be deleted soon! 
    2525*/ 
    26 class KalmanFull : public BM {  
     26 
     27class KalmanFull { 
    2728        int dimx, dimy, dimu; 
    2829        mat A, B, C, D, R, Q; 
    29          
    30         //cache  
     30 
     31        //cache 
    3132        mat _Pp, _Ry, _iRy, _K; 
    3233public: 
    33         //posterior  
     34        //posterior 
    3435        //! Mean value of the posterior density 
    3536        vec mu; 
     
    3839 
    3940public: 
    40         //! Full constructor  
    41         KalmanFull ( mat A, mat B, mat C, mat D, mat R, mat Q, mat P0, vec mu0); 
     41        //! Full constructor 
     42        KalmanFull ( mat A, mat B, mat C, mat D, mat R, mat Q, mat P0, vec mu0 ); 
    4243        //! Here dt = [yt;ut] of appropriate dimensions 
    43         void bayes(const vec &dt);  
    44         epdf* _epdf(){return NULL;};  
     44        void bayes ( const vec &dt ); 
    4545 
    4646        friend std::ostream &operator<< ( std::ostream &os, const KalmanFull &kf ); 
     
    5353*/ 
    5454template<class sq_T> 
    55 class Kalman : public BM {  
     55 
     56class Kalman : public BM { 
    5657protected: 
     58        RV rvy; 
     59        RV rvu; 
    5760        int dimx, dimy, dimu; 
    5861        mat A, B, C, D; 
    59         sq_T R, Q; 
    60          
    61         //!posterior on $x_t$ 
     62        sq_T Q,R; 
     63 
     64        //!posterior density on $x_t$ 
    6265        enorm<sq_T> est; 
    6366        //!preditive density on $y_t$ 
    6467        enorm<sq_T> fy; 
    65          
     68 
    6669        mat _K; 
    6770        //cache of fy 
    68         vec* _yp;  
     71        vec* _yp; 
    6972        sq_T* _Ry,*_iRy; 
    7073        //cache of est 
    7174        vec* _mu; 
    7275        sq_T* _P, *_iP; 
    73          
     76 
    7477public: 
    7578        //! Default constructor 
    76         Kalman (RV rvx0, RV rvy0, RV rvu0); 
    77         //! Set parameters with check of relevance  
    78         void set_parameters (const mat &A0,const mat &B0,const mat &C0,const mat &D0,const sq_T &R0,const sq_T &Q0); 
     79        Kalman ( RV rvx0, RV rvy0, RV rvu0 ); 
     80        //! Copy constructor 
     81        Kalman ( const Kalman<sq_T> &K0 ); 
     82        //! Set parameters with check of relevance 
     83        void set_parameters ( const mat &A0,const mat &B0,const mat &C0,const mat &D0,const sq_T &R0,const sq_T &Q0 ); 
    7984        //! Set estimate values, used e.g. in initialization. 
    80         void set_est(const vec &mu0, const sq_T &P0 ){est.set_parameters(mu0,P0);}; 
     85 
     86        void set_est ( const vec &mu0, const sq_T &P0 ) { 
     87                sq_T pom(dimy); 
     88                est.set_parameters ( mu0,P0 ); 
     89                P0.mult_sym(C,pom); 
     90                fy.set_parameters ( C*mu0, pom ); 
     91        }; 
     92 
    8193        //! Here dt = [yt;ut] of appropriate dimensions 
    82         void bayes(const vec &dt);  
     94        void bayes ( const vec &dt ); 
     95        epdf& _epdf() {return est;} 
    8396 
    8497//      friend std::ostream &operator<< ( std::ostream &os, const Kalman<sq_T> &kf ); 
    8598 
    8699        //!access functions 
    87         enorm<sq_T>* _epdf(){return &est;}  
    88 }; 
    89  
    90 /*! 
    91 \brief Extended Kalman Filter  
     100}; 
     101 
     102/*! 
     103\brief Extended Kalman Filter 
    92104 
    93105An approximation of the exact Bayesian filter with Gaussian noices and non-linear evolutions of their mean. 
    94106*/ 
    95107template<class sq_T> 
     108 
    96109class EKF : public Kalman<ldmat> { 
    97110        //! Internal Model f(x,u) 
     
    99112        //! Observation Model h(x,u) 
    100113        diffbifn* phxu; 
    101 public:  
     114public: 
    102115        //! Default constructor 
    103         EKF (RV rvx, RV rvy, RV rvu); 
    104         void set_parameters(diffbifn* pfxu, diffbifn* phxu, const sq_T Q0, const sq_T R0); 
     116        EKF ( RV rvx, RV rvy, RV rvu ); 
     117        void set_parameters ( diffbifn* pfxu, diffbifn* phxu, const sq_T Q0, const sq_T R0 ); 
    105118        //! Here dt = [yt;ut] of appropriate dimensions 
    106         void bayes(const vec &dt);       
     119        void bayes ( const vec &dt ); 
     120}; 
     121 
     122/*! 
     123\brief Kalman Filter with conditional diagonal matrices R and Q. 
     124*/ 
     125 
     126class KFcondQR : public Kalman<ldmat>, public BMcond { 
     127//protected: 
     128public: 
     129        KFcondQR ( RV rvx, RV rvy, RV rvu, RV rvRQ ) : Kalman<ldmat> ( rvx, rvy,rvu ),BMcond ( rvRQ ) {}; 
     130 
     131        void condition ( const vec &RQ ); 
     132}; 
     133 
     134/*! 
     135\brief Kalman Filter with conditional diagonal matrices R and Q. 
     136*/ 
     137 
     138class KFcondR : public Kalman<ldmat>, public BMcond { 
     139//protected: 
     140public: 
     141        KFcondR ( RV rvx, RV rvy, RV rvu, RV rvR ) : Kalman<ldmat> ( rvx, rvy,rvu ),BMcond ( rvR ) {}; 
     142 
     143        void condition ( const vec &R ); 
    107144}; 
    108145 
     
    110147 
    111148template<class sq_T> 
    112 Kalman<sq_T>::Kalman(RV rvx, RV rvy, RV rvu): BM(), 
    113 dimx(rvx.count()), dimy(rvy.count()),dimu(rvu.count()),  
    114  A(dimx,dimx), B(dimx,dimu), C(dimy,dimx), D(dimy,dimu), est(rvx), fy(rvy){ 
     149Kalman<sq_T>::Kalman ( const Kalman<sq_T> &K0 ) : BM ( K0.rv ),rvy ( K0.rvy ),rvu ( K0.rvu ), 
     150                dimx ( rv.count() ), dimy ( rvy.count() ),dimu ( rvu.count() ), 
     151                A ( dimx,dimx ), B ( dimx,dimu ), C ( dimy,dimx ), D ( dimy,dimu ),est ( rv ), fy ( rvy ) { 
     152 
     153        this->set_parameters ( K0.A, K0.B, K0.C, K0.D, K0.R, K0.Q ); 
     154 
     155//establish pointers 
     156        _mu = est._mu(); 
     157        est._R ( _P,_iP ); 
     158 
     159//fy 
     160        _yp = fy._mu(); 
     161        fy._R ( _Ry,_iRy ); 
     162 
     163//reset copy values in pointers 
     164        *_mu = *K0._mu; 
     165        *_P = *K0._P; 
     166        *_iP = *K0._iP; 
     167        *_yp = *K0._yp; 
     168        *_iRy = *K0._iRy; 
     169        *_Ry = *K0._Ry; 
     170 
     171} 
     172 
     173template<class sq_T> 
     174Kalman<sq_T>::Kalman ( RV rvx, RV rvy0, RV rvu0 ) : BM ( rvx ),rvy ( rvy0 ),rvu ( rvu0 ), 
     175                dimx ( rvx.count() ), dimy ( rvy.count() ),dimu ( rvu.count() ), 
     176                A ( dimx,dimx ), B ( dimx,dimu ), C ( dimy,dimx ), D ( dimy,dimu ), 
     177                Q(dimx), R (dimy), 
     178                est ( rvx ), fy ( rvy ) { 
    115179//assign cache 
    116180//est 
    117 _mu = est._mu(); 
    118 est._R(_P,_iP); 
     181        _mu = est._mu(); 
     182        est._R ( _P,_iP ); 
    119183 
    120184//fy 
    121 _yp = fy._mu(); 
    122 fy._R(_Ry,_iRy); 
    123 }; 
    124  
    125 template<class sq_T> 
    126 void Kalman<sq_T>::set_parameters(const mat &A0,const  mat &B0, const mat &C0, const mat &D0, const sq_T &R0, const sq_T &Q0) { 
    127         it_assert_debug( A0.cols()==dimx, "Kalman: A is not square" ); 
    128         it_assert_debug( B0.rows()==dimx, "Kalman: B is not compatible" ); 
    129         it_assert_debug( C0.cols()==dimx, "Kalman: C is not square" ); 
    130         it_assert_debug(( D0.rows()==dimy ) || ( D0.cols()==dimu ),     "Kalman: D is not compatible" ); 
    131         it_assert_debug(( R0.cols()==dimy ) || ( R0.rows()==dimy ), "Kalman: R is not compatible" ); 
    132         it_assert_debug(( Q0.cols()==dimx ) || ( Q0.rows()==dimx ), "Kalman: Q is not compatible" ); 
     185        _yp = fy._mu(); 
     186        fy._R ( _Ry,_iRy ); 
     187}; 
     188 
     189template<class sq_T> 
     190void Kalman<sq_T>::set_parameters ( const mat &A0,const  mat &B0, const mat &C0, const mat &D0, const sq_T &R0, const sq_T &Q0 ) { 
     191        it_assert_debug ( A0.cols() ==dimx, "Kalman: A is not square" ); 
     192        it_assert_debug ( B0.rows() ==dimx, "Kalman: B is not compatible" ); 
     193        it_assert_debug ( C0.cols() ==dimx, "Kalman: C is not square" ); 
     194        it_assert_debug ( ( D0.rows() ==dimy ) || ( D0.cols() ==dimu ), "Kalman: D is not compatible" ); 
     195        it_assert_debug ( ( R0.cols() ==dimy ) || ( R0.rows() ==dimy ), "Kalman: R is not compatible" ); 
     196        it_assert_debug ( ( Q0.cols() ==dimx ) || ( Q0.rows() ==dimx ), "Kalman: Q is not compatible" ); 
    133197 
    134198        A = A0; 
     
    137201        D = D0; 
    138202        R = R0; 
    139         Q = Q0;  
     203        Q = Q0; 
    140204} 
    141205 
    142206template<class sq_T> 
    143 void Kalman<sq_T>::bayes( const vec &dt) { 
    144         it_assert_debug( dt.length()==( dimy+dimu ),"KalmanFull::bayes wrong size of dt" ); 
    145  
    146         vec u = dt.get( dimy,dimy+dimu-1 ); 
    147         vec y = dt.get( 0,dimy-1 ); 
     207void Kalman<sq_T>::bayes ( const vec &dt ) { 
     208        it_assert_debug ( dt.length() == ( dimy+dimu ),"KalmanFull::bayes wrong size of dt" ); 
     209 
     210        vec u = dt.get ( dimy,dimy+dimu-1 ); 
     211        vec y = dt.get ( 0,dimy-1 ); 
    148212        //Time update 
    149         *_mu = A*(*_mu) + B*u; 
     213        *_mu = A* ( *_mu ) + B*u; 
    150214        //P  = A*P*A.transpose() + Q; in sq_T 
    151         _P->mult_sym( A ); 
    152         (*_P)+=Q; 
     215        _P->mult_sym ( A ); 
     216        ( *_P ) +=Q; 
    153217 
    154218        //Data update 
    155219        //_Ry = C*P*C.transpose() + R; in sq_T 
    156         _P->mult_sym( C, *_Ry); 
    157         (*_Ry)+=R; 
     220        _P->mult_sym ( C, *_Ry ); 
     221        ( *_Ry ) +=R; 
    158222 
    159223        mat Pfull = _P->to_mat(); 
    160          
    161         _Ry->inv( *_iRy ); // result is in _iRy; 
    162         _K = Pfull*C.transpose()*(_iRy->to_mat()); 
    163          
    164         sq_T pom((int)Pfull.rows()); 
    165         _iRy->mult_sym_t(C*Pfull,pom); 
    166         (*_P) -= pom; // P = P -PC'iRy*CP; 
    167         (*_yp) = C*(*_mu)+D*u; //y prediction 
    168         (*_mu) += _K*( y-(*_yp) ); 
    169          
    170         if (evalll==true) { 
    171                 ll+=fy.evalpdflog(*_yp); 
     224 
     225        _Ry->inv ( *_iRy ); // result is in _iRy; 
     226        fy._cached ( true ); 
     227        _K = Pfull*C.transpose() * ( _iRy->to_mat() ); 
     228 
     229        sq_T pom ( ( int ) Pfull.rows() ); 
     230        _iRy->mult_sym_t ( C*Pfull,pom ); 
     231        ( *_P ) -= pom; // P = P -PC'iRy*CP; 
     232        ( *_yp ) = C* ( *_mu ) +D*u; //y prediction 
     233        ( *_mu ) += _K* ( y- ( *_yp ) ); 
     234 
     235 
     236        if ( evalll==true ) { //likelihood of observation y 
     237                ll=fy.evalpdflog ( y ); 
    172238        } 
     239 
     240//cout << "y: " << y-(*_yp) <<" R: " << _Ry->to_mat() << " iR: " << _iRy->to_mat() << " ll: " << ll <<endl; 
     241 
    173242}; 
    174243 
     
    176245 
    177246template<class sq_T> 
    178 EKF<sq_T>::EKF(RV rvx0, RV rvy0, RV rvu0): Kalman<ldmat>(rvx0,rvy0,rvu0){} 
    179  
    180 template<class sq_T> 
    181 void EKF<sq_T>::set_parameters(diffbifn* pfxu0,  diffbifn* phxu0,const sq_T Q0,const sq_T R0) { 
    182                 pfxu = pfxu0; 
    183                 phxu = phxu0; 
    184                  
    185                 //initialize matrices A C, later, these will be only updated! 
    186                 pfxu->dfdx_cond(*_mu,zeros(dimu),A,true); 
    187                 pfxu->dfdu_cond(*_mu,zeros(dimu),B,true); 
    188                 phxu->dfdx_cond(*_mu,zeros(dimu),C,true); 
    189                 phxu->dfdu_cond(*_mu,zeros(dimu),D,true); 
    190  
    191                 R = R0; 
    192                 Q = Q0; 
     247EKF<sq_T>::EKF ( RV rvx0, RV rvy0, RV rvu0 ) : Kalman<ldmat> ( rvx0,rvy0,rvu0 ) {} 
     248 
     249template<class sq_T> 
     250void EKF<sq_T>::set_parameters ( diffbifn* pfxu0,  diffbifn* phxu0,const sq_T Q0,const sq_T R0 ) { 
     251        pfxu = pfxu0; 
     252        phxu = phxu0; 
     253 
     254        //initialize matrices A C, later, these will be only updated! 
     255        pfxu->dfdx_cond ( *_mu,zeros ( dimu ),A,true ); 
     256        pfxu->dfdu_cond ( *_mu,zeros ( dimu ),B,true ); 
     257        phxu->dfdx_cond ( *_mu,zeros ( dimu ),C,true ); 
     258        phxu->dfdu_cond ( *_mu,zeros ( dimu ),D,true ); 
     259 
     260        R = R0; 
     261        Q = Q0; 
    193262 
    194263        using std::cout; 
     
    201270 
    202271template<class sq_T> 
    203 void EKF<sq_T>::bayes( const vec &dt) { 
    204         it_assert_debug( dt.length()==( dimy+dimu ),"KalmanFull::bayes wrong size of dt" ); 
    205  
    206         vec u = dt.get( dimy,dimy+dimu-1 ); 
    207         vec y = dt.get( 0,dimy-1 ); 
     272void EKF<sq_T>::bayes ( const vec &dt ) { 
     273        it_assert_debug ( dt.length() == ( dimy+dimu ),"KalmanFull::bayes wrong size of dt" ); 
     274 
     275        vec u = dt.get ( dimy,dimy+dimu-1 ); 
     276        vec y = dt.get ( 0,dimy-1 ); 
    208277        //Time update 
    209         *_mu = pfxu->eval(*_mu, u); 
    210         pfxu->dfdx_cond(*_mu,u,A,false); //update A by a derivative of fx 
    211          
     278        *_mu = pfxu->eval ( *_mu, u ); 
     279        pfxu->dfdx_cond ( *_mu,u,A,false ); //update A by a derivative of fx 
     280 
    212281        //P  = A*P*A.transpose() + Q; in sq_T 
    213         _P->mult_sym( A ); 
    214         (*_P)+=Q; 
     282        _P->mult_sym ( A ); 
     283        ( *_P ) +=Q; 
    215284 
    216285        //Data update 
    217         phxu->dfdx_cond(*_mu,u,C,false); //update C by a derivative hx 
     286        phxu->dfdx_cond ( *_mu,u,C,false ); //update C by a derivative hx 
    218287        //_Ry = C*P*C.transpose() + R; in sq_T 
    219         _P->mult_sym( C, *_Ry); 
    220         (*_Ry)+=R; 
     288        _P->mult_sym ( C, *_Ry ); 
     289        ( *_Ry ) +=R; 
    221290 
    222291        mat Pfull = _P->to_mat(); 
    223          
    224         _Ry->inv( *_iRy ); // result is in _iRy; 
    225         _K = Pfull*C.transpose()*(_iRy->to_mat()); 
    226         (*_P) -= _K*C*Pfull; // P = P -KCP; 
    227         *_yp = phxu->eval(*_mu,u); //y prediction 
    228         (*_mu) += _K*( y-*_yp ); 
    229          
    230         if (evalll==true) {ll+=est.evalpdflog(y);} 
     292 
     293        _Ry->inv ( *_iRy ); // result is in _iRy; 
     294        _K = Pfull*C.transpose() * ( _iRy->to_mat() ); 
     295 
     296        sq_T pom ( ( int ) Pfull.rows() ); 
     297        _iRy->mult_sym_t ( C*Pfull,pom ); 
     298        ( *_P ) -= pom; // P = P -PC'iRy*CP; 
     299        *_yp = phxu->eval ( *_mu,u ); //y prediction 
     300        ( *_mu ) += _K* ( y-*_yp ); 
     301 
     302        if ( evalll==true ) {ll+=fy.evalpdflog ( y );} 
    231303}; 
    232304 
  • bdm/estim/libPF.cpp

    r28 r32  
    55using std::endl; 
    66 
    7 PF::PF(vec w0){w=w0/sum(w0); n=w.length();} 
    87 
    9 ivec PF::resample( RESAMPLING_METHOD method ) { 
    10         ivec ind=zeros_i( n ); 
    11         ivec N_babies = zeros_i( n ); 
    12         vec cumDist = cumsum( w ); 
    13         vec u( n ); 
    14         int i,j,parent; 
    15         double u0; 
     8void PF::bayes ( const vec &dt ) { 
     9        int i; 
     10        vec lls ( n ); 
     11        ivec ind; 
     12        double mlls=-std::numeric_limits<double>::infinity(), sum=0.0; 
    1613 
    17         switch ( method ) { 
    18         case MULTINOMIAL: 
    19                 u( n - 1 ) = pow( URNG.sample(), 1.0 / n ); 
    20                 for ( i = n - 2;i >= 0;i-- ) { 
    21                         u( i ) = u( i + 1 ) * pow( URNG.sample(), 1.0 / ( i + 1 ) ); 
    22                 } 
    23                 break; 
    24         case STRATIFIED: 
    25                 for ( i = 0;i < n;i++ ) { 
    26                         u( i ) = ( i + URNG.sample() ) / n; 
    27                 } 
    28                 break; 
    29         case SYSTEMATIC: 
    30                 u0 = URNG.sample(); 
    31                 for ( i = 0;i < n;i++ ) { 
    32                         u( i ) = ( i + u0 ) / n; 
    33                 } 
    34                 break; 
    35         default: 
    36                 it_error( "PF::resample(): Unknown resampling method" ); 
    37         } 
    38          
    39 //      // <<<<<<<<<<< 
    40 //      using std::cout; 
    41 //      cout << "resampling:" << endl; 
    42 //      cout << w <<endl; 
    43 //      cout << cumDist <<endl; 
    44 //      cout << u <<endl; 
     14        for ( i=0;i<n;i++ ) { 
     15                //generate new samples from paramater evolution model; 
     16                _samples ( i ) = par.samplecond ( _samples ( i ), lls ( i ) ); 
     17                lls ( i ) *= obs.evalcond ( dt,_samples ( i ) ); 
    4518 
    46         // U is now full 
    47         j = 0; 
    48         for ( i = 0;i < n;i++ ) { 
    49                 while ( u( i ) > cumDist( j ) ) j++; 
    50                 N_babies( j )++; 
     19                if ( lls ( i ) >mlls ) mlls=lls ( i ); //find maximum 
    5120        } 
    5221 
    53 //      // <<<<<<<<<<< 
    54 //      cout << N_babies <<endl; 
     22        // compute weights 
     23        for ( i=0;i<n;i++ ) { 
     24                _w ( i ) *= exp ( lls ( i ) - mlls ); // multiply w by likelihood 
     25        } 
    5526 
    56         // We have assigned new babies for each Particle 
    57         // Now, we fill the resulting index such that: 
    58         // * particles with at least one baby should not move * 
    59         // This assures that reassignment can be done inplace; 
     27        //renormalize 
     28        for ( i=0;i<n;i++ ) {sum+=_w ( i );}; 
    6029 
    61         // find the first parent; 
    62         parent=0; while(N_babies(parent)==0) parent++; 
    63         // Build index 
    64         for ( i = 0;i < n;i++ ) { 
    65                 if ( N_babies( i ) > 0 ){ 
    66                         ind( i ) = i; 
    67                         N_babies( i ) --; //this index was now replicated; 
    68                         } 
    69                 else { 
    70                         // test if the parent has been fully replicated  
    71                         // if yes, find the next one 
    72                         while((N_babies(parent)==0) || (N_babies(parent)==1 && parent>i) ) parent++; 
    73                         // Replicate parent 
    74                         ind (i) = parent; 
    75                         N_babies( parent ) --; //this index was now replicated; 
    76                 } 
    77 /*                      // <<<<<<<<<<< 
    78                         cout <<ind << endl;*/ 
    79         } 
    80         return ind; 
     30        _w ( i ) /=sum; //? 
     31 
     32        ind = est.resample(); 
     33 
    8134} 
    8235 
    83 TrivialPF::TrivialPF( mpdf &par0, mpdf &obs0, BM &prop0, int n0 ) : PF(1/n*ones(n)) { 
    84         is_proposal = true; 
    85         prop = &prop0; 
    86         par = &par0; 
    87         obs = &obs0; 
    88 } 
    89 TrivialPF::TrivialPF( mpdf &par0, mpdf &obs0,  int n0 ) : PF(1/n*ones(n)) { 
    90         is_proposal = false; 
    91         par = &par0; 
    92         obs = &obs0; 
     36void PF::set_est ( const epdf &epdf0 ) { 
     37        int i; 
     38 
     39        for ( i=0;i<n;i++ ) { 
     40                _samples ( i ) = epdf0.sample(); 
     41        } 
    9342} 
    9443 
    95 void TrivialPF::bayes( const vec &dt , bool evalll ) { 
    96         int i; 
    97         vec oldp; 
    98         double ll, gl, sum = 0.0; 
    99         Sort<double> S; 
    100         ivec ind, iw; 
    101          
    102         //generate new samples 
    103         for ( i=0;i<n;i++ ) { 
    104                 if(is_proposal) { 
    105                         epdf* prop_epdf; 
    106         //              prop_epdf = prop._epdf(); 
    107                         prop->bayes(dt); 
    108                         ptcls( i ) = prop_epdf->sample(); 
    109                         } 
    110 //              gl = prop_cond.eval( ptcls( i ) ); 
    111  
    112 //              obs.evalcond( ptcls( i ), &obs_cond ); 
    113 //              ll = obs_cond.eval( dt ); 
    114                 w( i ) *= ll/gl; 
    115         } 
    116         //renormalize 
    117         for ( i=0;i<n;i++ ){sum+=w( i );}; 
    118         w( i ) /=sum; //? 
    119          
    120         ind = resample(); 
    121         iw = S.sort_index( 0,n-1,w ); // the first one in iw is the strongest 
    122  
    123         for ( i=0;i<n;i++ ) { 
    124                 ptcls( i ) = ptcls( i ); //potentionally dangerous! 
    125         } 
    126          
    127 } 
     44//MPF::MPF:{} 
  • bdm/estim/libPF.h

    r28 r32  
    1515 
    1616#include <itpp/itbase.h> 
    17 #include "../stat/libBM.h" 
     17#include "../stat/libEF.h" 
    1818#include "../math/libDC.h" 
    1919 
    2020using namespace itpp; 
    2121 
    22 enum RESAMPLING_METHOD { MULTINOMIAL = 0, STRATIFIED = 1, SYSTEMATIC = 3 }; 
     22/*! 
     23* \brief Trivial particle filter with proposal density equal to parameter evolution model. 
    2324 
    24 /*! 
    25 * \brief A Particle Filter prototype 
     25Posterior density is represented by a weighted empirical density (\c eEmp ). 
     26*/ 
    2627 
    27 Bayesian Filtering equations hold. 
    28 */ 
    29 class PF : public BM {  
     28class PF : public BM { 
    3029protected: 
    31         int n; //number of particles 
    32         vec w; //particle weights 
    33         Uniform_RNG URNG; //used for resampling 
    34          
     30        //!number of particles; 
     31        int n; 
     32        //!posterior density 
     33        eEmp est; 
     34        //! pointer into \c eEmp 
     35        vec &_w; 
     36        //! pointer into \c eEmp 
     37        Array<vec> &_samples; 
     38        //! Parameter evolution model 
     39        mpdf &par; 
     40        //! Observation model 
     41        mpdf &obs; 
    3542public: 
    36         //! Returns indexes of particles that should be resampled. The ordering MUST guarantee inplace replacement. (Important for MPF.) 
    37         ivec resample(RESAMPLING_METHOD method = SYSTEMATIC); 
    38         PF (vec w); 
     43        PF ( const RV &rv0, mpdf &par0,  mpdf &obs0, int n0 ) :BM ( rv0 ), 
     44                        n ( n0 ),est ( rv0,n ),_w ( est._w() ),_samples ( est._samples() ), 
     45                        par ( par0 ), obs ( obs0 ) {}; 
     46 
     47//      void set_parametres(mpdf &par0, mpdf &obs0) {par=&par0;obs=&obs0;}; 
     48        void set_est ( const epdf &epdf0 ); 
    3949        //TODO remove or implement bayes()! 
    40         void bayes(const vec &dt){}; 
    41         epdf* _epdf(){return NULL;} 
     50        void bayes ( const vec &dt ); 
    4251}; 
    4352 
    4453/*! 
    45 * \brief Trivial particle filter with proposal density that is not conditioned on the data. 
     54\brief Marginalized Particle filter 
    4655 
    47  
     56Trivial version: proposal $=$ parameter evolution, observation model is not used. (it is assumed to be part of BM). 
    4857*/ 
    4958 
    50 class TrivialPF : public PF { 
    51         Array<vec> ptcls; 
    52          
    53         bool is_proposal; 
    54         BM *prop; 
    55         mpdf *par; 
    56         mpdf *obs; 
    57          
     59template<class BM_T> 
     60 
     61class MPF : public PF { 
     62        BM_T* Bms[1000]; 
     63 
     64        //! internal class for MPDF providing composition of eEmp with external components 
     65 
     66class mpfepdf : public epdf  { 
     67        protected: 
     68                eEmp &E; 
     69                vec &_w; 
     70                Array<epdf*> Coms; 
    5871        public: 
    59         TrivialPF(mpdf &par, mpdf &obs, BM &prop, int n0); 
    60         TrivialPF(mpdf &par, mpdf &obs, int n0); 
    61         void bayes(const vec &dt, bool evalll); 
     72                mpfepdf ( eEmp &E0, const RV &rvc ) : 
     73                                epdf ( RV( ) ), E ( E0 ),  _w ( E._w() ), 
     74                                Coms ( _w.length() ) { 
     75                        rv.add ( E._rv() ); 
     76                        rv.add ( rvc ); 
     77                }; 
     78 
     79                void set_elements ( int &i, double wi, epdf* ep ) 
     80                {_w ( i ) =wi; Coms ( i ) =ep;}; 
     81 
     82                vec mean() const { 
     83                        // ugly 
     84                        vec pom=zeros ( ( Coms ( 0 )->_rv() ).count() ); 
     85 
     86                        for ( int i=0; i<_w.length(); i++ ) {pom += Coms ( i )->mean() * _w ( i );} 
     87 
     88                        return concat ( E.mean(),pom ); 
     89                } 
     90 
     91                vec sample() const {it_error ( "Not implemented" );return 0;} 
     92 
     93                double evalpdflog ( const vec &val ) const {it_error ( "not implemented" ); return 0.0;} 
     94        }; 
     95 
     96        //! estimate joining PF.est with conditional 
     97        mpfepdf jest; 
     98 
     99public: 
     100        //! Default constructor. 
     101        MPF ( const RV &rvlin, const RV &rvpf, mpdf &par0, mpdf &obs0, int n, const BM_T &BMcond0 ) : PF ( rvpf ,par0,obs0,n ),jest ( est,rvlin ) { 
     102                // 
     103                //TODO test if rv and BMcond.rv are compatible. 
     104                rv.add ( rvlin ); 
     105                // 
     106 
     107                if ( n>1000 ) it_error ( "increase 1000 here!" ); 
     108 
     109                for ( int i=0;i<n;i++ ) { 
     110                        Bms[i] = new BM_T ( BMcond0 ); //copy constructor 
     111                        epdf& pom=Bms[i]->_epdf(); 
     112                        jest.set_elements ( i,1.0/n,&pom ); 
     113                } 
     114        }; 
     115 
     116        ~MPF() { 
     117        } 
     118 
     119        void bayes ( const vec &dt ); 
     120        epdf& _epdf() {return jest;} 
     121 
     122        void set_est ( const epdf& epdf0 ) { 
     123                PF::set_est ( epdf0 );  // sample params in condition 
     124                // copy conditions to BMs 
     125 
     126                for ( int i=0;i<n;i++ ) {Bms[i]->condition ( _samples ( i ) );} 
     127        } 
    62128}; 
    63129 
    64 class MPF : public TrivialPF { 
    65         Array<BM> Bms; 
    66         public: 
    67         MPF(BM &B, BM &prop, mpdf &obs, mpdf &par); 
    68         void bayes(vec &dt);     
    69 }; 
     130template<class BM_T> 
     131void MPF<BM_T>::bayes ( const vec &dt ) { 
     132        int i; 
     133        vec lls ( n ); 
     134        ivec ind; 
     135        double mlls=-std::numeric_limits<double>::infinity(); 
     136        double sum=0.0; 
     137 
     138        for ( i=0;i<n;i++ ) { 
     139                //generate new samples from paramater evolution model; 
     140                _samples ( i ) = par.samplecond ( _samples ( i ), lls ( i ) ); 
     141                Bms[i]->condition ( _samples ( i ) ); 
     142                Bms[i]->bayes ( dt ); 
     143                lls ( i ) += Bms[i]->_ll(); 
     144 
     145                if ( lls ( i ) >mlls ) mlls=lls ( i ); //find maximum likelihood (for numerical stability) 
     146        } 
     147 
     148        // compute weights 
     149        for ( i=0;i<n;i++ ) { 
     150                _w ( i ) *= exp ( lls ( i ) - mlls ); // multiply w by likelihood 
     151        } 
     152 
     153        //renormalize 
     154        for ( i=0;i<n;i++ ) {sum+=_w ( i );}; 
     155 
     156        _w /=sum; //? 
     157 
     158        if ( ( _w*_w ) < ( 0.5*n ) ) { 
     159                ind = est.resample(); 
     160                // Resample Bms! 
     161 
     162                for ( i=0;i<n;i++ ) { 
     163                        if ( ind ( i ) !=i ) {//replace the current Bm by a new one 
     164                                //fixme this would require new assignment operator 
     165                                // *Bms[i] = *Bms[ind ( i ) ]; 
     166                                 
     167                                // poor-man's solution: replicate constructor here 
     168                                // copied from MPF::MPF 
     169                                delete Bms[i]; 
     170                                Bms[i] = new BM_T ( *Bms[ind ( i ) ] ); //copy constructor 
     171                                epdf& pom=Bms[i]->_epdf(); 
     172                                jest.set_elements ( i,1.0/n,&pom ); 
     173                        } 
     174                }; 
     175        } 
     176} 
    70177 
    71178#endif // KF_H