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