/* ** ** DGESL benchmark ** ** We would like to declare a[][lda], but c does not allow it. In this ** function, references to a[i][j] are written a[lda*i+j]. ** ** dgesl solves the double precision system ** a * x = b or trans(a) * x = b ** using the factors computed by dgeco or dgefa. ** ** on entry ** ** a double precision[n][lda] ** the output from dgeco or dgefa. ** ** lda integer ** the leading dimension of the array a . ** ** n integer ** the order of the matrix a . ** ** ipvt integer[n] ** the pivot vector from dgeco or dgefa. ** ** b double precision[n] ** the right hand side vector. ** ** job integer ** = 0 to solve a*x = b , ** = nonzero to solve trans(a)*x = b where ** trans(a) is the transpose. ** ** on return ** ** b the solution vector x . ** ** error condition ** ** a division by zero will occur if the input factor contains a ** zero on the diagonal. technically this indicates singularity ** but it is often caused by improper arguments or improper ** setting of lda . it will not occur if the subroutines are ** called correctly and if dgeco has set rcond .gt. 0.0 ** or dgefa has set info .eq. 0 . ** ** to compute inverse(a) * c where c is a matrix ** with p columns ** dgeco(a,lda,n,ipvt,rcond,z) ** if (!rcond is too small){ ** for (j=0,j<p,j++) ** dgesl(a,lda,n,ipvt,c[j][0],0); ** } ** ** linpack. this version dated 08/14/78 . ** cleve moler, university of new mexico, argonne national lab. ** ** functions ** ** blas daxpy,ddot */ static void dgesl(REAL *a,int lda,int n,int *ipvt,REAL *b,int job,int roll) { REAL t; int k,kb,l,nm1; if (roll) { nm1 = n - 1; if (job == 0) { /* job = 0 , solve a * x = b */ /* first solve l*y = b */ if (nm1 >= 1) for (k = 0; k < nm1; k++) { l = ipvt[k]; t = b[l]; if (l != k) { b[l] = b[k]; b[k] = t; } daxpy_r(n-(k+1),t,&a[lda*k+k+1],1,&b[k+1],1); } /* now solve u*x = y */ for (kb = 0; kb < n; kb++) { k = n - (kb + 1); b[k] = b[k]/a[lda*k+k]; t = -b[k]; daxpy_r(k,t,&a[lda*k+0],1,&b[0],1); } } else { /* job = nonzero, solve trans(a) * x = b */ /* first solve trans(u)*y = b */ for (k = 0; k < n; k++) { t = ddot_r(k,&a[lda*k+0],1,&b[0],1); b[k] = (b[k] - t)/a[lda*k+k]; } /* now solve trans(l)*x = y */ if (nm1 >= 1) for (kb = 1; kb < nm1; kb++) { k = n - (kb+1); b[k] = b[k] + ddot_r(n-(k+1),&a[lda*k+k+1],1,&b[k+1],1); l = ipvt[k]; if (l != k) { t = b[l]; b[l] = b[k]; b[k] = t; } } } } else { nm1 = n - 1; if (job == 0) { /* job = 0 , solve a * x = b */ /* first solve l*y = b */ if (nm1 >= 1) for (k = 0; k < nm1; k++) { l = ipvt[k]; t = b[l]; if (l != k) { b[l] = b[k]; b[k] = t; } daxpy_ur(n-(k+1),t,&a[lda*k+k+1],1,&b[k+1],1); } /* now solve u*x = y */ for (kb = 0; kb < n; kb++) { k = n - (kb + 1); b[k] = b[k]/a[lda*k+k]; t = -b[k]; daxpy_ur(k,t,&a[lda*k+0],1,&b[0],1); } } else { /* job = nonzero, solve trans(a) * x = b */ /* first solve trans(u)*y = b */ for (k = 0; k < n; k++) { t = ddot_ur(k,&a[lda*k+0],1,&b[0],1); b[k] = (b[k] - t)/a[lda*k+k]; } /* now solve trans(l)*x = y */ if (nm1 >= 1) for (kb = 1; kb < nm1; kb++) { k = n - (kb+1); b[k] = b[k] + ddot_ur(n-(k+1),&a[lda*k+k+1],1,&b[k+1],1); l = ipvt[k]; if (l != k) { t = b[l]; b[l] = b[k]; b[k] = t; } } } } }
void dgesl(int *a,int lda,int n,int *ipvt,int *b,int job,int roll) { int t; int k,kb,l,nm1; if (roll>=1) { nm1 = n - 1; if (job == 0) { if (nm1 >= 1) for (k = 0; k < nm1; k++) { l = ipvt[k]; t = b[l]; if (!(l == k)) { b[l] = b[k]; b[k] = t; } daxpy_r(n-(k+1),t,&a[lda*k+k+1],1,&b[k+1],1); } for (kb = 0; kb < n; kb++) { k = n - (kb + 1); b[k] = b[k]/a[lda*k+k]; t = -b[k]; daxpy_r(k,t,&a[lda*k+0],1,&b[0],1); } } else { for (k = 0; k < n; k++) { t = ddot_r(k,&a[lda*k+0],1,&b[0],1); b[k] = (b[k] - t)/a[lda*k+k]; } if (nm1 >= 1) for (kb = 1; kb < nm1; kb++) { k = n - (kb+1); b[k] = b[k] + ddot_r(n-(k+1),&a[lda*k+k+1],1,&b[k+1],1); l = ipvt[k]; if (!(l == k)) { t = b[l]; b[l] = b[k]; b[k] = t; } } } } else { nm1 = n - 1; if (job == 0) { if (nm1 >= 1) for (k = 0; k < nm1; k++) { l = ipvt[k]; t = b[l]; if (!(l == k)) { b[l] = b[k]; b[k] = t; } daxpy_ur(n-(k+1),t,&a[lda*k+k+1],1,&b[k+1],1); } for (kb = 0; kb < n; kb++) { k = n - (kb + 1); b[k] = b[k]/a[lda*k+k]; t = -b[k]; daxpy_ur(k,t,&a[lda*k+0],1,&b[0],1); } } else { for (k = 0; k < n; k++) { t = ddot_ur(k,&a[lda*k+0],1,&b[0],1); b[k] = (b[k] - t)/a[lda*k+k]; } if (nm1 >= 1) for (kb = 1; kb < nm1; kb++) { k = n - (kb+1); b[k] = b[k] + ddot_ur(n-(k+1),&a[lda*k+k+1],1,&b[k+1],1); l = ipvt[k]; if (!(l == k)) { t = b[l]; b[l] = b[k]; b[k] = t; } } } } }
/* ** ** DGEFA benchmark ** ** We would like to declare a[][lda], but c does not allow it. In this ** function, references to a[i][j] are written a[lda*i+j]. ** ** dgefa factors a double precision matrix by gaussian elimination. ** ** dgefa is usually called by dgeco, but it can be called ** directly with a saving in time if rcond is not needed. ** (time for dgeco) = (1 + 9/n)*(time for dgefa) . ** ** on entry ** ** a REAL precision[n][lda] ** the matrix to be factored. ** ** lda integer ** the leading dimension of the array a . ** ** n integer ** the order of the matrix a . ** ** on return ** ** a an upper triangular matrix and the multipliers ** which were used to obtain it. ** the factorization can be written a = l*u where ** l is a product of permutation and unit lower ** triangular matrices and u is upper triangular. ** ** ipvt integer[n] ** an integer vector of pivot indices. ** ** info integer ** = 0 normal value. ** = k if u[k][k] .eq. 0.0 . this is not an error ** condition for this subroutine, but it does ** indicate that dgesl or dgedi will divide by zero ** if called. use rcond in dgeco for a reliable ** indication of singularity. ** ** linpack. this version dated 08/14/78 . ** cleve moler, university of New Mexico, argonne national lab. ** ** functions ** ** blas daxpy,dscal,idamax ** */ static void dgefa(REAL *a,int lda,int n,int *ipvt,int *info,int roll) { REAL t; int /*idamax(),*/j,k,kp1,l,nm1; /* gaussian elimination with partial pivoting */ if (roll) { *info = 0; nm1 = n - 1; if (nm1 >= 0) for (k = 0; k < nm1; k++) { kp1 = k + 1; /* find l = pivot index */ l = idamax(n-k,&a[lda*k+k],1) + k; ipvt[k] = l; /* zero pivot implies this column already triangularized */ if (a[lda*k+l] != ZERO) { /* interchange if necessary */ if (l != k) { t = a[lda*k+l]; a[lda*k+l] = a[lda*k+k]; a[lda*k+k] = t; } /* compute multipliers */ t = -ONE/a[lda*k+k]; dscal_r(n-(k+1),t,&a[lda*k+k+1],1); /* row elimination with column indexing */ for (j = kp1; j < n; j++) { t = a[lda*j+l]; if (l != k) { a[lda*j+l] = a[lda*j+k]; a[lda*j+k] = t; } daxpy_r(n-(k+1),t,&a[lda*k+k+1],1,&a[lda*j+k+1],1); } } else (*info) = k; } ipvt[n-1] = n-1; if (a[lda*(n-1)+(n-1)] == ZERO) (*info) = n-1; } else { *info = 0; nm1 = n - 1; if (nm1 >= 0) for (k = 0; k < nm1; k++) { kp1 = k + 1; /* find l = pivot index */ l = idamax(n-k,&a[lda*k+k],1) + k; ipvt[k] = l; /* zero pivot implies this column already triangularized */ if (a[lda*k+l] != ZERO) { /* interchange if necessary */ if (l != k) { t = a[lda*k+l]; a[lda*k+l] = a[lda*k+k]; a[lda*k+k] = t; } /* compute multipliers */ t = -ONE/a[lda*k+k]; dscal_ur(n-(k+1),t,&a[lda*k+k+1],1); /* row elimination with column indexing */ for (j = kp1; j < n; j++) { t = a[lda*j+l]; if (l != k) { a[lda*j+l] = a[lda*j+k]; a[lda*j+k] = t; } daxpy_ur(n-(k+1),t,&a[lda*k+k+1],1,&a[lda*j+k+1],1); } } else (*info) = k; } ipvt[n-1] = n-1; if (a[lda*(n-1)+(n-1)] == ZERO) (*info) = n-1; } }
void dgefa(int *a,int lda,int n,int *ipvt,int *info,int roll) { int t; int idamax(),j,k,kp1,l,nm1; if (roll>=1) { *info = 0; nm1 = n - 1; if (nm1 >= 0) for (k = 0; k < nm1; k++) { kp1 = k + 1; l = idamax(n-k,&a[lda*k+k],1) + k; ipvt[k] = l; if (!(a[lda*k+l] == ZERO)) { if (!(l == k)) { t = a[lda*k+l]; a[lda*k+l] = a[lda*k+k]; a[lda*k+k] = t; } t = -ONE/a[lda*k+k]; dscal_r(n-(k+1),t,&a[lda*k+k+1],1); for (j = kp1; j < n; j++) { t = a[lda*j+l]; if (!(l == k)) { a[lda*j+l] = a[lda*j+k]; a[lda*j+k] = t; } daxpy_r(n-(k+1),t,&a[lda*k+k+1],1,&a[lda*j+k+1],1); } } else (*info) = k; } ipvt[n-1] = n-1; if (a[lda*(n-1)+(n-1)] == ZERO) (*info) = n-1; } else { *info = 0; nm1 = n - 1; if (nm1 >= 0) for (k = 0; k < nm1; k++) { kp1 = k + 1; l = idamax(n-k,&a[lda*k+k],1) + k; ipvt[k] = l; if (!(a[lda*k+l] == ZERO)) { if (!(l == k)) { t = a[lda*k+l]; a[lda*k+l] = a[lda*k+k]; a[lda*k+k] = t; } t = -ONE/a[lda*k+k]; dscal_ur(n-(k+1),t,&a[lda*k+k+1],1); for (j = kp1; j < n; j++) { t = a[lda*j+l]; if (!(l == k)) { a[lda*j+l] = a[lda*j+k]; a[lda*j+k] = t; } daxpy_ur(n-(k+1),t,&a[lda*k+k+1],1,&a[lda*j+k+1],1); } } else (*info) = k; } ipvt[n-1] = n-1; if (a[lda*(n-1)+(n-1)] == ZERO) (*info) = n-1; } }