Changeset 1218 for library

Show
Ignore:
Timestamp:
10/19/10 22:38:37 (14 years ago)
Author:
vahalam
Message:

inv() function replaced by own ldutg() one based on Gauss elimination

Files:
1 modified

Legend:

Unmodified
Added
Removed
  • library/bdm/design/lq_ctrl.h

    r1210 r1218  
    44 
    55const bool STRICT_RV = true; //empty RV NOT allowed 
     6 
     7//! left matrix division with upper triangular matrix using Gauss elimination 
     8//! fast variant of inv(A) * B where A is UT matrix, returns result in C and true if no error 
     9bool 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         
     19        int totsize = utsize + mbcol; 
     20        int sqs = utsize*utsize; 
     21        int i, j, k; 
     22         
     23        double pvt; 
     24         
     25        double tmp[utsize*totsize]; 
     26         
     27        //fill tmp array 
     28        for(i = 0; i < sqs; i++)  
     29                tmp[i] = utA._data()[i]; 
     30        for(i = sqs; i < utsize*totsize; i++)                            
     31                tmp[i] = mB._data()[i-sqs];                  
     32                    
     33        for(i = utsize-1; i >= 0; i--){  //Gauss elimination 
     34                pvt = tmp[i + utsize*i];    //get pivot  
     35                for(j = i; j < totsize; j++) tmp[i + utsize*j] /= pvt;  //normalize row                                     
     36                for(j = 0;j < i; j++){ //subtract normalized row from above ones 
     37                        pvt = tmp[j + utsize*i]; //get pivot 
     38                        for(k = 0; k < totsize; k++)     
     39                                tmp[j + utsize*k] -= pvt * tmp[i + utsize*k]; //create zero col above                                              
     40                } 
     41                                                                                   
     42        }     
     43                     
     44        for(i = 0; i < utsize*mbcol; i++) 
     45                mC._data()[i] = tmp[i+sqs];              
     46         
     47        return true; 
     48} 
     49 
    650 
    751//! extended class representing function \f$f(x) = Ax+B\f$ 
     
    229273                                //for(k = 0; k < Models.size(); k++){                                                    
    230274                                //      if( sum((tmpQrv(j_vec)).findself(Models(k).rv_ret)) > (-1) ){ 
    231                                 //      //TODO is tmpQrv(j) in kth Models RV 
     275                                //      //tTODO is tmpQrv(j) in kth Models RV 
    232276                                //              //if( (Models(k)).rv_ret.findself_ids(trs_crv) ){//??????????????????? 
    233277                                //              // is kth Models rv_ret subset of trs_crv 
     
    243287                                 
    244288                                //if(selectedModel == -1) {cout << "NO MODEL" << endl;return mat("0");}//ERROR - inconsistent model data;                                
    245                         //!!TODO!!if(NOT((tmpQrv(j_vec)).findself(model_rv_ret))) {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;                               
    246290                                //use kth Model to convert tmpQrv memeber to trs_crv memeber 
    247291 
     
    445489                qr(pre_qr, tmpQ, post_qr); 
    446490//cout << "preQR " << pre_qr << endl << "postQR" << post_qr << endl; 
    447                 mat qrA = get_qr_submatrix(0);           
     491                mat qrA = -get_qr_submatrix(0);          
    448492                mat qrB = get_qr_submatrix(1); 
    449493                mat qrC = get_qr_submatrix(2); 
    450494//cout << "A " << qrA << "\n B " << qrB << "\n C " << qrC << endl; 
    451495 
    452                 L = - inv(qrA)*qrB; ///////// INVERSE OF TRIANGLE MATRIX! better? 
     496                //mat L1 = - inv(qrA)*qrB;  
     497                //mat L2; 
     498                bool invmult = ldutg(qrA, qrB, L); 
     499                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                                 
     513                // ldutg is faster matrix inv&mult (like Matlab's \ operator) function than inv 
     514                // it uses Gauss elimination 
     515                // BUT based on NOT RECOMENDED direct data access method in mat class 
     516                // even faster implementation could be implemented using fix double arrays               
     517                 
    453518                tolC = qrC; 
    454519        }