Changeset 586

Show
Ignore:
Timestamp:
08/27/09 15:39:35 (15 years ago)
Author:
smidl
Message:

redesign of ctrl LQ control for arx

Files:
1 added
10 modified

Legend:

Unmodified
Added
Removed
  • applications/bdmtoolbox/tutorial/estimation/arx_test.m

    r414 r586  
     1theta = [0.8, -0.3, 0.4, 1.0;... 
     2         0.0, 0.0, 0.0, 0.0]; 
     3R = [0.1, 0.0; 0.0, 1.0]; 
     4 
     5 
    16y = struct('class','RV','names',{{'y'}});  
     7y.class = 'RV'; 
     8y.names= {'y'}; 
     9 
    210u = struct('class','RV','names',{{'u'}});  
    3 yu = struct('class','RV','names',{{'y','u'}});  
     11%yu = struct('class','RV','names',{{'y','u'}});  
    412rgr= struct('class','RV',... 
    513        'names',{{'y', 'y','y','u'}},... 
     
    1220        'u',  struct('class','RV','names',{{}}),... 
    1321        'rgr', rgr,... 
    14         'theta', [0.8, -0.3, 0.4, 1.0; 
    15               0.0, 0.0, 0.0, 0.0],... 
     22        'theta', theta,... 
    1623        'offset',  [0.0, 0.0],... 
    17         'r', [0.1, 0.0; 0.0, 1.0],... 
     24        'r', R,... 
    1825        'opt', 'L_theta'); 
    1926 
    20 %store results 
    21 logger = struct(... 
    22         'class','dirfilelog',... 
    23         'dirname','arx_test',... 
    24         'maxlen',  1000); 
     27% store results 
     28% logger = struct(... 
     29%       'class','dirfilelog',... 
     30%       'dirname','arx_test',... 
     31%       'maxlen',  1000); 
    2532 
    26 estimators = { 
    27         struct('class','ARX',... 
    28         'y', y,... 
    29         'rgr', rgr) 
    30 }; 
     33A1.class = 'ARX'; 
     34A1.y = y; 
     35A1.rgr = rgr; 
     36A1.options ='logbounds,logll'; 
     37 
     38estimators = { A1}; 
    3139 
    3240%experiment description 
    33 experiment.ndat = 9000; 
     41ndat = 90; 
     42experiment.ndat = ndat; 
    3443 
    3544M=estimator(system,estimators,experiment);%,logger); 
     45 
     46%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 
     47% plot results 
     48 
     49subplot(1,2,1); 
     50hold off 
     51plot([M.tth(1:ndat,1:2:end) ],'-.'); 
     52title(' Regression parameters \theta') 
     53hold on 
     54plot(M.mean_theta(1:ndat,:)); 
     55co = get(gca,'ColorOrder'); 
     56for i=1:4 
     57    ind =1:10:ndat; 
     58    h=errorbar(ind,M.mean_theta(ind,i),... 
     59    M.mean_theta(ind,i)-M.lb_theta(ind,i),M.mean_theta(ind,i)-M.ub_theta(ind,i),'.'); 
     60    set(h,'color',co(i,:)); 
     61end 
     62 
     63set(gca,'YLim',[-0.7,2]); 
     64 
     65subplot(1,2,2); 
     66hold off 
     67plot([M.rR(1:ndat) ],'-.'); 
     68title('Variance parameters r') 
     69hold on 
     70plot(M.mean_r(1:ndat,:)); 
     71co = get(gca,'ColorOrder'); 
     72ind =1:10:ndat; 
     73for i=1:size(M.mean_r, 2) 
     74    h=errorbar(ind,M.mean_r(ind,i),... 
     75    M.mean_r(ind,i)-M.lb_r(ind,i),M.mean_r(ind,i)-M.ub_r(ind,i),'.'); 
     76    set(h,'color',co(i,:)); 
     77end 
  • library/bdm/CMakeLists.txt

    r565 r586  
    2222 
    2323# Normal BDM library 
    24 add_library (bdm STATIC ${bdm_support} ${bdm_base} ${bdm_math} ${bdm_stat} ${bdm_estim} ${bdm_mex} ${bdm_user_info}) 
     24add_library (bdm STATIC ${bdm_support} ${bdm_base} ${bdm_math} ${bdm_stat} ${bdm_estim} ${bdm_ctrl} ${bdm_mex} ${bdm_user_info}) 
  • library/bdm/base/bdmbase.h

    r584 r586  
    995995                                set_drv (*r); 
    996996                        } 
     997                        string opt; 
     998                        if(!UI::get(opt, set, "options", UI::optional)) { 
     999                                set_options(opt); 
     1000                        } 
    9971001                } 
    9981002 
  • library/bdm/design/ctrlbase.cpp

    r565 r586  
    33namespace bdm{ 
    44 
    5 void LQG::set_system_parameters(const mat &A0, const mat &B0, const mat &C0){ 
    6         dimx = A0.rows(); 
    7         dimy = C0.rows(); 
    8         dimu = B0.cols(); 
    9  
    10         bdm_assert_debug ( A0.cols() == dimx, "LQG: A is not square" ); 
    11         bdm_assert_debug ( B0.rows() == dimx, "LQG: B is not compatible" ); 
    12         bdm_assert_debug ( C0.cols() == dimx, "LQG: C is not square" ); 
    13  
    14         A=A0; 
    15         B=B0; 
    16         C=C0; 
     5void LQG::set_system(shared_ptr<StateSpace<fsqmat> > S0){ 
     6        S = S0; 
     7        dimx= S->_dimx(); 
     8        dimy= S->_dimy(); 
     9        dimu= S->_dimu(); 
    1710        pr=zeros(dimx+dimu+dimy,  dimu+dimx+dimu+dimy); 
    1811        pr.set_submatrix(dimx, dimu+dimx, eye(dimu+dimy)); 
    1912} 
    2013 
    21 void LQG::set_control_parameters(const mat &Qy0, const mat &Qu0, const vec y_req0, int horizon0){ 
    22         bdm_assert_debug ( Qy0.cols() == dimy, "LQG: wrong dimensions of Qy " ); 
    23         bdm_assert_debug ( Qu0.cols() == dimu, "LQG: wrong dimensions of Qu " ); 
    24         bdm_assert_debug ( y_req0.length() == dimy, "LQG: wrong dimensions of y_req " ); 
    25  
     14void LQG::set_control_parameters(const mat &Qy0, const mat &Qu0, const vec &y_req0, int horizon0){ 
    2615        Qy=Qy0; 
    2716        Qu=Qu0; 
    2817        y_req=y_req0; 
    2918        horizon = horizon0; 
    30         prepare_qr(); 
     19        validate(); 
     20        initialize(); 
    3121} 
    3222 
    33 void LQG::prepare_qr(){ 
     23void LQG::validate() { 
     24        bdm_assert_debug ( Qy.cols() == dimy, "LQG: wrong dimensions of Qy " ); 
     25        bdm_assert_debug ( Qu.cols() == dimu, "LQG: wrong dimensions of Qu " ); 
     26        bdm_assert_debug ( y_req.length() == dimy, "LQG: wrong dimensions of y_req " ); 
     27} 
     28 
     29void LQG::initialize(){ 
    3430        // set parameter matrix 
    35         pr.set_submatrix(0,0,B); 
    36         pr.set_submatrix(0,dimu, A); 
     31        pr.set_submatrix(0,0,S->_B()); 
     32        pr.set_submatrix(0,dimu, S->_A()); 
    3733         
    3834        //penalization 
     
    4238 
    4339        qyx=zeros(dimy, dimx+dimy+dimu); 
    44         qyx.set_submatrix(0,0,C); 
     40        qyx.set_submatrix(0,0,S->_C()); 
    4541        qyx.set_submatrix(0,dimx,-eye(dimy)); 
    4642         
    4743        // 
    48         s=1e-5*eye(4);//dimx+dimu+dimy); 
     44        s=1e-5*eye(dimx+dimu+dimy); 
    4945        // parts of QR 
    5046        hqy=Qy*qyx*pr; 
  • library/bdm/design/ctrlbase.h

    r565 r586  
    1212 
    1313#include "../base/bdmbase.h" 
     14#include "../estim/kalman.h" 
    1415 
    1516namespace bdm{ 
    1617 
    17 //! Base class of designers of control strategy 
    18 class Designer : public root { 
     18//! Low-level class for design of control strategy 
     19class Designer  { 
     20         
    1921        public: 
    2022                //! Redesign control strategy  
     
    3436class LQG : public Designer { 
    3537        protected: 
    36                 //! dimension of state 
    37                 int dimx; 
    38                 //! dimension of inputs 
    39                 int dimu; 
    40                 //! dimension of output 
    41                 int dimy; 
    42  
    43                 //! matrix A of the linear system 
    44                 mat A; 
    45                 //! matrix B of the linear system 
    46                 mat B; 
    47                 //! matrix C of the linear system 
    48                 mat C; 
     38                //! StateSpace model from which we read data 
     39                shared_ptr<StateSpace<fsqmat> > S; 
    4940                //! required value of the output y at time t (assumed constant) 
    5041                vec y_req; 
     42                //! required value of the output y at time t (assumed constant) 
     43                vec u_req; 
    5144                 
    5245                //! Control horizon, set to maxint for infinite horizons 
     
    6154                mat L; 
    6255                 
    63                 //!@{ \name temporary storage for ricatti 
     56                //!@{ \name temporary storage for ricatti - use initialize 
     57                //! convenience parameters 
     58                int dimx; 
     59                //! convenience parameters 
     60                int dimy; 
     61                //! convenience parameters 
     62                int dimu; 
     63                 
    6464                //!  parameters 
    6565                mat pr; 
     
    8282        public: 
    8383                //! set system parameters from given matrices 
    84                 void set_system_parameters(const mat &A, const mat &B, const mat &C); 
     84                void set_system(shared_ptr<StateSpace<fsqmat> > S0); 
    8585                //! set penalization matrices and control horizon 
    86                 void set_control_parameters(const mat &Qy0, const mat &Qu0, const vec y_req0, int horizon0); 
     86                void set_control_parameters(const mat &Qy0, const mat &Qu0, const vec &y_req0, int horizon0); 
    8787                //! set system parameters from Kalman filter 
    8888//              void set_system_parameters(const Kalman &K); 
    8989                //! refresh temporary storage - inefficient can be improved 
    90                 void prepare_qr(); 
    91                 //! function for future use which is called at each time td; Should call prepare_qr()! 
     90                void initialize(); 
     91                void validate(); 
     92                //! function for future use which is called at each time td; Should call initialize()! 
    9293                virtual void update_state(){}; 
    9394                //! redesign one step of the  
     
    113114        } ; 
    114115 
     116        //! Base class for adaptive controllers  
     117        //! The base class is however non-adaptive, method \c adapt() is empty. 
     118        //! \note advanced Controllers will probably include estimator as their internal attribute (e.g. dual controllers) 
     119        class Controller : public root { 
     120                //! identifier of the system output; 
     121                RV yrv; 
     122                //! identifier of the system input; 
     123                RV urv; 
     124                //! description of data needed for \c ctrlaction , required for automatic connection to DS 
     125                RV drv; 
     126                public: 
     127                        //! function processing new observations and adapting control strategy accordingly 
     128                        virtual void adapt(const vec &data){}; 
     129                        //! returns designed control action 
     130                        virtual vec ctrlaction(const vec &data){return vec(0);} 
     131                         
     132                        void from_setting(const Setting &set){ 
     133                                UI::get(yrv,set,"yrv",UI::optional); 
     134                                UI::get(yrv,set,"urv",UI::optional); 
     135                        } 
     136                        //! access function 
     137                        const RV& _urv() {return urv;} 
     138                        //! access function 
     139                        const RV& _yrv() {return yrv;} 
     140                        //! access function 
     141                        const RV& _drv() {return drv;} 
     142        }; 
     143                         
    115144} // namespace 
  • library/bdm/estim/kalman.h

    r583 r586  
    7878                        validate(); 
    7979                }                
     80                //! access function 
     81                int _dimx(){return dimx;} 
     82                //! access function 
     83                int _dimy(){return dimy;} 
     84                //! access function 
     85                int _dimu(){return dimu;} 
     86                //! 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;} 
    8098}; 
    8199 
     
    135153                void bayes (const vec &dt); 
    136154}; 
    137  
     155UIREGISTER(KalmanFull); 
    138156 
    139157 
     
    182200                void bayes (const vec &dt); 
    183201                 
    184                 void from_settings(const Setting &set){ 
     202                void from_setting(const Setting &set){ 
    185203                        Kalman<chmat>::from_setting(set); 
    186204                        initialize(); 
    187205                } 
    188206}; 
     207UIREGISTER(KalmanCh); 
    189208 
    190209/*! 
     
    219238                } 
    220239}; 
     240UIREGISTER(EKFfull); 
     241 
    221242 
    222243/*! 
     
    330351SHAREDPTR (MultiModel); 
    331352 
     353//! conversion of outer ARX model (mlnorm) to state space model  
     354/*! 
     355The model is constructed as: 
     356\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] 
     357For example, for: 
     358\f[ y_t = a y_{t-1} + b u_{t-1}\f] 
     359the state \f$ x_t = [y_{t-1}, u_{t-1}] \f$ 
     360*/ 
     361template<class sq_T> 
     362shared_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())); 
     371                        //We can do only 1d now... :( 
     372                        bdm_assert_debug(yrv_uni._dsize()==urv_uni._dsize()==1, "Only for SISO so far..." ); 
     373                                         
     374                        RV xrv; //empty 
     375                        RV Crv; //empty 
     376                        int td=ml._rvc().mintd(); 
     377                        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()); 
     390                        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); 
     396                        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} 
     405 
    332406/////////// INSTANTIATION 
    333407 
  • library/bdm/itpp_ext.cpp

    r584 r586  
    415415} 
    416416 
    417 } 
     417ivec unique_complement (const ivec &in, const ivec &base) 
     418{ 
     419        // almost a copy of unique 
     420        ivec uniq (0); 
     421        int j = 0; 
     422        bool found = false; 
     423        for (int i = 0;i < in.length(); i++) { 
     424                found = false; 
     425                j = 0; 
     426                while ( (!found) && (j < uniq.length())) { 
     427                        if (in (i) == uniq (j)) found = true; 
     428                        j++; 
     429                } 
     430                j=0; 
     431                while ( (!found) && (j < base.length())) { 
     432                        if (in (i) == uniq (j)) found = true; 
     433                        j++; 
     434                } 
     435                if (!found) uniq = concat (uniq, in (i)); 
     436        } 
     437        return uniq; 
     438} 
     439 
     440} 
  • library/bdm/itpp_ext.h

    r584 r586  
    115115//! function returns unique entries in input vector \c in 
    116116ivec unique(const ivec &in); 
     117//! function returns unique entries of vector \c in that are not present in vector \c base 
     118ivec unique_complement(const ivec &in, const ivec &base); 
    117119} 
    118120 
  • library/tests/CMakeLists.txt

    r583 r586  
    3939 
    4040# using UnitTest++ 
    41 add_executable(testsuite datalink_test.cpp egiw_test.cpp emix_test.cpp epdf_test.cpp logger_test.cpp merger_test.cpp  
     41add_executable(testsuite datalink_test.cpp egiw_test.cpp emix_test.cpp epdf_test.cpp logger_test.cpp LQG_test.cpp merger_test.cpp  
    4242        mpdf_test.cpp randun_test.cpp rectangular_support_test.cpp rv_test.cpp shared_ptr_test.cpp square_mat_test.cpp testsuite.cpp user_info_test.cpp) 
    4343target_link_libraries(testsuite testutil unittest) 
  • library/tests/rv_test.cpp

    r584 r586  
    142142        join.add(tmp); 
    143143         
    144         CHECK_EQUAL(unique(join._ids()), vec_2(a.id(0), b.id(0))); 
     144        CHECK_EQUAL(unique(join._ids()), vec_2(a.id(0), b.id(0))); // find only ids of a and b 
     145        CHECK_EQUAL(unique_complement(join._ids(), vec_1(a.id(0))), vec_1(b.id(0))); // complemnet of a in previous is b 
    145146}