Changeset 605

Show
Ignore:
Timestamp:
09/06/09 22:53:08 (15 years ago)
Author:
smidl
Message:

StateCanonical? = StateSpace? model with connection to ARX models

Location:
library
Files:
2 modified

Legend:

Unmodified
Added
Removed
  • library/bdm/estim/kalman.h

    r586 r605  
    8585                int _dimu(){return dimu;} 
    8686                //! access function 
    87                 mat _A(){return A;} 
    88                 //! access function 
    89                 mat _B(){return B;} 
    90                 //! access function 
    91                 mat _C(){return C;} 
    92                 //! access function 
    93                 mat _D(){return D;} 
    94                 //! access function 
    95                 sq_T _Q(){return Q;} 
    96                 //! access function 
    97                 sq_T _R(){return R;} 
     87                const mat& _A() const {return A;} 
     88                //! access function 
     89                const mat& _B()const {return B;} 
     90                //! access function 
     91                const mat& _C()const {return C;} 
     92                //! access function 
     93                const mat& _D()const {return D;} 
     94                //! access function 
     95                const sq_T& _Q()const {return Q;} 
     96                //! access function 
     97                const sq_T& _R()const {return R;} 
    9898}; 
    9999 
     
    356356\f[ x_{t+1} = Ax_t + B u_t + R^{1/2} e_t, y_t=Cx_t+Du_t + R^{1/2}w_t, \f] 
    357357For example, for: 
    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())); 
     358Using Frobenius form, see []. 
     359 
     360For easier use in the future, indeces theta_in_A and theta_in_C are set. TODO - explain 
     361*/ 
     362//template<class sq_T> 
     363class 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                         
    371387                        //We can do only 1d now... :( 
    372                         bdm_assert_debug(yrv_uni._dsize()==urv_uni._dsize()==1, "Only for SISO so far..." ); 
    373                                          
     388                        bdm_assert_debug(yrv._dsize()==1, "Only for SISO so far..." ); 
     389 
     390                        // create names for  
    374391                        RV xrv; //empty 
    375392                        RV Crv; //empty 
    376                         int td=ml._rvc().mintd(); 
     393                        int td=ml._rvc().mint(); 
     394                        // assuming strictly proper function!!! 
    377395                        for (int t=-1;t>=td;t--){ 
    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                         
    390430                        vec theta = ml._A().get_row(0); // this  
    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 
    396438                        A.set_row(0,A1row); 
    397                         for (int j=1; j<dimx; j++){A(j,j-1)=1.0;} // off diagonal 
    398                         mat B=zeros(dimx,1); 
    399                         B(0) = 1.0; 
    400                         mat C=zeros(1,dimx); 
    401                         C.set_row(0,C1row); 
    402                         stsp.set_parameters(A,B,C,zeros(1,1), zeros(dimx,dimx), ml._R()); 
    403                         return stsp; 
    404 } 
     439                        C.set_row(0,C1row+D1row*A1row); 
     440                        D.set_row(0,D1row); 
     441                         
     442                } 
     443}; 
    405444 
    406445/////////// INSTANTIATION 
  • library/tests/LQG_test.cpp

    r588 r605  
    11#define BDMLIB 
    2 #include "UnitTest++.h" 
     2#include "mat_checks.h" 
    33#include "design/ctrlbase.h" 
    44 
     
    1818} 
    1919 
     20TEST(test_to_state) { 
     21        mlnorm<fsqmat> ml; 
     22        mat A="1.1, 2.3"; 
     23        ml.set_parameters(A, vec_1(1.3), eye(1)); 
     24        RV yr=RV("y",1); 
     25        RV ur=RV("u",1); 
     26        ml.set_rv(yr); 
     27        yr.t_plus(-1); 
     28        ml.set_rvc(concat(yr, ur)); 
     29         
     30        shared_ptr<StateCanonical > Stsp=new StateCanonical; 
     31        Stsp->connect_mlnorm(ml); 
     32         
     33        /* results from  
     34        [A,B,C,D]=tf2ss([2.3 0],[1 -1.1]) 
     35        */ 
     36        CHECK_CLOSE_EX(Stsp->_A().get_row(0), vec("1.1"), 0.0001); 
     37        CHECK_CLOSE_EX(Stsp->_C().get_row(0), vec("2.53"), 0.0001); 
     38        CHECK_CLOSE_EX(Stsp->_D().get_row(0), vec("2.30"), 0.0001); 
     39} 
     40 
     41