log_value<dcomplex> TransposeInverseMatrix(const Array2 < complex <doublevar> > & a, Array2 < complex <doublevar> > & a1, const int n) { Array2 <complex <doublevar> > temp(n,n); Array1 <int> indx(n); doublevar d; // a(i,j) first index i is row index (convention) // elements of column vectors are stored contiguous in memory in C style arrays // a(i) refers to a column vector // calculate the inverse of the transposed matrix because this // allows to pass a column vector to lubksb() instead of a row // put the transposed matrix in temp //cout << "temp " << endl; for(int i=0;i<n;++i) { for(int j=0;j<n;++j) { temp(i,j)=a(i,j); a1(i,j)=complex <doublevar> (0.0,0.0); } a1(i,i)=complex <doublevar> (1.0,0.0); } //cout << "ludcmp" << endl; //if the matrix is singular, the determinant is zero. if(ludcmp(temp,n,indx,d)==0) { #ifdef SUPERDEBUG cout << "log_value<dcomplex>TransposeInverseMatrix:zero determinant " << endl; #endif return dcomplex(0.0,0.0); } //cout << "lubksb" << endl; for(int j=0;j<n;++j) { // get column vector Array1 <complex <doublevar> > yy;//(a1(j)); yy.refer(a1(j)); lubksb(temp,n,indx,yy); } //complex <doublevar> det(d,0); log_value<dcomplex> det=dcomplex(d,0); for(int j=0;j<n;++j) { det *= temp(j,j); } return det; }
// Invert matrix a, but do not change a // Inverse in a1 void InvertMatrix(const Array2 <doublevar> & a, Array2 <doublevar> & a1, const int n) { Array2 <doublevar>& temp(tmp2); temp.Resize(n,n); Array1 <int>& indx(itmp1); indx.Resize(n); doublevar d; // a(i,j) first index i is row index (convention) // elements of column vectors are stored contiguous in memory in C style arrays // a(i) refers to a column vector // calculate the inverse of the transposed matrix because this // allows to pass a column vector to lubksb() instead of a row // put the transposed matrix in temp for(int i=0;i<n;++i) { for(int j=0;j<n;++j) { temp(i,j)=a(j,i); a1(i,j)=0.0; } a1(i,i)=1.0; } if(!ludcmp(temp,n,indx,d)) error("singular matrix in inversion"); for(int j=0;j<n;++j) { // get column vector Array1 <doublevar> yy;//(a1(j)); yy.refer(a1(j)); lubksb(temp,n,indx,yy); } }
// Calculate the transpose inverse of matrix a // and return the determinant log_real_value TransposeInverseMatrix(const Array2 <doublevar> & a, Array2 <doublevar> & a1, const int n) { Array2 <doublevar> &temp(tmp2); temp.Resize(n,n); Array1 <int>& indx(itmp1); indx.Resize(n); doublevar d=1; log_real_value logdet; logdet.logval=0; logdet.sign=1; //for(int i=0; i< n; i++) { // cout << "matrix "; // for(int j=0; j< n; j++) cout << a(i,j) << " "; // cout << endl; //} #ifdef USE_LAPACK //LAPACK routines don't handle n==1 case?? if(n==1) { a1(0,0)=1.0/a(0,0); logdet.logval=log(fabs(a(0,0))); logdet.sign=a(0,0)<0?-1:1; return logdet; } else { for(int i=0; i < n;++i) { for(int j=0; j< n; ++j) { temp(j,i)=a(i,j); a1(i,j)=0.0; } a1(i,i)=1.0; } if(dgetrf(n, n, temp.v, n, indx.v)> 0) { return 0.0; } for(int j=0; j< n; ++j) { dgetrs('N',n,1,temp.v,n,indx.v,a1.v+j*n,n); } } for(int i=0; i< n; i++) { if(indx(i)!=i+1) logdet.sign*=-1; logdet.logval+=log(fabs(temp(i,i))); if(temp(i,i) <0) logdet.sign*=-1; } //cout << " det " << det << " logval " << logdet.val() << endl; //return det; return logdet; //#endif #else // a(i,j) first index i is row index (convention) // elements of column vectors are stored contiguous in memory in C style arrays // a(i) refers to a column vector // calculate the inverse of the transposed matrix because this // allows to pass a column vector to lubksb() instead of a row // put the transposed matrix in temp //cout << "temp " << endl; for(int i=0;i<n;++i) { for(int j=0;j<n;++j) { temp(i,j)=a(i,j); a1(i,j)=0.0; } a1(i,i)=1.0; } //cout << "ludcmp" << endl; //if the matrix is singular, the determinant is zero. d=1; if(ludcmp(temp,n,indx,d)==0) return 0; //cout << "lubksb" << endl; for(int j=0;j<n;++j) { // get column vector Array1 <doublevar> yy;//(a1(j)); yy.refer(a1(j)); lubksb(temp,n,indx,yy); } //for(int j=0;j<n;++j) { // d *= temp(j,j); //} logdet.logval=0; logdet.sign=1; for(int i=0; i< n; i++) { if(indx(i)!=i) logdet.sign*=-1; logdet.logval+=log(fabs(temp(i,i))); if(temp(i,i) <0) logdet.sign*=-1; } //cout << " det " << d << " logval " << logdet.val() << endl; return logdet; #endif }