| 358 | | \f[ y_t = a y_{t-1} + b u_{t-1}\f] |
| 359 | | the state \f$ x_t = [y_{t-1}, u_{t-1}] \f$ |
| 360 | | */ |
| 361 | | template<class sq_T> |
| 362 | | shared_ptr<StateSpace<fsqmat> > to_state_space(const mlnorm<sq_T > &ml, ivec &theta_in_A, ivec &theta_in_C){ |
| 363 | | //get ids of yrv |
| 364 | | |
| 365 | | ivec yids= unique(ml._rv()._ids()); //yrv is now stored in _yrv |
| 366 | | ivec dids= unique(ml._rvc()._ids()); //yrv is now stored in _yrv |
| 367 | | ivec uids=unique_complement(dids, yids); |
| 368 | | |
| 369 | | RV yrv_uni = RV(yids,zeros_i(yids.length())); |
| 370 | | RV urv_uni = RV(uids,zeros_i(yids.length())); |
| | 358 | Using Frobenius form, see []. |
| | 359 | |
| | 360 | For easier use in the future, indeces theta_in_A and theta_in_C are set. TODO - explain |
| | 361 | */ |
| | 362 | //template<class sq_T> |
| | 363 | class StateCanonical: public StateSpace<fsqmat>{ |
| | 364 | protected: |
| | 365 | //! remember connection from theta ->A |
| | 366 | datalink_part th2A; |
| | 367 | //! remember connection from theta ->C |
| | 368 | datalink_part th2C; |
| | 369 | //! remember connection from theta ->D |
| | 370 | datalink_part th2D; |
| | 371 | //!cached first row of A |
| | 372 | vec A1row; |
| | 373 | //!cached first row of C |
| | 374 | vec C1row; |
| | 375 | //!cached first row of D |
| | 376 | vec D1row; |
| | 377 | |
| | 378 | public: |
| | 379 | //! set up this object to match given mlnorm |
| | 380 | void connect_mlnorm(const mlnorm<fsqmat > &ml){ |
| | 381 | //get ids of yrv |
| | 382 | const RV &yrv = ml._rv(); |
| | 383 | //need to determine u_t - it is all in _rvc that is not in ml._rv() |
| | 384 | RV rgr0 = ml._rvc().remove_time(); |
| | 385 | RV urv = rgr0.subt(yrv); |
| | 386 | |
| 378 | | xrv.add(yrv_uni); |
| 379 | | Crv.add(urv_uni); |
| 380 | | } |
| 381 | | |
| 382 | | int dimx = xrv._dsize(); |
| 383 | | |
| 384 | | theta_in_A = ml._rv().dataind(xrv); |
| 385 | | theta_in_C = ml._rvc().dataind(xrv); |
| 386 | | // some chcek of corretness |
| 387 | | |
| 388 | | vec A1row = zeros(xrv._dsize()); |
| 389 | | vec C1row = zeros(xrv._dsize()); |
| | 396 | xrv.add(yrv.copy_t(t)); |
| | 397 | Crv.add(urv.copy_t(t)); |
| | 398 | } |
| | 399 | |
| | 400 | this->dimx = xrv._dsize(); |
| | 401 | this->dimy = yrv._dsize(); |
| | 402 | this->dimu = urv._dsize(); |
| | 403 | |
| | 404 | // get mapp |
| | 405 | th2A.set_connection(xrv, ml._rvc()); |
| | 406 | th2C.set_connection(Crv, ml._rvc()); |
| | 407 | th2D.set_connection(urv, ml._rvc()); |
| | 408 | |
| | 409 | //set matrix sizes |
| | 410 | this->A=zeros(dimx,dimx); |
| | 411 | for (int j=1; j<dimx; j++){A(j,j-1)=1.0;} // off diagonal |
| | 412 | this->B=zeros(dimx,1); |
| | 413 | this->B(0) = 1.0; |
| | 414 | this->C=zeros(1,dimx); |
| | 415 | this->D=zeros(1,urv._dsize()); |
| | 416 | this->Q = zeros(dimx,dimx); |
| | 417 | // R is set by update |
| | 418 | |
| | 419 | //set cache |
| | 420 | this->A1row = zeros(xrv._dsize()); |
| | 421 | this->C1row = zeros(xrv._dsize()); |
| | 422 | this->D1row = zeros(urv._dsize()); |
| | 423 | |
| | 424 | update_from(ml); |
| | 425 | validate(); |
| | 426 | }; |
| | 427 | //! fast function to update parameters from ml - not checked for compatibility!! |
| | 428 | void update_from(const mlnorm<fsqmat> &ml){ |
| | 429 | |
| 391 | | set_subvector( A1row, theta_in_A, theta); |
| 392 | | set_subvector( C1row, theta_in_C, theta); |
| 393 | | |
| 394 | | StateSpace<fsqmat> stsp=new StateSpace<fsqmat>(); |
| 395 | | mat A=zeros(dimx,dimx); |
| | 431 | |
| | 432 | th2A.filldown(theta,A1row); |
| | 433 | th2C.filldown(theta,C1row); |
| | 434 | th2D.filldown(theta,D1row); |
| | 435 | |
| | 436 | R = ml._R(); |
| | 437 | |