| | 505 | |
| | 506 | } |
| | 507 | }; |
| | 508 | /*! |
| | 509 | State-Space representation of multivariate autoregressive model. |
| | 510 | The original model: |
| | 511 | \f[ y_t = \theta [\ldots y_{t-k}, \ldots u_{t-l}, \ldots z_{t-m}]' + \Sigma^{-1/2} e_t \f] |
| | 512 | where \f$ k,l,m \f$ are maximum delayes of corresponding variables in the regressor. |
| | 513 | |
| | 514 | The transformed state is: |
| | 515 | \f[ x_t = [y_{t} \ldots y_{t-k-1}, u_{t} \ldots u_{t-l-1}, z_{t} \ldots z_{t-m-1}]\f] |
| | 516 | |
| | 517 | The state accumulates all delayed values starting from time \f$ t \f$ . |
| | 518 | |
| | 519 | |
| | 520 | */ |
| | 521 | class StateFromARX: public StateSpace<fsqmat>{ |
| | 522 | protected: |
| | 523 | //! remember connection from theta ->A |
| | 524 | datalink_part th2A; |
| | 525 | //! xrv |
| | 526 | RV xrv; |
| | 527 | //!function adds n diagonal elements from given starting point r,c |
| | 528 | void diagonal_part(mat &A, int r, int c, int n){ |
| | 529 | for(int i=0; i<n; i++){A(r,c)=1.0; r++;c++;} |
| | 530 | }; |
| | 531 | public: |
| | 532 | //! set up this object to match given mlnorm |
| | 533 | void connect_mlnorm(const mlnorm<fsqmat> &ml){ |
| | 534 | //get ids of yrv |
| | 535 | const RV &yrv = ml._rv(); |
| | 536 | //need to determine u_t - it is all in _rvc that is not in ml._rv() |
| | 537 | const RV &rgr = ml._rvc(); |
| | 538 | RV rgr0 = rgr.remove_time(); |
| | 539 | RV urv = rgr0.subt(yrv); |
| | 540 | |
| | 541 | // create names for state variables |
| | 542 | xrv=yrv; |
| | 543 | |
| | 544 | int y_multiplicity = rgr.mint(yrv); |
| | 545 | int y_block_size = yrv.length()*(y_multiplicity+1); // current yt + all delayed yts |
| | 546 | for (int m=0;m<y_multiplicity;m++){ |
| | 547 | xrv.add(yrv.copy_t(-m-1)); //add delayed yt |
| | 548 | } |
| | 549 | // add regressors |
| | 550 | ivec u_block_sizes(urv.length()); // no_blocks = yt + unique rgr |
| | 551 | for (int r=0;r<urv.length();r++){ |
| | 552 | RV R=urv.subselect(vec_1(r)); //non-delayed element of rgr |
| | 553 | int r_size=urv.size(r); |
| | 554 | int r_multiplicity=rgr.mint(R); |
| | 555 | u_block_sizes(r)= r_size*r_multiplicity ; |
| | 556 | for(int m=0;m<r_multiplicity;m++){ |
| | 557 | xrv.add(R.copy_t(-m-1)); //add delayed yt |
| | 558 | } |
| | 559 | } |
| | 560 | |
| | 561 | // get mapp |
| | 562 | th2A.set_connection(xrv, ml._rvc()); |
| | 563 | |
| | 564 | //set matrix sizes |
| | 565 | this->A=zeros(xrv._dsize(),xrv._dsize()); |
| | 566 | //create y block |
| | 567 | diagonal_part(this->A, yrv._dsize(), 0, y_block_size-yrv._dsize() ); |
| | 568 | |
| | 569 | this->B=zeros(xrv._dsize(), urv._dsize()); |
| | 570 | //add diagonals for rgr |
| | 571 | int active_x=y_block_size; |
| | 572 | for (int r=0; r<urv.length(); r++){ |
| | 573 | diagonal_part( this->A, active_x+urv.size(r),active_x, u_block_sizes(r)-urv.size(r)); |
| | 574 | this->B.set_submatrix(active_x, 0, eye(urv.size(r))); |
| | 575 | active_x+=u_block_sizes(r); |
| | 576 | } |
| | 577 | this->C=zeros(yrv._dsize(), xrv._dsize()); |
| | 578 | this->C.set_submatrix(0,0,eye(yrv._dsize())); |
| | 579 | this->D=zeros(yrv._dsize(),urv._dsize()); |
| | 580 | this->R = zeros(yrv._dsize(),yrv._dsize()); |
| | 581 | this->Q = zeros(xrv._dsize(),xrv._dsize()); |
| | 582 | // Q is set by update |
| | 583 | |
| | 584 | update_from(ml); |
| | 585 | validate(); |
| | 586 | }; |
| | 587 | //! fast function to update parameters from ml - not checked for compatibility!! |
| | 588 | void update_from(const mlnorm<fsqmat> &ml){ |
| | 589 | |
| | 590 | vec theta = ml._A().get_row(0); // this |
| | 591 | this->Q._M().set_submatrix(0,0,ml._R()); |