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 | } |