void LU_Refactorize(PT_Basis pB) { char L = 'L'; /* lower triangular */ char D = 'U'; /* unit triangular matrix (diagonals are ones) */ ptrdiff_t info, incx=1, incp; /* Matrix_Print_row(pB->pLX); */ /* Matrix_Print_utril_row(pB->pUX); */ /* factorize using lapack */ dgetrf(&(Matrix_Rows(pB->pF)), &(Matrix_Rows(pB->pF)), pMAT(pB->pF), &((pB->pF)->rows_alloc), pB->p, &info); /* store upper triangular matrix (including the diagonal to Ut), i.e. copy Ut <- F */ /* lapack ignores remaining elements below diagonal when computing triangular solutions */ Matrix_Copy(pB->pF, pB->pUt, pB->w); /* transform upper part of F (i.e. Ut) to triangular row major matrix UX*/ /* UX <- F */ Matrix_Full2RowTriangular(pB->pF, pB->pUX, pB->r); /* invert lower triangular part */ dtrtri( &L, &D, &(Matrix_Rows(pB->pF)), pMAT(pB->pF), &((pB->pF)->rows_alloc), &info); /* set strictly upper triangular parts to zeros because L is a full matrix * and we need zeros to compute proper permutation inv(L)*P */ Matrix_Uzeros(pB->pF); /* transpose matrix because dlaswp operates rowwise and we need columnwise */ /* LX <- F' */ Matrix_Transpose(pB->pF, pB->pLX, pB->r); /* interchange columns according to pivots in pB->p and write to LX*/ incp = -1; /* go backwards */ dlaswp( &(Matrix_Rows(pB->pLX)), pMAT(pB->pLX), &((pB->pLX)->rows_alloc), &incx, &(Matrix_Rows(pB->pLX)) , pB->p, &incp); /* Matrix_Print_col(pB->pX); */ /* Matrix_Print_row(pB->pLX); */ /* Matrix_Print_col(pB->pUt); */ /* Matrix_Print_utril_row(pB->pUX); */ /* matrix F after solution is factored in [L\U], we want the original format for the next call to dgesv, thus create a copy F <- X */ Matrix_Copy(pB->pX, pB->pF, pB->w); }
/*! Inverts an n by n matrix. */ int invertMatrix(int n,double *A,double *INVA) { double *work; int *ipiv; int lwork = n; int info; if (A && INVA) { work = new double[n]; // should we optimize work size? ipiv = new int[n]; dcopy(n*n,A,1,INVA,1); dgetrf(n,n,INVA,n,ipiv,&info); dgetri(n,INVA,n,ipiv,work,lwork,&info); delete [] work; delete [] ipiv; } else { printf("One or both matricies in InvertMatrix are NULL\n"); info = -1; } return info; }
void EIS_reg(double *y, double *theta, double *w, mwSignedIndex S, double *beta) { mwSignedIndex i; char *chN = "N", *chT = "T"; double one = 1.0, zero = 0.0; double A[9], B[3], *X, *Y; mwSignedIndex K, N; mwSignedIndex IPIV[3], INFO; /* Variable size arrays */ X = malloc((3*S)*sizeof(double)); Y = malloc((S)*sizeof(double)); K = 3; N = 1; /* create X and Y */ for (i=0; i<S; i++) { X[i] = w[i]; X[S+i] = w[i]*theta[i]; X[2*S+i] = -0.5*theta[i]*X[S+i]; Y[i] = w[i]*y[i]; } dgemm(chT, chN, &K, &K, &S, &one, X, &S, X, &S, &zero, &A, &K); /* get X'*X*/ dgemm(chT, chN, &K, &N, &S, &one, X, &S, Y, &S, &zero, &B, &K); /* get X'*Y*/ dgetrf(&K, &K, &A, &K, &IPIV, &INFO); /* get LU factorisation of A*/ dgetrs(chN, &K, &N, &A, &K, &IPIV, &B, &K, &INFO); /* get solution B*/ beta[0] = B[1]; beta[1] = B[2]; /* Free allocated memory */ free(X); free(Y); }
void SqSylvMatrix::multInvLeft2(GeneralMatrix& a, GeneralMatrix& b, double& rcond1, double& rcondinf) const { if (rows != a.numRows() || rows != b.numRows()) { throw SYLV_MES_EXCEPTION("Wrong dimensions for multInvLeft2."); } // PLU factorization Vector inv(data); lapack_int * const ipiv = new lapack_int[rows]; lapack_int info; lapack_int rows2 = rows; dgetrf(&rows2, &rows2, inv.base(), &rows2, ipiv, &info); // solve a lapack_int acols = a.numCols(); double* abase = a.base(); dgetrs("N", &rows2, &acols, inv.base(), &rows2, ipiv, abase, &rows2, &info); // solve b lapack_int bcols = b.numCols(); double* bbase = b.base(); dgetrs("N", &rows2, &bcols, inv.base(), &rows2, ipiv, bbase, &rows2, &info); delete [] ipiv; // condition numbers double* const work = new double[4*rows]; lapack_int* const iwork = new lapack_int[rows]; double norm1 = getNorm1(); dgecon("1", &rows2, inv.base(), &rows2, &norm1, &rcond1, work, iwork, &info); double norminf = getNormInf(); dgecon("I", &rows2, inv.base(), &rows2, &norminf, &rcondinf, work, iwork, &info); delete [] iwork; delete [] work; }
void Load_HO_Surface(char *name) { register int i,j; int np,nface,ntot,info; FILE *infile; char buf[BUFSIZ],*p; double *Rpts, *Spts; if(Loaded_Surf_File) return; // allow for multiple calls // check for .hsf file first sprintf(buf,"%s.hsf",strtok(name,".")); if(!(infile = fopen(buf,"r"))) { fprintf(stderr,"unable to open file %s or %s\n" "Run homesh on the .fro file to generate " "high order surface file \n",name,buf); exit(1); } // read header fgets(buf,BUFSIZ,infile); p = strchr(buf,'='); sscanf(++p,"%d",&np); p = strchr(p,'='); sscanf(++p,"%d",&nface); Snp = np; Snface = nface; ntot = np*(np+1)/2; Rpts = dvector(0,ntot-1); Spts = dvector(0,ntot-1); // read in point distribution in standard region fgets(buf,BUFSIZ,infile); fscanf(infile,"# %lf",Rpts); for(i = 1; i < ntot; ++i) fscanf(infile,"%lf",Rpts+i); fgets(buf,BUFSIZ,infile); fscanf(infile,"# %lf",Spts); for(i = 1; i < ntot; ++i) fscanf(infile,"%lf",Spts+i); fgets(buf,BUFSIZ,infile); fgets(buf,BUFSIZ,infile); SurXpts = dmatrix(0,nface-1,0,ntot-1); SurYpts = dmatrix(0,nface-1,0,ntot-1); SurZpts = dmatrix(0,nface-1,0,ntot-1); // read surface points for(i = 0; i < nface; ++i) { fgets(buf,BUFSIZ,infile); for(j = 0; j < ntot; ++j) { fgets(buf,BUFSIZ,infile); sscanf(buf,"%lf%lf%lf",SurXpts[i]+j,SurYpts[i]+j,SurZpts[i]+j); } // read input connectivity data for(j = 0; j < (np-1)*(np-1); ++j) fgets(buf,BUFSIZ,infile); } fgets(buf,BUFSIZ,infile); // read Vertids to match with .rea file surfids = imatrix(0,nface,0,4); for(i = 0; i < nface; ++i) { fgets(buf,BUFSIZ,infile); sscanf(buf,"# %*d%d%d%d",surfids[i],surfids[i]+1,surfids[i]+2); surfids[i][0]--; surfids[i][1]--; surfids[i][2]--; surfids[i][3] = surfids[i][0] + surfids[i][1] + surfids[i][2]; } Tri T; T.qa = Snp+1; T.qb = Snp; T.lmax = Snp; Basis *B = Tri_addbase(Snp,Snp+1,Snp,Snp); double av,bv,*hr,*hs,v1,v2; hr = dvector(0,Snp); hs = dvector(0,Snp); // setup collocation interpolation matrix CollMat = dmatrix(0,ntot-1,0,ntot-1); for(i = 0; i < ntot; ++i) { av = (fabs(1.0-Spts[i]) > FPTOL)? 2*(1+Rpts[i])/(1-Spts[i])-1: 0; bv = Spts[i]; Tri_get_point_shape(&T,av,bv,hr,hs); for(j =0; j < ntot; ++j) { v1 = ddot(Snp+1,hr,1,B->vert[j].a,1); v2 = ddot(Snp,hs,1,B->vert[j].b,1); CollMat[i][j] = v1*v2; } } Tri_reset_basis(B); CollMatIpiv = ivector(0,ntot-1); // invert matrix dgetrf(ntot,ntot,*CollMat,ntot,CollMatIpiv,info); if(info) fprintf(stderr,"Trouble factoring collocation matrix\n"); Loaded_Surf_File = 1; free(hr); free(hs); free(Rpts); free(Spts); }
// 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 }
void dgesv( long n, long nrhs, double a[], long lda, long ipiv[], double b[], long ldb, long *info ) { /** * -- LAPACK driver routine (version 1.1) -- * Univ. of Tennessee, Univ. of California Berkeley, NAG Ltd., * Courant Institute, Argonne National Lab, and Rice University * March 31, 1993 * * .. Scalar Arguments ..*/ /** .. * .. Array Arguments ..*/ #undef ipiv_1 #define ipiv_1(a1) ipiv[a1-1] #undef b_2 #define b_2(a1,a2) b[a1-1+ldb*(a2-1)] #undef a_2 #define a_2(a1,a2) a[a1-1+lda*(a2-1)] /** .. * * Purpose * ======= * * DGESV computes the solution to a real system of linear equations * A * X = B, * where A is an N-by-N matrix and X and B are N-by-NRHS matrices. * * The LU decomposition with partial pivoting and row interchanges is * used to factor A as * A = P * L * U, * where P is a permutation matrix, L is unit lower triangular, and U is * upper triangular. The factored form of A is then used to solve the * system of equations A * X = B. * * Arguments * ========= * * N (input) INTEGER * The number of linear equations, i.e., the order of the * matrix A. N >= 0. * * NRHS (input) INTEGER * The number of right hand sides, i.e., the number of columns * of the matrix B. NRHS >= 0. * * A (input/output) DOUBLE PRECISION array, dimension (LDA,N) * On entry, the N-by-N coefficient matrix A. * On exit, the factors L and U from the factorization * A = P*L*U; the unit diagonal elements of L are not stored. * * LDA (input) INTEGER * The leading dimension of the array A. LDA >= max(1,N). * * IPIV (output) INTEGER array, dimension (N) * The pivot indices that define the permutation matrix P; * row i of the matrix was interchanged with row IPIV(i). * * B (input/output) DOUBLE PRECISION array, dimension (LDB,NRHS) * On entry, the N-by-NRHS matrix of right hand side matrix B. * On exit, if INFO = 0, the N-by-NRHS solution matrix X. * * LDB (input) INTEGER * The leading dimension of the array B. LDB >= max(1,N). * * INFO (output) INTEGER * = 0: successful exit * < 0: if INFO = -i, the i-th argument had an illegal value * > 0: if INFO = i, U(i,i) is exactly zero. The factorization * has been completed, but the factor U is exactly * singular, so the solution could not be computed. * * ===================================================================== **/ /** .. * .. Intrinsic Functions ..*/ /* intrinsic max;*/ /** .. * .. Executable Statements .. * * Test the input parameters. **/ /*-----implicit-declarations-----*/ /*-----end-of-declarations-----*/ *info = 0; if( n<0 ) { *info = -1; } else if( nrhs<0 ) { *info = -2; } else if( lda<max( 1, n ) ) { *info = -4; } else if( ldb<max( 1, n ) ) { *info = -7; } if( *info!=0 ) { xerbla( "dgesv ", -*info ); return; } /** * Compute the LU factorization of A. **/ dgetrf( n, n, a, lda, ipiv, info ); if( *info==0 ) { /** * Solve the system A*X = B, overwriting B with X. **/ dgetrs( 'n'/*o transpose*/, n, nrhs, a, lda, ipiv, b, ldb, info ); } return; /** * End of DGESV **/ }
void mexFunction( int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[]) { // ovals - struct, the structure containing the ovals if(nlhs != 0 || nrhs != 0) mexErrMsgTxt("Error this function takes and returns no arguments"); const mxArray* pmxBeta = mexGetArrayPtr("BETA", "global"); double* beta = mxGetPr(pmxBeta); const mxArray* pmxNdata = mexGetArrayPtr("NDATA", "global"); int nData = (int)*mxGetPr(pmxNdata); const mxArray* pmxDataDim = mexGetArrayPtr("DATADIM", "global"); int dataDim = (int)*mxGetPr(pmxDataDim); const mxArray* pmxLatentDim = mexGetArrayPtr("LATENTDIM", "global"); int latentDim = (int)*mxGetPr(pmxLatentDim); const mxArray* pmxX = mexGetArrayPtr("X", "global"); double* X = mxGetPr(pmxX); const mxArray* pmxA = mexGetArrayPtr("A", "global"); double* A = mxGetPr(pmxA); const mxArray* pmxSBar = mexGetArrayPtr("SBAR", "global"); double* sBar = mxGetPr(pmxSBar); const mxArray* pmxSigma_s = mexGetArrayPtr("SIGMA_S", "global"); double* Sigma_s = mxGetPr(pmxSigma_s); const mxArray* pmxFANoise = mexGetArrayPtr("FANOISE", "global"); int FANoise = (int)*mxGetPr(pmxFANoise); const mxArray* pmxTau = mexGetArrayPtr("TAU", "global"); double* tau = mxGetPr(pmxTau); //for n = 1:NDATA //end int lda = latentDim; int length = latentDim; int info = 0; int* ipiv = (int*)mxMalloc(length*sizeof(int)); int order = latentDim; int lwork = order*16; double* work = (double*)mxMalloc(lwork*sizeof(double)); for(int n = 0; n < nData; n++) { // invSigma_s = diag(TAU(n, :)) + ATBA; for(int j = 0; j < latentDim; j++) { for(int j2 = 0; j2 < latentDim; j2++) { if(j2==j) { // Add the diagonal term Sigma_s[j + j2*latentDim + n*latentDim*latentDim] = tau[n + j*nData]; } else { Sigma_s[j + j2*latentDim + n*latentDim*latentDim] = 0; } double temp = 0; if (FANoise != 0){ for(int i = 0; i < dataDim; i++) { temp += A[i + j2*dataDim]*A[i + j*dataDim]*beta[i]; } } else { for(int i = 0; i < dataDim; i++) { temp += A[i + j2*dataDim]*A[i + j*dataDim]; } temp *= beta[0]; } // This is really inv(Sigma_s) but it is stored here for convenience Sigma_s[j + j2*latentDim + n*latentDim*latentDim] += temp; } } // It is not being done by cholesky decomposition in the c++ code // but it should be // C = chol(invSigma_s); // Cinv = eye(LATENTDIM)/C; // SIGMA_S(:, :, n) = Cinv*Cinv'; // create inverse first by lu decomposition of input // call lapack dgetrf(latentDim, latentDim, Sigma_s+n*latentDim*latentDim, lda, ipiv, info); if(info != 0) mexErrMsgTxt("Problems in lu factorisation of matrix"); info = 0; // peform the matrix inversion. dgetri(order, Sigma_s+n*latentDim*latentDim, lda, ipiv, work, lwork, info); // check for successfull inverse if(info > 0) mexErrMsgTxt("Matrix is singular"); else if(info < 0) mexErrMsgTxt("Problem in matrix inverse"); // SBAR(n, :) = (X(n, :).*BETA)*A*SIGMA_S(:, :, n); if(FANoise != 0) { for(int j = 0; j < latentDim; j++) { sBar[n + j*nData] = 0; for(int j2 = 0; j2 < latentDim; j2++) { for(int i = 0; i < dataDim; i++) { sBar[n + j*nData] += X[n + i*nData]*beta[i]*A[i + j2*dataDim]*Sigma_s[j + j2*latentDim + n*latentDim*latentDim]; } } } } else { for(int j = 0; j < latentDim; j++) { sBar[n + j*nData] = 0; for(int j2 = 0; j2 < latentDim; j2++) { for(int i = 0; i < dataDim; i++) { sBar[n + j*nData] += X[n + i*nData]*beta[0]*A[i + j2*dataDim]*Sigma_s[j + j2*latentDim + n*latentDim*latentDim]; } } } } } mxFree(work); mxFree(ipiv); }
void mexFunction( int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[]) { // ovals - struct, the structure containing the ovals if(nrhs != 2) mexErrMsgTxt("Error this function takes two arguments"); if(nlhs != 2) mexErrMsgTxt("Error this function returns two arguments"); if(mxGetClassID(prhs[0]) != mxSTRUCT_CLASS) mexErrMsgTxt("Error model should be a structure"); double* A = mxGetPr(mxGetField(prhs[0], 0, "A")); double* beta = mxGetPr(mxGetField(prhs[0], 0, "beta")); double* tau = mxGetPr(mxGetField(prhs[0], 0, "tau")); int nData = (int)*mxGetPr(mxGetField(prhs[0], 0, "numData")); int dataDim = (int)*mxGetPr(mxGetField(prhs[0], 0, "dataDim")); int latentDim = (int)*mxGetPr(mxGetField(prhs[0], 0, "latentDim")); int FANoise = (int)*mxGetPr(mxGetField(prhs[0], 0, "FANoise")); if(mxGetClassID(prhs[1]) != mxDOUBLE_CLASS) mexErrMsgTxt("Error X should be DOUBLE"); double* X = mxGetPr(prhs[1]); int dims[3]; dims[0] = nData; dims[1] = latentDim; plhs[0] = mxCreateNumericArray(2, dims, mxDOUBLE_CLASS, mxREAL); double* sBar = mxGetPr(plhs[0]); dims[0] = latentDim; dims[1] = latentDim; dims[2] = nData; plhs[1] = mxCreateNumericArray(3, dims, mxDOUBLE_CLASS, mxREAL); double* Sigma_s = mxGetPr(plhs[1]); //for n = 1:NDATA //end int lda = latentDim; int length = latentDim; int info = 0; int* ipiv = (int*)mxMalloc(length*sizeof(int)); int order = latentDim; int lwork = order*16; double* work = (double*)mxMalloc(lwork*sizeof(double)); for(int n = 0; n < nData; n++) { // invSigma_s = diag(TAU(n, :)) + ATBA; for(int j = 0; j < latentDim; j++) { for(int j2 = 0; j2 < latentDim; j2++) { if(j2==j) { // Add the diagonal term Sigma_s[j + j2*latentDim + n*latentDim*latentDim] = tau[n + j*nData]; } else { Sigma_s[j + j2*latentDim + n*latentDim*latentDim] = 0; } double temp = 0; if (FANoise != 0){ for(int i = 0; i < dataDim; i++) { temp += A[i + j2*dataDim]*A[i + j*dataDim]*beta[i]; } } else { for(int i = 0; i < dataDim; i++) { temp += A[i + j2*dataDim]*A[i + j*dataDim]; } temp *= beta[0]; } // This is really inv(Sigma_s) but it is stored here for convenience Sigma_s[j + j2*latentDim + n*latentDim*latentDim] += temp; } } // It is not being done by cholesky decomposition in the c++ code // but it should be // C = chol(invSigma_s); // Cinv = eye(LATENTDIM)/C; // SIGMA_S(:, :, n) = Cinv*Cinv'; // create inverse first by lu decomposition of input // call lapack dgetrf(latentDim, latentDim, Sigma_s+n*latentDim*latentDim, lda, ipiv, info); if(info != 0) mexErrMsgTxt("Problems in lu factorisation of matrix"); info = 0; // peform the matrix inversion. dgetri(order, Sigma_s+n*latentDim*latentDim, lda, ipiv, work, lwork, info); // check for successfull inverse if(info > 0) mexErrMsgTxt("Matrix is singular"); else if(info < 0) mexErrMsgTxt("Problem in matrix inverse"); // SBAR(n, :) = (X(n, :).*BETA)*A*SIGMA_S(:, :, n); if(FANoise != 0) { for(int j = 0; j < latentDim; j++) { sBar[n + j*nData] = 0; for(int j2 = 0; j2 < latentDim; j2++) { for(int i = 0; i < dataDim; i++) { sBar[n + j*nData] += X[n + i*nData]*beta[i]*A[i + j2*dataDim]*Sigma_s[j + j2*latentDim + n*latentDim*latentDim]; } } } } else { for(int j = 0; j < latentDim; j++) { sBar[n + j*nData] = 0; for(int j2 = 0; j2 < latentDim; j2++) { for(int i = 0; i < dataDim; i++) { sBar[n + j*nData] += X[n + i*nData]*beta[0]*A[i + j2*dataDim]*Sigma_s[j + j2*latentDim + n*latentDim*latentDim]; } } } } } mxFree(work); mxFree(ipiv); }
int la_main(){ int i, j, inf, size; double *A, *w, determinant=1; long *ip; FILE *input, *output; input = fopen("origMatrix.txt", "r"); fscanf(input, "%d", &size); A = (double *) malloc(size*size*sizeof(double)); for(i=0;i<size*size;i++)fscanf(input, "%lf", &A[i]); w = (double *) malloc(size*sizeof(double)); ip = (long *) malloc(size*sizeof(long)); inf = dgetrf(size,size,A,size,ip); if (inf != 0) fprintf(stderr, "failure with error %d\n", inf); //LU decomposition for(i=0;i<size;i++)determinant*=A[i*size+i]; //determinant of A inf = dgetri(size, A, size, ip, w, size); if (inf != 0) fprintf(stderr, "failure with error %d\n", inf);//inverse from LU output = fopen("invMatrix.txt","w"); fprintf(output,"%lf\n",determinant);//determinant of A for (i=0; i<size; ++i){ for(j=0; j<size; j++)fprintf(output,"%5.9lf ", A[i*size+j]); fprintf(output,"\n"); } fclose(output); fclose(input); // printf("optimal Lw = %lf\n",w[0]); return 0; }
double la(int size, double *A){ int i, inf; double *w, determinant = 1; long *ip; w = (double *) malloc(size*sizeof(double)); ip = (long *) malloc(size*sizeof(long)); inf = dgetrf(size, size, A, size, ip); if (inf != 0) fprintf(stderr, "failure with error %d\n", inf); //LU decomposition for(i = 0; i < size; i++) determinant *= A[i*size+i]; //determinant of A inf = dgetri(size, A, size, ip, w, size); if (inf != 0) fprintf(stderr, "failure with error %d\n", inf);//inverse from LU return determinant; }