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