|  | 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 | 
                          |  | 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 |  | 
                          |  | 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 |  | 
            
                      
                        | 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 |  |