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