- Timestamp:
- 08/17/10 22:06:50 (14 years ago)
- Location:
- library
- Files:
-
- 4 modified
Legend:
- Unmodified
- Added
- Removed
-
library/bdm/estim/kalman.cpp
r1064 r1158 436 436 } 437 437 438 } 438 void 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 465 void 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 ///// 553 est._R().__L()=U.T(); 554 est._R().__D()=D; 555 556 if ( evalll == true ) { //likelihood of observation y 557 } 558 } 559 560 void 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 } -
library/bdm/estim/kalman.h
r1154 r1158 362 362 363 363 void validate() { 364 KalmanFull::validate();364 // KalmanFull::validate(); 365 365 366 366 // check stats and IM and OM … … 426 426 SHAREDPTR ( EKFCh ); 427 427 428 //! EKF using bierman and Thorton code 429 class EKF_UD : public BM { 430 protected: 431 //! Internal Model f(x,u) 432 shared_ptr<diffbifn> pfxu; 433 434 //! Observation Model h(x,u) 435 shared_ptr<diffbifn> phxu; 436 437 //! U part 438 mat U; 439 //! D part 440 vec D; 441 442 mat A; 443 mat C; 444 mat Q; 445 vec R; 446 447 enorm<ldmat> est; 448 public: 449 //! copy constructor duplicated 450 EKF_UD* _copy() const { 451 return new EKF_UD(*this); 452 } 453 454 const enorm<ldmat>& posterior()const{return est;}; 455 456 enorm<ldmat>& prior() { 457 return const_cast<enorm<ldmat>&>(posterior()); 458 } 459 460 461 EKF_UD(){} 462 463 EKF_UD(const EKF_UD &E0): pfxu(E0.pfxu),phxu(E0.phxu), U(E0.U), D(E0.D){} 464 465 //! Set nonlinear functions for mean values and covariance matrices. 466 void set_parameters ( const shared_ptr<diffbifn> &pfxu, const shared_ptr<diffbifn> &phxu, const mat Q0, const vec R0 ); 467 468 //! Here dt = [yt;ut] of appropriate dimensions 469 void bayes ( const vec &yt, const vec &cond = empty_vec ); 470 471 /*! Create object from the following structure 472 473 \code 474 class = 'EKF_UD'; 475 OM = configuration of bdm::diffbifn; % any offspring of diffbifn, bdm::diffbifn::from_setting 476 IM = configuration of bdm::diffbifn; % any offspring of diffbifn, bdm::diffbifn::from_setting 477 dQ = [...]; % vector containing diagonal of Q 478 dR = [...]; % vector containing diagonal of R 479 --- optional fields --- 480 mu0 = [...]; % vector of statistics mu0 481 dP0 = [...]; % vector containing diagonal of P0 482 -- or -- 483 P0 = [...]; % full matrix P0 484 --- inherited fields --- 485 bdm::BM::from_setting 486 \endcode 487 If the optional fields are not given, they will be filled as follows: 488 \code 489 mu0 = [0,0,0,....]; % empty statistics 490 P0 = eye( dim ); 491 \endcode 492 */ 493 void from_setting ( const Setting &set ); 494 495 void validate() {}; 496 // TODO dodelat void to_setting( Setting &set ) const; 497 498 }; 499 UIREGISTER(EKF_UD); 500 428 501 class UKFCh : public EKFCh{ 429 502 public: … … 468 541 469 542 //step 4 470 mat Xpred_dif(dim2,dim); 543 mat P4=Q.to_mat(); 544 vec tmp; 471 545 for (i=0;i<dim2;i++){ 472 Xpred_dif.set_row(i, sqrt(w(i)) * (Xik.get_col(i) - xp)); 546 tmp = Xik.get_col(i)-xp; 547 P4+=w(i)*outer_product(tmp,tmp); 473 548 } 474 475 // NEW Sigma points 476 mat tmp; 477 qr(concat_vertical(Xpred_dif,Q._Ch()), tmp); 478 mat Ppred=tmp.get_rows(0,dim-1); 479 // New Xi(k+1) 480 Xik.set_col(0,xp); 481 for ( i=0;i<dim; i++){ 482 vec tmp=sqrt(npk)*Ppred.get_col(i); 483 Xik.set_col(i+1, _mu+tmp); 484 Xik.set_col(i+1+dim, _mu-tmp); 485 } 486 for (i=0;i<dim2;i++){ 487 Xpred_dif.set_row(i, sqrt(w(i)) * (Xik.get_col(i) - xp)); 488 } 489 490 491 549 492 550 //step 5 493 551 mat Yi(dimy,dim2); … … 501 559 } 502 560 //step 7 503 mat Ypred_dif(dim2,dimy); 504 505 for (i=0; i<dim2; i++){ 506 Ypred_dif.set_row(i, sqrt(w(i))*(Yi.get_col(i)-_yp)); 507 } 508 if (!qr(concat_vertical(Ypred_dif,R._Ch()) ,tmp)){ bdm_warning("QR failed");} 509 _Ry._Ch() = tmp.get_rows(0,dimy-1); 561 mat Pvv=R.to_mat(); 562 for (i=0;i<dim2;i++){ 563 tmp = Yi.get_col(i)-_yp; 564 Pvv+=w(i)*outer_product(tmp,tmp); 565 } 566 _Ry._Ch() = chol(Pvv); 510 567 511 568 // step 8 512 mat Pxy=Xpred_dif.T()*Ypred_dif; 569 mat Pxy=zeros(dim,dimy); 570 for (i=0;i<dim2;i++){ 571 Pxy+=w(i)*outer_product(Xi.get_col(i)-xp, Yi.get_col(i)-_yp); 572 } 513 573 mat iRy=inv(_Ry._Ch()); 514 574 … … 516 576 mat K=Pxy*iRy*iRy.T(); 517 577 mat K2=Pxy*inv(_Ry.to_mat()); 518 578 519 579 /////////////// new filtering density 520 580 _mu = xp + K*(yt - _yp); 581 582 if ( _mu ( 3 ) >pi ) _mu ( 3 )-=2*pi; 583 if ( _mu ( 3 ) <-pi ) _mu ( 3 ) +=2*pi; 521 584 // fill the space in Ppred; 522 mat Rpred =concat_vertical(Xpred_dif - Ypred_dif*K.T(), _Ry._Ch()*K.T()); 523 524 if(!qr(Rpred,tmp)) {bdm_warning("QR failed");} 525 _P._Ch()=tmp.get_rows(0,dim-1); 585 _P._Ch()=chol(P4-K*_Ry.to_mat()*K.T()); 526 586 } 527 587 void from_setting(const Setting &set){ -
library/tests/stresssuite/kalman_stress.cpp
r1064 r1158 51 51 RV ry ( "{y }", vec_1 ( C.rows() ) ); 52 52 53 // // LDMAT 54 // Kalman<ldmat> KF(rx,ry,ru); 55 // KF.set_parameters(A,B,C,D,ldmat(R),ldmat(Q)); 56 // KF.set_est(mu0,ldmat(P0) ); 57 // epdf& KFep = KF.posterior(); 58 // mat Xt(2,Ndat); 59 // Xt.set_col( 0,KFep.mean() ); 53 // LDMAT 54 EKF_UD KFu; 55 KFu.set_rv(rx); 56 KFu.set_yrv(ry); 57 KFu.set_rvc(ru); 58 shared_ptr<bilinfn> f=new bilinfn; f->set_parameters(A,B); 59 shared_ptr<bilinfn> h=new bilinfn; h->set_parameters(C,D); 60 KFu.set_parameters(f,h,Q,diag(R)); 61 KFu.prior()._mu()=mu0; 62 KFu.prior()._R()=ldmat(P0); 63 const epdf& KFuep = KFu.posterior(); 64 mat Xtu(dimx,Ndat); 65 Xtu.set_col( 0,KFuep.mean() ); 60 66 61 67 //Chol … … 99 105 for ( int t = 1; t < Ndat; t++ ) { 100 106 dt = Dt.get_col ( t ); 101 KF .bayes ( dt.get ( 0, C.rows() - 1 ), dt.get ( C.rows(), dt.length() - 1 ) );102 Xt .set_col ( t, KFep.mean() );107 KFu.bayes ( dt.get ( 0, C.rows() - 1 ), dt.get ( C.rows(), dt.length() - 1 ) ); 108 Xtu.set_col ( t, KFuep.mean() ); 103 109 } 104 110 exec_times ( 0 ) = tt.toc(); … … 122 128 123 129 it_file fou ( "kalman_stress_res.it" ); 124 fou << Name ( "xth " ) << Xt;130 fou << Name ( "xthu" ) << Xtu; 125 131 fou << Name ( "xth2" ) << Xt2; 126 132 fou << Name ( "xthE" ) << XtE; -
library/tests/stresssuite/kalman_stress.m
r721 r1158 60 60 Mu(1:2,t)=mu; 61 61 62 [Oxt,OPt,ll(t)] = Kalman(Oxt,y(:,t),A,C,Q,R,OPt);62 % [Oxt,OPt,ll(t)] = Kalman(Oxt,y(:,t),A,C,Q,R,OPt); 63 63 % [oxt,oPt,oll(t)] = KalmanSq(oxt,y(:,t),A,C,sQ,sR,oPt); 64 MuK(1:2,t) = Oxt;64 % MuK(1:2,t) = Oxt; 65 65 % MuS(1:2,t) = oxt; 66 66 end … … 68 68 %keyboard 69 69 70 ! cd ../;./tests/testKF71 itload(' testKF_res.it');70 !./stresssuite kalman_stress 71 itload('kalman_stress_res.it'); 72 72 73 73 hold off … … 77 77 plot(xth2','+'); 78 78 plot(xthE','o'); 79 plot([zeros(size(xth,1),1) MuK]','d'); % shift the predictions79 %plot([zeros(size(xth,1),1) MuK]','d'); % shift the predictions 80 80 81 81 exec_times