Show
Ignore:
Timestamp:
08/17/10 22:06:50 (14 years ago)
Author:
smidl
Message:

Kalman with UD (bierman, thorton) and tests

Files:
1 modified

Legend:

Unmodified
Added
Removed
  • library/bdm/estim/kalman.cpp

    r1064 r1158  
    436436} 
    437437 
    438 } 
     438void EKF_UD::set_parameters ( const shared_ptr<diffbifn> &pfxu0, const shared_ptr<diffbifn> &phxu0, const mat Q0, const vec R0 ) { 
     439        pfxu = pfxu0; 
     440        phxu = phxu0; 
     441         
     442        set_dim ( pfxu0->_dimx() ); 
     443        dimy = phxu0->dimension(); 
     444        dimc = pfxu0->_dimu(); 
     445         
     446        vec &_mu = est._mu(); 
     447        // if mu is not set, set it to zeros, just for constant terms of A and C 
     448        if ( _mu.length() != dimension() ) _mu = zeros ( dimension() ); 
     449        A = zeros ( dimension(), dimension() ); 
     450        C = zeros ( dimy, dimension() ); 
     451         
     452        //initialize matrices A C, later, these will be only updated! 
     453        pfxu->dfdx_cond ( _mu, zeros ( dimc ), A, true ); 
     454        //      pfxu->dfdu_cond ( *_mu,zeros ( dimu ),B,true ); 
     455        phxu->dfdx_cond ( _mu, zeros ( dimc ), C, true ); 
     456        //      phxu->dfdu_cond ( *_mu,zeros ( dimu ),D,true ); 
     457         
     458        R = R0; 
     459        Q = Q0; 
     460         
     461        //  
     462} 
     463 
     464 
     465void EKF_UD::bayes ( const vec &yt, const vec &cond ) { 
     466        //preparatory 
     467        vec &_mu=est._mu(); 
     468        const vec &u=cond; 
     469        int dim = dimension(); 
     470         
     471        U = est._R()._L().T(); 
     472        D =  est._R()._D(); 
     473         
     474        //////////// 
     475         
     476        pfxu->dfdx_cond ( _mu, u, A, false ); //update A by a derivative of fx 
     477        phxu->dfdx_cond ( _mu, u, C, false ); //update A by a derivative of fx 
     478 
     479        mat PhiU = A*U; 
     480         
     481        vec Din = D; 
     482        int i,j,k; 
     483        double sigma; 
     484        mat G = eye(dim); 
     485        //////// thorton 
     486         
     487        //move mean; 
     488        _mu = pfxu->eval(_mu,u); 
     489         
     490        for (i=dim-1; i>=0;i--){ 
     491                sigma = 0.0;  
     492                for (j=0; j<dim; j++) { 
     493                        sigma += PhiU(i,j)*PhiU(i,j) *Din(j);  
     494                        sigma += G(i,j)*G(i,j) * Q(j,j);  
     495                } 
     496                D(i) = sigma;  
     497                for (j=0;j<i;j++){  
     498                        sigma = 0.0;  
     499                        for (k=0;k<dim;k++){  
     500                                sigma += PhiU(i,k)*Din(k)*PhiU(j,k);  
     501                        } 
     502                        for (k=0;k<dim;k++){  
     503                                sigma += G(i,k)*Q(k,k)*G(j,k);  
     504                        } 
     505                        // 
     506                        U(j,i) = sigma/D(i);  
     507                        for (k=0;k<dim;k++){  
     508                                PhiU(j,k) = PhiU(j,k) - U(j,i)*PhiU(i,k);  
     509                        } 
     510                        for (k=0;k<dim;k++){  
     511                                G(j,k) = G(j,k) - U(j,i)*G(i,k);  
     512                        } 
     513                } 
     514        } 
     515        //cout << "Ut: " << U << endl; 
     516        //cout << "Dt: " << D << endl; 
     517        // bierman 
     518         
     519        double dz,alpha,gamma,beta,lambda; 
     520        vec a; 
     521        vec b; 
     522        vec yp = phxu->eval(_mu,u); 
     523        for (int iy=0; iy<dimy; iy++){ 
     524                a     = U.T()*C.get_row(iy);    // a is not modified, but  
     525                b     = elem_mult(D,a);                          // b is modified to become unscaled Kalman gain.  
     526                dz    = yt(iy) - yp(iy);  
     527 
     528                alpha = R(iy);  
     529                gamma = 1/alpha;  
     530                for (j=0;j<dim;j++){ 
     531                        beta   = alpha;  
     532                        alpha  = alpha + a(j)*b(j);  
     533                        lambda = -a(j)*gamma;  
     534                        gamma  = 1.0/alpha;  
     535                        D(j) = beta*gamma*D(j);  
     536 
     537                        cout << "a: " << alpha << "g: " << gamma << endl; 
     538                        for (i=0;i<j;i++){ 
     539                                beta   = U(i,j);  
     540                                U(i,j) = beta + b(i)*lambda;  
     541                                b(i)   = b(i) + b(j)*beta;  
     542                        } 
     543                } 
     544                double dzs = gamma*dz;  // apply scaling to innovations  
     545                _mu   = _mu + dzs*b; // multiply by unscaled Kalman gain  
     546                 
     547                //cout << "Ub: " << U << endl; 
     548                //cout << "Db: " << D << endl <<endl; 
     549                 
     550        } 
     551                 
     552///// 
     553est._R().__L()=U.T(); 
     554est._R().__D()=D; 
     555 
     556        if ( evalll == true ) { //likelihood of observation y 
     557        } 
     558} 
     559 
     560void EKF_UD::from_setting ( const Setting &set ) { 
     561        BM::from_setting ( set ); 
     562        shared_ptr<diffbifn> IM = UI::build<diffbifn> ( set, "IM", UI::compulsory ); 
     563        shared_ptr<diffbifn> OM = UI::build<diffbifn> ( set, "OM", UI::compulsory ); 
     564         
     565        //statistics 
     566        int dim = IM->dimension(); 
     567        vec mu0; 
     568        if ( !UI::get ( mu0, set, "mu0" ) ) 
     569                mu0 = zeros ( dim ); 
     570         
     571        mat P0; 
     572        vec dP0; 
     573        if ( UI::get ( dP0, set, "dP0" ) ) 
     574                P0 = diag ( dP0 ); 
     575        else if ( !UI::get ( P0, set, "P0" ) ) 
     576                P0 = eye ( dim ); 
     577         
     578        est._mu()=mu0; 
     579        est._R()=ldmat(P0); 
     580         
     581        //parameters 
     582        vec dQ, dR; 
     583        UI::get ( dQ, set, "dQ", UI::compulsory ); 
     584        UI::get ( dR, set, "dR", UI::compulsory ); 
     585        set_parameters ( IM, OM, diag ( dQ ), dR  ); 
     586} 
     587 
     588}