root/library/tests/testsuite/LQG_test.cpp @ 1167

Revision 1157, 7.7 kB (checked in by vahalam, 14 years ago)

quadratic_test temporaty disabled
created new lqguniversal_test

  • Property svn:eol-style set to native
Line 
1#define BDMLIB
2#include "../mat_checks.h"
3#include "design/lq_ctrl.h"
4
5using namespace bdm;
6
7TEST ( LQG_test ) {
8    LQG reg;
9    shared_ptr<StateSpace<chmat> > stsp = new StateSpace<chmat>;
10    // 2 x 1 x 1
11    stsp-> set_parameters ( eye ( 2 ), ones ( 2, 1 ), ones ( 1, 2 ), ones ( 1, 1 ), /* Q,R */ eye ( 2 ), eye ( 1 ) );
12    reg.set_system ( stsp ); // A, B, C
13    reg.set_control_parameters ( eye ( 1 ), eye ( 1 ),  vec_1 ( 1.0 ), 6 ); //Qy, Qu, horizon
14    reg.validate();
15
16    reg.redesign();
17    double reg_apply = reg.ctrlaction ( "0.5, 1.1", "0.0" ) ( 0 ); /*convert vec to double*/
18    CHECK_CLOSE ( reg_apply, -0.248528137234392, 0.0001 );
19}
20
21TEST ( to_state_test ) {
22    mlnorm<fsqmat> ml;
23    mat A = "1.1, 2.3";
24    ml.set_parameters ( A, vec_1 ( 1.3 ), eye ( 1 ) );
25    RV yr = RV ( "y", 1 );
26    RV ur = RV ( "u", 1 );
27    ml.set_rv ( yr );
28    yr.t_plus ( -1 );
29    ml.set_rvc ( concat ( yr, ur ) );
30
31    shared_ptr<StateCanonical > Stsp = new StateCanonical;
32    Stsp->connect_mlnorm ( ml );
33
34    /* results from
35    [A,B,C,D]=tf2ss([2.3 0],[1 -1.1])
36    */
37    CHECK_CLOSE_EX ( Stsp->_A().get_row ( 0 ), vec ( "1.1" ), 0.0001 );
38    CHECK_CLOSE_EX ( Stsp->_C().get_row ( 0 ), vec ( "2.53" ), 0.0001 );
39    CHECK_CLOSE_EX ( Stsp->_D().get_row ( 0 ), vec ( "2.30" ), 0.0001 );
40}
41
42TEST ( to_state_arx_test ) {
43    mlnorm<chmat> ml;
44    mat A = "1.1, 2.3, 3.4";
45    ml.set_parameters ( A, vec_1 ( 1.3 ), eye ( 1 ) );
46    RV yr = RV ( "y", 1 );
47    RV ur = RV ( "u", 1 );
48    ml.set_rv ( yr );
49    ml.set_rvc ( concat ( yr.copy_t ( -1 ), concat ( ur, ur.copy_t ( -1 ) ) ) );
50
51    shared_ptr<StateFromARX> Stsp = new StateFromARX;
52    RV xrv;
53    RV urv;
54    Stsp->connect_mlnorm ( ml, xrv, urv );
55
56    /* results from
57    [A,B,C,D]=tf2ss([2.3 0],[1 -1.1])
58    */
59    CHECK_CLOSE_EX ( Stsp->_A().get_row ( 0 ), vec ( "1.1, 3.4, 1.3" ), 0.0001 );
60    CHECK_CLOSE_EX ( Stsp->_B().get_row ( 0 ), vec ( "2.3" ), 0.0001 );
61    CHECK_CLOSE_EX ( Stsp->_C().get_row ( 0 ), vec ( "1, 0, 0" ), 0.0001 );
62}
63
64TEST ( arx_LQG_test ) {
65    mlnorm<chmat> ml;
66    mat A = "1.81, -.81, .00468, .00438";
67    ml.set_parameters ( A, vec_1 ( 0.0 ), 0.00001*eye ( 1 ) );
68    RV yr = RV ( "y", 1 );
69    RV ur = RV ( "u", 1 );
70    RV rgr = yr.copy_t ( -1 );
71    rgr.add ( yr.copy_t ( -2 ) );
72    rgr.add ( yr.copy_t ( -2 ) );
73    rgr.add ( ur.copy_t ( -1 ) );
74    rgr.add ( ur );
75
76    ml.set_rv ( yr );
77    ml.set_rvc ( rgr );
78    ml.validate();
79
80    shared_ptr<StateFromARX> Stsp = new StateFromARX;
81    RV xrv;
82    RV urv;
83    Stsp->connect_mlnorm ( ml, xrv, urv );
84
85    LQG L;
86    L.set_system ( Stsp );
87    L.set_control_parameters ( eye ( 1 ), sqrt ( 1.0 / 1000 ) *eye ( 1 ), vec_1 ( 0.0 ), 100 );
88    L.validate();
89
90    L.redesign();
91    cout << L.to_string() << endl;
92}
93
94TEST (quadratic_test){
95  /*quadraticfn qf;
96  qf.Q = chmat(2);
97  qf.Q._Ch() = mat("1 -1 0; 0 0 0; 0 0 0");
98  CHECK_CLOSE_EX(qf.eval(vec("1 2")), vec_1(1.0), 0.0000000000000001);
99 
100  LQG_universal lq;
101  lq.Losses = Array<quadraticfn>(1);
102  lq.Losses(0) = quadraticfn();
103  lq.Losses(0).Q._Ch() = mat("1 -1 0; 0 0 0; 0 0 0");
104  lq.Losses(0).rv = RV("{u up }");
105 
106  lq.Models = Array<linfnEx>(1);
107  lq.Models(0) = linfnEx(mat("1"),vec("1"));
108  lq.Models(0).rv = RV("{x }");
109 
110  lq.rv = RV("u",1);
111 
112  lq.redesign();
113  CHECK_CLOSE_EX(lq.ctrlaction(vec("1,0")), vec("1.24, -5.6"), 0.0000001);*/
114}
115
116TEST (lqguniversal_test){
117  //test of universal LQG controller
118  LQG_universal lq;
119  lq.rv = RV("u", 2, 0); 
120  lq.set_rvc(RV("x", 2, 0));
121  lq.horizon = 10;
122
123  /*
124                model:      x = Ax + Bu                 time: 0..horizon
125                loss:       l = x'Q'Qx + u'R'Ru         time: 0..horizon-1
126                final loss: l = x'S'Sx                  time: horizon
127
128                dim:    x: 2
129                                u: 2
130
131                A = [   2       -1       ]
132                        [       0       0.5      ]
133               
134                B = [   1               -0.1    ]       
135                        [       -0.2    2               ]
136
137                Q = [   5       0       ]
138                        [       0       1       ]
139
140                R = [   0.01    0        ]
141                        [       0               0.1      ]
142
143                S = Q
144  */
145
146  //mat mA("2 -1;0 0.5");
147  //mat mB("1 -0.1;-0.2 2");
148  //mat mQ("5 0;0 1");
149  //mat mR("0.01 0;0 0.1");
150  //mat mS = mQ;
151
152  ////starting configuration
153  //vec x0("6 3");
154
155  //uniform random generator
156  Uniform_RNG urng;
157  double maxmult = 10;
158  vec tmpdiag;
159 
160  mat mA;   
161        urng.sample_matrix(2, 2, mA);
162        mA *= maxmult;
163  mat mB; 
164        urng.sample_matrix(2, 2, mB);
165        mB *= maxmult;
166  mat mQ(2, 2); 
167        urng.sample_vector(2, tmpdiag);
168        tmpdiag *= maxmult;
169        mQ.zeros();
170        mQ.set(0, 0, tmpdiag.get(0));
171        mQ.set(1, 1, tmpdiag.get(1));
172  mat mR(2, 2); 
173        urng.sample_vector(2, tmpdiag);
174        tmpdiag *= maxmult;
175        mR.zeros();
176        mR.set(0, 0, tmpdiag.get(0));
177        mR.set(1, 1, tmpdiag.get(1));
178  mat mS(2, 2); 
179        urng.sample_vector(2, tmpdiag);
180        tmpdiag *= maxmult;
181        mS.zeros();
182        mS.set(0, 0, tmpdiag.get(0));
183        mS.set(1, 1, tmpdiag.get(1));
184
185  //starting configuration
186  vec x0;
187        urng.sample_vector(2, x0);
188        x0 *= maxmult;
189 
190        /*cout << "configuration:" << endl
191                << "mA:" << endl << mA << endl
192                << "mB:" << endl << mB << endl
193                << "mQ:" << endl << mQ << endl
194                << "mR:" << endl << mR << endl
195                << "mS:" << endl << mS << endl
196                << "x0:" << endl << x0 << endl;*/
197
198  //model
199  Array<linfnEx> model(2);
200  //model Ax part
201  model(0).A = mA;
202  model(0).B = vec("0 0");
203  model(0).rv = RV("x", 2, 0);
204  model(0).rv_ret = RV("x", 2, 1);
205  //model Bu part
206  model(1).A = mB;
207  model(1).B = vec("0 0");
208  model(1).rv = RV("u", 2, 0);
209  model(1).rv_ret = RV("x", 2, 1);     
210  //setup
211  lq.Models = model;
212
213  //loss
214  Array<quadraticfn> loss(2);
215  //loss x'Qx part
216  loss(0).Q.setCh(mQ);
217  loss(0).rv = RV("x", 2, 0);
218  //loss u'Ru part
219  loss(1).Q.setCh(mR);
220  loss(1).rv = RV("u", 2, 0);
221  //setup
222  lq.Losses = loss;
223
224  //finalloss setup
225  lq.finalLoss.Q.setCh(mS);
226  lq.finalLoss.rv = RV("x", 2, 1);
227 
228  //default L
229  //cout << "default L matrix:" << endl << lq.getL() << endl;
230
231  //produce last control matrix L
232  lq.redesign();
233 
234  //verification via Riccati LQG version
235  mat mK = mS;
236  mat mL = - inv(mR + mB.transpose() * mK * mB) * mB.transpose() * mK * mA;
237
238  //cout << "L matrix LQG_universal:" << endl << lq.getL() << endl <<
239          //"L matrix LQG Riccati:" << endl << mL << endl;
240
241  //checking L matrix (universal vs Riccati), tolerance is high, but L is not main criterion
242  //more important is reached loss compared in the next part
243  double tolerr = 1;//0.01; //0.01 OK x 0.001 NO OK
244
245  //check last time L matrix
246  CHECK_CLOSE_EX(lq.getL().get_cols(0,1), mL, tolerr);
247 
248  mat oldK;
249  int i;
250
251  //produce next control matrix L
252  for(i = 0; i < lq.horizon - 1; i++) {
253          lq.redesign();
254          oldK = mK;
255          mK = mA.transpose() * (oldK - oldK * mB * inv(mR + mB.transpose() * oldK * mB) * mB.transpose() * oldK) * mA + mQ;
256          mL = - inv(mR + mB.transpose() * mK * mB) * mB.transpose() * mK * mA;
257
258          //cout << "L matrix LQG_universal:" << endl << lq.getL() << endl <<
259                  //"L matrix LQG Riccati:" << endl << mL << endl;
260
261          //check other times L matrix
262          CHECK_CLOSE_EX(lq.getL().get_cols(0,1), mL, tolerr);
263  }
264
265 //check losses of LQG control - compare LQG_universal and Riccati version, no noise
266   
267  //loss of LQG_universal
268  /*double*/vec loss_uni("0");
269
270  //setup
271  vec x = x0;
272  vec xold = x;
273  vec u;
274  //vec tmploss;
275
276  //iteration
277  for(i = 0; i < lq.horizon - 1; i++){
278        u = lq.getL().get_cols(0,1) * xold;
279        x = mA * xold + mB * u;
280        /*tmploss*/loss_uni = x.transpose() * mQ * x + u.transpose() * mR * u;
281        //loss_uni += tmploss.get(0);
282        xold = x;
283  }
284  /*tmploss*/ loss_uni = x.transpose() * mS * x;
285  //loss_uni += tmploss.get(0);
286
287  //loss of LQG Riccati version
288  /*double*/ vec loss_rct("0");
289
290  //setup
291  x = x0;
292  xold = x;
293
294  //iteration
295  for(i = 0; i < lq.horizon - 1; i++){
296        u = mL * xold;
297        x = mA * xold + mB * u;
298        /*tmploss*/loss_rct = x.transpose() * mQ * x + u.transpose() * mR * u;
299        //loss_rct += tmploss.get(0);
300        xold = x;
301  }
302  /*tmploss*/loss_rct = x.transpose() * mS * x;
303  //loss_rct += tmploss.get(0);
304
305  //cout << "Loss LQG_universal: " << loss_uni << " vs Loss LQG Riccati: " << loss_rct << endl;
306  CHECK_CLOSE_EX(loss_uni, loss_rct, 0.0001);
307}
Note: See TracBrowser for help on using the browser.