- Timestamp:
- 10/20/10 18:41:40 (14 years ago)
- Files:
-
- 1 modified
Legend:
- Unmodified
- Added
- Removed
-
library/bdm/design/lq_ctrl.h
r1218 r1221 7 7 //! left matrix division with upper triangular matrix using Gauss elimination 8 8 //! fast variant of inv(A) * B where A is UT matrix, returns result in C and true if no error 9 bool ldutg(mat &utA, mat &mB, mat &mC){ 10 int utsize = utA.rows(); 11 12 if(utsize != utA.cols()) return false; //utA not square 13 if(utsize != mB.rows()) return false; //incorrect mB size 14 15 int mbcol = mB.cols(); 16 17 mC.set_size(utsize, mbcol); 18 9 inline bool ldutg(mat &_utA, mat &_mB, mat &_mC){ 10 int utsize = _utA.rows(); 11 12 if(utsize != _utA.cols()) return false; //utA not square 13 if(utsize != _mB.rows()) return false; //incorrect mB size 14 15 int mbcol = _mB.cols(); 19 16 int totsize = utsize + mbcol; 20 17 int sqs = utsize*utsize; 21 int i, j, k; 22 23 double pvt; 24 18 int i, j, k; 19 20 double pvt; 25 21 double tmp[utsize*totsize]; 22 double *utA = _utA._data(); 23 double *mB = _mB._data(); 24 25 _mC.set_size(utsize, mbcol); 26 27 double *mC = _mC._data(); 26 28 27 29 //fill tmp array 28 30 for(i = 0; i < sqs; i++) 29 tmp[i] = utA ._data()[i];31 tmp[i] = utA[i]; 30 32 for(i = sqs; i < utsize*totsize; i++) 31 tmp[i] = mB ._data()[i-sqs];33 tmp[i] = mB[i-sqs]; 32 34 33 35 for(i = utsize-1; i >= 0; i--){ //Gauss elimination 34 36 pvt = tmp[i + utsize*i]; //get pivot 35 for(j = i; j < totsize; j++) tmp[i + utsize*j] /= pvt; //normalize row37 for(j = utsize; j < totsize; j++) tmp[i + utsize*j] /= pvt; //normalize row - only part on the right 36 38 for(j = 0;j < i; j++){ //subtract normalized row from above ones 37 39 pvt = tmp[j + utsize*i]; //get pivot 38 for(k = 0; k < totsize; k++)40 for(k = utsize; k < totsize; k++) //goes from utsize - do not need make matrix on the left = I 39 41 tmp[j + utsize*k] -= pvt * tmp[i + utsize*k]; //create zero col above 40 42 } … … 43 45 44 46 for(i = 0; i < utsize*mbcol; i++) 45 mC ._data()[i] = tmp[i+sqs];47 mC[i] = tmp[i+sqs]; 46 48 47 49 return true; … … 69 71 //! model of evolutin 70 72 Array<linfnEx> Models; 71 // RV model_rv_ret;72 73 73 74 //! control law rv is public member in Controller class … … 106 107 curtime--; 107 108 generateLmat(curtime); 108 } 109 //cout << "time " << curtime << endl; 110 //report time 0 reached - LQG designing complete 111 //if(curtime == 0) cout << "time 0 reached" << endl; 109 } 112 110 } 113 111 //! returns designed control action … … 170 168 if(finding1(j) <= (-1) ) return; //rv element is not part of admissible rvs => error 171 169 } 172 } 173 174 //NOT!!! (2) test Models array rv_ret - each array element's rv_ret must be unique (except const 1) 175 //RV unique_rv_ret; 176 //unique_rv_ret = Models(0).rv_ret; 177 178 //for(i = 1; i < Models.length(); i++){ 179 // finding1 = Models(i).rv_ret.findself(unique_rv_ret); 180 181 // for(j = 0; j < finding1.size(); j++){ 182 // if(Models(i).rv_ret.name(j) == "1") continue; // except const 1 183 184 // bdm_assert((finding1(j) == (-1) ), "VALIDATION FAILED! Models functions result RV (rv_ret) must be unique."); 185 // if(finding1(j) != (-1) ) return; //rv_ret element not unique 186 // } 187 188 // unique_rv_ret.add(Models(i).rv_ret); 189 //} 170 } 190 171 191 172 // (3) test Losses array - acceptable rv is only part/composition of LQG_universal::rv, LQG_universal::rvc, Models rv_ret and const 1 … … 215 196 216 197 private: 217 RV trs_crv; 218 219 //! compute complete RV from all of RVs used in Losses array 220 /*RV getCompleteRV() { 221 RV cRv; //complete RV 222 223 //cRv has form [rv, "other", 1] 224 cRv = rv; //add rv 225 226 //add "other" 227 for(int i = 0; i < Losses.size(); i++) 228 cRv.add(Losses(i).rv); 229 230 cRv.add(rvOne); //add 1 231 232 return cRv; 233 }*/ 198 RV trs_crv; 234 199 235 200 mat getMatRow (quadraticfn sourceQfn){ //returns row of matrixes crated from quadratic function … … 241 206 //set data in tmpMatRow - other times then current replace using model 242 207 RV tmpQrv = sourceQfn.rv; 243 //cout << "Qrv " << tmpQrv << endl << "total crv " << trs_crv << endl; 208 244 209 ivec j_vec(1); 245 210 vec copycol; … … 247 212 for(int j = 0; j < tmpQrv.length(); j++){ 248 213 j_vec(0) = j; 249 //cout << "matrow\n" << tmpMatRow << endl; 250 251 if( /*(tmpQrv.time(j) == 0) &&*/ (sum(tmpQrv(j_vec).findself(trs_crv)) > (-1)) ) {//sum is only formal, summed vector is in fact scalar 214 215 if( (sum(tmpQrv(j_vec).findself(trs_crv)) > (-1)) ) {//sum is only formal, summed vector is in fact scalar 252 216 //jth element of tmpQrv is also element of trs_crv with a proper time 253 //cout << "copy" << endl; 217 254 218 ivec copytarget = (tmpQrv(j_vec)).dataind(trs_crv); //get target column position in tmpMatRow 255 219 ivec copysource = (tmpQrv(j_vec)).dataind(tmpQrv); //get source column position in Losses(i).Q … … 261 225 } 262 226 } 263 else { 264 //cout << "USING MODEL on " << tmpQrv(j,j) << endl; 265 //cout << "model" << endl; 266 //jth tmpQrv element is not in trs_crv -> using Model to teplace it 267 // = (tmpQrv(j_vec)).findself(tmpQrv); //get source column position in Losses(i).Q 268 269 //int selectedModel = -1; 270 271 //int k; 272 ////find first usable replacement in Model 273 //for(k = 0; k < Models.size(); k++){ 274 // if( sum((tmpQrv(j_vec)).findself(Models(k).rv_ret)) > (-1) ){ 275 // //tTODO is tmpQrv(j) in kth Models RV 276 // //if( (Models(k)).rv_ret.findself_ids(trs_crv) ){//??????????????????? 277 // // is kth Models rv_ret subset of trs_crv 278 279 // selectedModel = k; 280 // break; 281 282 // //} 283 // } 284 //} 227 else { 228 //!model is model_rv_ret = sum(Array<linfn>) = sum( A1*rv + B1 + ... + An*rv + Bn) 285 229 286 //!model is model_rv_ret = sum(Array<linfn>) = sum( A1*rv + B1 + ... + An*rv + Bn)287 288 //if(selectedModel == -1) {cout << "NO MODEL" << endl;return mat("0");}//ERROR - inconsistent model data;289 //!!tTODO!!if(NOT((tmpQrv(j_vec)).findself(model_rv_ret))) {cout << "NO MODEL" << endl;return mat("0");}//ERROR - inconsistent model data;290 230 //use kth Model to convert tmpQrv memeber to trs_crv memeber 291 231 … … 319 259 ivec copytarget = (Models(k)).rv.dataind(trs_crv); //get target column position in tmpMatRow 320 260 321 //copy transsubmat into tmpMatRow with adding to current one 322 // tmpMatRow(new) = tmpMatRow(old) + transsubmat /all in proper indices 261 //copy transsubmat into tmpMatRow with adding to current one 323 262 int l; 324 263 for(l = 0; l < copytarget.size(); l++){ … … 352 291 int i; 353 292 //used fake quadratic function from tolC matrix 354 quadraticfn fakeQfn; 355 356 //RV pretrs_crv = getCompleteRV(); // crv before transformation based on Losses array 293 quadraticfn fakeQfn; 357 294 358 295 //set proper size of pre_qr matrix … … 370 307 fakeM1.t_plus(1); //RV in time t+1 => necessary use of Model to get RV in time t 371 308 fakeM1.set_time((RV("1", 1, 1).findself(fakeM1))(0) , 0); 372 //cout << fakeM1 << endl; 309 373 310 fakeQfn.rv = fakeM1; 374 311 375 312 rows += fakeQfn.Q.rows(); 376 313 } 377 //cout << "buildpreqr trscrv: " << trs_crv << " of size " << trs_crv.countsize() << endl; 314 378 315 pre_qr.set_size(rows, trs_crv.countsize()); //(rows, cols) 379 316 pre_qr.zeros(); … … 387 324 //compute row matrix and insert it on proper place in pre_qr 388 325 tmpMatRow = getMatRow(Losses(i)); 389 //cout << "tmpMatRow no " << i << endl << tmpMatRow << endl; 326 390 327 //copy tmpMatRow in pre_qr 391 392 /*cout << "submatrix ( " << rowIndex << ", " <<393 (rowIndex + rows - 1) << ", 0, " << (trs_crv.countsize() - 1) << ")" << endl;394 cout << "seting with submatrix of rows " << tmpMatRow.rows() << " and cols " << tmpMatRow.cols() <<395 "and data " << endl << tmpMatRow << endl;*/396 397 328 pre_qr.set_submatrix(rowIndex, (rowIndex + rows - 1), 0, (trs_crv.countsize() - 1), tmpMatRow); //(int r1, int r2, int c1, int c2, const Mat< Num_T > &m) 398 329 rowIndex += rows; … … 406 337 //based on tolC but time must be shifted by one - all implemented in getMatRow method 407 338 408 //get matrix row via getMatRow method 409 //cout << "XXXXXXXXXXXXXXX" << endl; 339 //get matrix row via getMatRow method 410 340 tmpMatRow = getMatRow(fakeQfn); 411 //cout << tmpMatRow << endl; 412 /*cout << "submatrix ( " << rowIndex << ", " << 413 (rowIndex + fakeQfn.Q.rows() - 1) << ", 0, " << (trs_crv.countsize() - 1) << ")" << endl; 414 cout << "seting with submatrix of rows " << tmpMatRow.rows() << " and cols " << tmpMatRow.cols() << 415 "and data " << endl << tmpMatRow << endl;*/ 341 416 342 pre_qr.set_submatrix(rowIndex, (rowIndex + fakeQfn.Q.rows() - 1), 0, (trs_crv.countsize() - 1), tmpMatRow); //(int r1, int r2, int c1, int c2, const Mat< Num_T > &m) 417 //cout << "NEXT 3" << endl; 418 } 419 //cout << "last tmpMatRow " << endl << tmpMatRow << endl; 343 } 420 344 } 421 345 … … 488 412 mat tmpQ; 489 413 qr(pre_qr, tmpQ, post_qr); 490 //cout << "preQR " << pre_qr << endl << "postQR" << post_qr << endl; 414 491 415 mat qrA = -get_qr_submatrix(0); 492 416 mat qrB = get_qr_submatrix(1); 493 417 mat qrC = get_qr_submatrix(2); 494 //cout << "A " << qrA << "\n B " << qrB << "\n C " << qrC << endl; 495 496 //mat L1 = - inv(qrA)*qrB; 497 //mat L2; 418 419 //mat L = inv(qrA)*qrB; 498 420 bool invmult = ldutg(qrA, qrB, L); 499 421 bdm_assert(invmult, "Matrix inversion error!"); 500 501 /*if(L1 != (-L2)){ 502 cout << "qrA" << qrA << endl; 503 int l; 504 for(l = 0; l < qrA.rows()*qrA.cols();l++) cout << qrA._data()[l] << " "; 505 cout << endl << "qrB" << qrB << endl; 506 for(l = 0; l < qrB.rows()*qrB.cols();l++) cout << qrB._data()[l] << " "; 507 cout << endl << L1 << endl << (-L2) << endl; 508 } 509 510 bdm_assert(L1 == (-L2), "Matrix compare error!"); 511 L = L1;*/ 512 422 513 423 // ldutg is faster matrix inv&mult (like Matlab's \ operator) function than inv 514 424 // it uses Gauss elimination … … 521 431 }; 522 432 523 class LQG_recedinghorizon : public LQG_universal {524 protected:525 //!total_curtime is curtime for total_horizon526 int total_curtime;527 public:528 //! LQG_universal::horizon means shorter receding horizon for designing control strategy529 //! total_horizon is longer total horizon530 int total_horizon;531 532 //!constructor533 LQG_recedinghorizon() : LQG_universal() {534 total_horizon = 0;535 total_curtime = 0;536 }537 538 virtual void redesign() {539 if (total_curtime < total_horizon){540 for(int i = 0; i < horizon - 1; i++) LQG_universal::redesign();541 total_curtime++;542 }543 }544 545 virtual vec ctrlaction ( const vec &cond ) const {546 //return L * concat(cond, 1.0);547 return empty_vec;548 }549 550 //! register this controller with given datasource under name "name"551 virtual void log_register ( logger &L, const string &prefix ) { }552 //! write requested values into the logger553 virtual void log_write ( ) const { }554 };555 556 433 } // namespace