00001 /* DGESVX.F -- translated by f2c (version 19941215). 00002 You must link the resulting object file with the libraries: 00003 -lf2c -lm (in that order) 00004 */ 00005 00006 #include "f2c.h" 00007 #include "camlaimpexp.h" 00008 00009 /* Subroutine */ int __IMPEXP__ dgesvx_(fact, trans, n, nrhs, a, lda, af, ldaf, ipiv, 00010 equed, r, c, b, ldb, x, ldx, rcond, ferr, berr, work, iwork, info, 00011 fact_len, trans_len, equed_len) 00012 char *fact, *trans; 00013 integer *n, *nrhs; 00014 doublereal *a; 00015 integer *lda; 00016 doublereal *af; 00017 integer *ldaf, *ipiv; 00018 char *equed; 00019 doublereal *r, *c, *b; 00020 integer *ldb; 00021 doublereal *x; 00022 integer *ldx; 00023 doublereal *rcond, *ferr, *berr, *work; 00024 integer *iwork, *info; 00025 ftnlen fact_len; 00026 ftnlen trans_len; 00027 ftnlen equed_len; 00028 { 00029 /* System generated locals */ 00030 integer a_dim1, a_offset, af_dim1, af_offset, b_dim1, b_offset, x_dim1, 00031 x_offset, i__1, i__2; 00032 doublereal d__1, d__2; 00033 00034 /* Local variables */ 00035 static doublereal amax; 00036 static char norm[1]; 00037 static integer i, j; 00038 extern logical lsame_(); 00039 static doublereal rcmin, rcmax, anorm; 00040 static logical equil; 00041 extern doublereal dlamch_(), dlange_(); 00042 extern /* Subroutine */ int dlaqge_(), dgecon_(); 00043 static doublereal colcnd; 00044 static logical nofact; 00045 extern /* Subroutine */ int dgeequ_(), dgerfs_(), dgetrf_(), dlacpy_(), 00046 xerbla_(); 00047 static doublereal bignum; 00048 static integer infequ; 00049 static logical colequ; 00050 extern /* Subroutine */ int dgetrs_(); 00051 static doublereal rowcnd; 00052 static logical notran; 00053 static doublereal smlnum; 00054 static logical rowequ; 00055 00056 00057 /* -- LAPACK driver routine (version 1.1) -- */ 00058 /* Univ. of Tennessee, Univ. of California Berkeley, NAG Ltd., */ 00059 /* Courant Institute, Argonne National Lab, and Rice University */ 00060 /* March 31, 1993 */ 00061 00062 /* .. Scalar Arguments .. */ 00063 /* .. */ 00064 /* .. Array Arguments .. */ 00065 /* .. */ 00066 00067 /* Purpose */ 00068 /* ======= */ 00069 00070 /* DGESVX uses the LU factorization to compute the solution to a real */ 00071 /* system of linear equations */ 00072 /* A * X = B, */ 00073 /* where A is an N-by-N matrix and X and B are N-by-NRHS matrices. */ 00074 00075 /* Error bounds on the solution and a condition estimate are also */ 00076 /* provided. */ 00077 00078 /* Description */ 00079 /* =========== */ 00080 00081 /* The following steps are performed: */ 00082 00083 /* 1. If FACT = 'E', real scaling factors are computed to equilibrate */ 00084 /* the system: */ 00085 /* TRANS = 'N': diag(R)*A*diag(C) *inv(diag(C))*X = diag(R)*B 00086 */ 00087 /* TRANS = 'T': (diag(R)*A*diag(C))**T *inv(diag(R))*X = diag(C)*B 00088 */ 00089 /* TRANS = 'C': (diag(R)*A*diag(C))**H *inv(diag(R))*X = diag(C)*B 00090 */ 00091 /* Whether or not the system will be equilibrated depends on the */ 00092 /* scaling of the matrix A, but if equilibration is used, A is */ 00093 /* overwritten by diag(R)*A*diag(C) and B by diag(R)*B (if TRANS='N') 00094 */ 00095 /* or diag(C)*B (if TRANS = 'T' or 'C'). */ 00096 00097 /* 2. If FACT = 'N' or 'E', the LU decomposition is used to factor the */ 00098 /* matrix A (after equilibration if FACT = 'E') as */ 00099 /* A = P * L * U, */ 00100 /* where P is a permutation matrix, L is a unit lower triangular */ 00101 /* matrix, and U is upper triangular. */ 00102 00103 /* 3. The factored form of A is used to estimate the condition number */ 00104 /* of the matrix A. If the reciprocal of the condition number is */ 00105 /* less than machine precision, steps 4-6 are skipped. */ 00106 00107 /* 4. The system of equations is solved for X using the factored form */ 00108 /* of A. */ 00109 00110 /* 5. Iterative refinement is applied to improve the computed solution */ 00111 /* matrix and calculate error bounds and backward error estimates */ 00112 /* for it. */ 00113 00114 /* 6. If FACT = 'E' and equilibration was used, the matrix X is */ 00115 /* premultiplied by diag(C) (if TRANS = 'N') or diag(R) (if */ 00116 /* TRANS = 'T' or 'C') so that it solves the original system */ 00117 /* before equilibration. */ 00118 00119 /* Arguments */ 00120 /* ========= */ 00121 00122 /* FACT (input) CHARACTER*1 */ 00123 /* Specifies whether or not the factored form of the matrix A is 00124 */ 00125 /* supplied on entry, and if not, whether the matrix A should be 00126 */ 00127 /* equilibrated before it is factored. */ 00128 /* = 'F': On entry, AF and IPIV contain the factored form of A. 00129 */ 00130 /* If EQUED is not 'N', the matrix A has been */ 00131 /* equilibrated with scaling factors given by R and C. */ 00132 /* A, AF, and IPIV are not modified. */ 00133 /* = 'N': The matrix A will be copied to AF and factored. */ 00134 /* = 'E': The matrix A will be equilibrated if necessary, then 00135 */ 00136 /* copied to AF and factored. */ 00137 00138 /* TRANS (input) CHARACTER*1 */ 00139 /* Specifies the form of the system of equations: */ 00140 /* = 'N': A * X = B (No transpose) */ 00141 /* = 'T': A**T * X = B (Transpose) */ 00142 /* = 'C': A**H * X = B (Transpose) */ 00143 00144 /* N (input) INTEGER */ 00145 /* The number of linear equations, i.e., the order of the */ 00146 /* matrix A. N >= 0. */ 00147 00148 /* NRHS (input) INTEGER */ 00149 /* The number of right-hand sides, i.e., the number of columns */ 00150 /* of the matrices B and X. NRHS >= 0. */ 00151 00152 /* A (input/output) DOUBLE PRECISION array, dimension (LDA,N) */ 00153 /* On entry, the N-by-N matrix A. If FACT = 'F' and EQUED is */ 00154 /* not 'N', then A must have been equilibrated by the scaling */ 00155 /* factors in R and/or C. A is not modified if FACT = 'F' or */ 00156 /* 'N', or if FACT = 'E' and EQUED = 'N' on exit. */ 00157 00158 /* On exit, if EQUED .ne. 'N', A is scaled as follows: */ 00159 /* EQUED = 'R': A := diag(R) * A */ 00160 /* EQUED = 'C': A := A * diag(C) */ 00161 /* EQUED = 'B': A := diag(R) * A * diag(C). */ 00162 00163 /* LDA (input) INTEGER */ 00164 /* The leading dimension of the array A. LDA >= max(1,N). */ 00165 00166 /* AF (input or output) DOUBLE PRECISION array, dimension (LDAF,N) 00167 */ 00168 /* If FACT = 'F', then AF is an input argument and on entry */ 00169 /* contains the factors L and U from the factorization */ 00170 /* A = P*L*U as computed by DGETRF. If EQUED .ne. 'N', then */ 00171 /* AF is the factored form of the equilibrated matrix A. */ 00172 00173 /* If FACT = 'N', then AF is an output argument and on exit */ 00174 /* returns the factors L and U from the factorization A = P*L*U 00175 */ 00176 /* of the original matrix A. */ 00177 00178 /* If FACT = 'E', then AF is an output argument and on exit */ 00179 /* returns the factors L and U from the factorization A = P*L*U 00180 */ 00181 /* of the equilibrated matrix A (see the description of A for */ 00182 /* the form of the equilibrated matrix). */ 00183 00184 /* LDAF (input) INTEGER */ 00185 /* The leading dimension of the array AF. LDAF >= max(1,N). */ 00186 00187 /* IPIV (input or output) INTEGER array, dimension (N) */ 00188 /* If FACT = 'F', then IPIV is an input argument and on entry */ 00189 /* contains the pivot indices from the factorization A = P*L*U */ 00190 /* as computed by DGETRF; row i of the matrix was interchanged */ 00191 /* with row IPIV(i). */ 00192 00193 /* If FACT = 'N', then IPIV is an output argument and on exit */ 00194 /* contains the pivot indices from the factorization A = P*L*U */ 00195 /* of the original matrix A. */ 00196 00197 /* If FACT = 'E', then IPIV is an output argument and on exit */ 00198 /* contains the pivot indices from the factorization A = P*L*U */ 00199 /* of the equilibrated matrix A. */ 00200 00201 /* EQUED (input/output) CHARACTER*1 */ 00202 /* Specifies the form of equilibration that was done. */ 00203 /* = 'N': No equilibration (always true if FACT = 'N'). */ 00204 /* = 'R': Row equilibration, i.e., A has been premultiplied by 00205 */ 00206 /* diag(R). */ 00207 /* = 'C': Column equilibration, i.e., A has been postmultiplied 00208 */ 00209 /* by diag(C). */ 00210 /* = 'B': Both row and column equilibration, i.e., A has been */ 00211 /* replaced by diag(R) * A * diag(C). */ 00212 /* EQUED is an input variable if FACT = 'F'; otherwise, it is an 00213 */ 00214 /* output variable. */ 00215 00216 /* R (input/output) DOUBLE PRECISION array, dimension (N) */ 00217 /* The row scale factors for A. If EQUED = 'R' or 'B', A is */ 00218 /* multiplied on the left by diag(R); if EQUED = 'N' or 'C', R */ 00219 /* is not accessed. R is an input variable if FACT = 'F'; */ 00220 /* otherwise, R is an output variable. If FACT = 'F' and */ 00221 /* EQUED = 'R' or 'B', each element of R must be positive. */ 00222 00223 /* C (input/output) DOUBLE PRECISION array, dimension (N) */ 00224 /* The column scale factors for A. If EQUED = 'C' or 'B', A is 00225 */ 00226 /* multiplied on the right by diag(C); if EQUED = 'N' or 'R', C 00227 */ 00228 /* is not accessed. C is an input variable if FACT = 'F'; */ 00229 /* otherwise, C is an output variable. If FACT = 'F' and */ 00230 /* EQUED = 'C' or 'B', each element of C must be positive. */ 00231 00232 /* B (input/output) DOUBLE PRECISION array, dimension (LDB,NRHS) */ 00233 /* On entry, the N-by-NRHS right-hand side matrix B. */ 00234 /* On exit, if EQUED = 'N', B is not modified; if TRANS = 'N' */ 00235 /* and EQUED = 'R' or 'B', B is overwritten by diag(R)*B; if */ 00236 /* TRANS = 'T' or 'C' and EQUED = 'C' or 'B', B is overwritten */ 00237 /* by diag(C)*B. */ 00238 00239 /* LDB (input) INTEGER */ 00240 /* The leading dimension of the array B. LDB >= max(1,N). */ 00241 00242 /* X (output) DOUBLE PRECISION array, dimension (LDX,NRHS) */ 00243 /* If INFO = 0, the N-by-NRHS solution matrix X to the original 00244 */ 00245 /* system of equations. Note that A and B are modified on exit 00246 */ 00247 /* if EQUED .ne. 'N', and the solution to the equilibrated */ 00248 /* system is inv(diag(C))*X if TRANS = 'N' and EQUED = 'C' or */ 00249 /* 'B', or inv(diag(R))*X if TRANS = 'T' or 'C' and EQUED = 'R' 00250 */ 00251 /* or 'B'. */ 00252 00253 /* LDX (input) INTEGER */ 00254 /* The leading dimension of the array X. LDX >= max(1,N). */ 00255 00256 /* RCOND (output) DOUBLE PRECISION */ 00257 /* The estimate of the reciprocal condition number of the matrix 00258 */ 00259 /* A after equilibration (if done). If RCOND is less than the */ 00260 /* machine precision (in particular, if RCOND = 0), the matrix */ 00261 /* is singular to working precision. This condition is */ 00262 /* indicated by a return code of INFO > 0, and the solution and 00263 */ 00264 /* error bounds are not computed. */ 00265 00266 /* FERR (output) DOUBLE PRECISION array, dimension (NRHS) */ 00267 /* The estimated forward error bounds for each solution vector */ 00268 /* X(j) (the j-th column of the solution matrix X). */ 00269 /* If XTRUE is the true solution, FERR(j) bounds the magnitude */ 00270 /* of the largest entry in (X(j) - XTRUE) divided by */ 00271 /* the magnitude of the largest entry in X(j). The quality of */ 00272 /* the error bound depends on the quality of the estimate of */ 00273 /* norm(inv(A)) computed in the code; if the estimate of */ 00274 /* norm(inv(A)) is accurate, the error bound is guaranteed. */ 00275 00276 /* BERR (output) DOUBLE PRECISION array, dimension (NRHS) */ 00277 /* The componentwise relative backward error of each solution */ 00278 /* vector X(j) (i.e., the smallest relative change in */ 00279 /* any entry of A or B that makes X(j) an exact solution). */ 00280 00281 /* WORK (workspace) DOUBLE PRECISION array, dimension (4*N) */ 00282 00283 /* IWORK (workspace) INTEGER array, dimension (N) */ 00284 00285 /* INFO (output) INTEGER */ 00286 /* = 0: successful exit */ 00287 /* < 0: if INFO = -i, the i-th argument had an illegal value */ 00288 /* > 0: if INFO = i, and i is */ 00289 /* <= N: U(i,i) is exactly zero. The factorization has */ 00290 /* been completed, but the factor U is exactly */ 00291 /* singular, so the solution and error bounds */ 00292 /* could not be computed. */ 00293 /* = N+1: RCOND is less than machine precision. The */ 00294 /* factorization has been completed, but the */ 00295 /* matrix is singular to working precision, and */ 00296 /* the solution and error bounds have not been */ 00297 /* computed. */ 00298 00299 /* ===================================================================== 00300 */ 00301 00302 /* .. Parameters .. */ 00303 /* .. */ 00304 /* .. Local Scalars .. */ 00305 /* .. */ 00306 /* .. External Functions .. */ 00307 /* .. */ 00308 /* .. External Subroutines .. */ 00309 /* .. */ 00310 /* .. Intrinsic Functions .. */ 00311 /* .. */ 00312 /* .. Executable Statements .. */ 00313 00314 /* Parameter adjustments */ 00315 a_dim1 = *lda; 00316 a_offset = a_dim1 + 1; 00317 a -= a_offset; 00318 af_dim1 = *ldaf; 00319 af_offset = af_dim1 + 1; 00320 af -= af_offset; 00321 --ipiv; 00322 --r; 00323 --c; 00324 b_dim1 = *ldb; 00325 b_offset = b_dim1 + 1; 00326 b -= b_offset; 00327 x_dim1 = *ldx; 00328 x_offset = x_dim1 + 1; 00329 x -= x_offset; 00330 --ferr; 00331 --berr; 00332 --work; 00333 --iwork; 00334 00335 /* Function Body */ 00336 *info = 0; 00337 nofact = lsame_(fact, "N", 1L, 1L); 00338 equil = lsame_(fact, "E", 1L, 1L); 00339 notran = lsame_(trans, "N", 1L, 1L); 00340 if (nofact || equil) { 00341 *(unsigned char *)equed = 'N'; 00342 rowequ = FALSE_; 00343 colequ = FALSE_; 00344 } else { 00345 rowequ = lsame_(equed, "R", 1L, 1L) || lsame_(equed, "B", 1L, 1L); 00346 colequ = lsame_(equed, "C", 1L, 1L) || lsame_(equed, "B", 1L, 1L); 00347 smlnum = dlamch_("Safe minimum", 12L); 00348 bignum = 1. / smlnum; 00349 } 00350 00351 /* Test the input parameters. */ 00352 00353 if (! nofact && ! equil && ! lsame_(fact, "F", 1L, 1L)) { 00354 *info = -1; 00355 } else if (! notran && ! lsame_(trans, "T", 1L, 1L) && ! lsame_(trans, 00356 "C", 1L, 1L)) { 00357 *info = -2; 00358 } else if (*n < 0) { 00359 *info = -3; 00360 } else if (*nrhs < 0) { 00361 *info = -4; 00362 } else if (*lda < max(1,*n)) { 00363 *info = -6; 00364 } else if (*ldaf < max(1,*n)) { 00365 *info = -8; 00366 } else if (lsame_(fact, "F", 1L, 1L) && ! (rowequ || colequ || lsame_( 00367 equed, "N", 1L, 1L))) { 00368 *info = -10; 00369 } else { 00370 if (rowequ) { 00371 rcmin = bignum; 00372 rcmax = 0.; 00373 i__1 = *n; 00374 for (j = 1; j <= i__1; ++j) { 00375 /* Computing MIN */ 00376 d__1 = rcmin, d__2 = r[j]; 00377 rcmin = min(d__1,d__2); 00378 /* Computing MAX */ 00379 d__1 = rcmax, d__2 = r[j]; 00380 rcmax = max(d__1,d__2); 00381 /* L10: */ 00382 } 00383 if (rcmin <= 0.) { 00384 *info = -11; 00385 } else if (*n > 0) { 00386 rowcnd = max(rcmin,smlnum) / min(rcmax,bignum); 00387 } else { 00388 rowcnd = 1.; 00389 } 00390 } 00391 if (colequ && *info == 0) { 00392 rcmin = bignum; 00393 rcmax = 0.; 00394 i__1 = *n; 00395 for (j = 1; j <= i__1; ++j) { 00396 /* Computing MIN */ 00397 d__1 = rcmin, d__2 = c[j]; 00398 rcmin = min(d__1,d__2); 00399 /* Computing MAX */ 00400 d__1 = rcmax, d__2 = c[j]; 00401 rcmax = max(d__1,d__2); 00402 /* L20: */ 00403 } 00404 if (rcmin <= 0.) { 00405 *info = -12; 00406 } else if (*n > 0) { 00407 colcnd = max(rcmin,smlnum) / min(rcmax,bignum); 00408 } else { 00409 colcnd = 1.; 00410 } 00411 } 00412 if (*info == 0) { 00413 if (*ldb < max(1,*n)) { 00414 *info = -14; 00415 } else if (*ldx < max(1,*n)) { 00416 *info = -16; 00417 } 00418 } 00419 } 00420 00421 if (*info != 0) { 00422 i__1 = -(*info); 00423 xerbla_("DGESVX", &i__1, 6L); 00424 return 0; 00425 } 00426 00427 if (equil) { 00428 00429 /* Compute row and column scalings to equilibrate the matrix A. 00430 */ 00431 00432 dgeequ_(n, n, &a[a_offset], lda, &r[1], &c[1], &rowcnd, &colcnd, & 00433 amax, &infequ); 00434 if (infequ == 0) { 00435 00436 /* Equilibrate the matrix. */ 00437 00438 dlaqge_(n, n, &a[a_offset], lda, &r[1], &c[1], &rowcnd, &colcnd, & 00439 amax, equed, 1L); 00440 rowequ = lsame_(equed, "R", 1L, 1L) || lsame_(equed, "B", 1L, 1L); 00441 colequ = lsame_(equed, "C", 1L, 1L) || lsame_(equed, "B", 1L, 1L); 00442 } 00443 } 00444 00445 /* Scale the right-hand side. */ 00446 00447 if (notran) { 00448 if (rowequ) { 00449 i__1 = *nrhs; 00450 for (j = 1; j <= i__1; ++j) { 00451 i__2 = *n; 00452 for (i = 1; i <= i__2; ++i) { 00453 b[i + j * b_dim1] = r[i] * b[i + j * b_dim1]; 00454 /* L30: */ 00455 } 00456 /* L40: */ 00457 } 00458 } 00459 } else if (colequ) { 00460 i__1 = *nrhs; 00461 for (j = 1; j <= i__1; ++j) { 00462 i__2 = *n; 00463 for (i = 1; i <= i__2; ++i) { 00464 b[i + j * b_dim1] = c[i] * b[i + j * b_dim1]; 00465 /* L50: */ 00466 } 00467 /* L60: */ 00468 } 00469 } 00470 00471 if (nofact || equil) { 00472 00473 /* Compute the LU factorization of A. */ 00474 00475 dlacpy_("Full", n, n, &a[a_offset], lda, &af[af_offset], ldaf, 4L); 00476 dgetrf_(n, n, &af[af_offset], ldaf, &ipiv[1], info); 00477 00478 /* Return if INFO is non-zero. */ 00479 00480 if (*info != 0) { 00481 if (*info > 0) { 00482 *rcond = 0.; 00483 } 00484 return 0; 00485 } 00486 } 00487 00488 /* Compute the norm of the matrix A. */ 00489 00490 if (notran) { 00491 *(unsigned char *)norm = '1'; 00492 } else { 00493 *(unsigned char *)norm = 'I'; 00494 } 00495 anorm = dlange_(norm, n, n, &a[a_offset], lda, &work[1], 1L); 00496 00497 /* Compute the reciprocal of the condition number of A. */ 00498 00499 dgecon_(norm, n, &af[af_offset], ldaf, &anorm, rcond, &work[1], &iwork[1], 00500 info, 1L); 00501 00502 /* Return if the matrix is singular to working precision. */ 00503 00504 if (*rcond < dlamch_("Epsilon", 7L)) { 00505 *info = *n + 1; 00506 return 0; 00507 } 00508 00509 /* Compute the solution matrix X. */ 00510 00511 dlacpy_("Full", n, nrhs, &b[b_offset], ldb, &x[x_offset], ldx, 4L); 00512 dgetrs_(trans, n, nrhs, &af[af_offset], ldaf, &ipiv[1], &x[x_offset], ldx, 00513 info, 1L); 00514 00515 /* Use iterative refinement to improve the computed solution and */ 00516 /* compute error bounds and backward error estimates for it. */ 00517 00518 dgerfs_(trans, n, nrhs, &a[a_offset], lda, &af[af_offset], ldaf, &ipiv[1], 00519 &b[b_offset], ldb, &x[x_offset], ldx, &ferr[1], &berr[1], &work[ 00520 1], &iwork[1], info, 1L); 00521 00522 /* Transform the solution matrix X to a solution of the original */ 00523 /* system. */ 00524 00525 if (notran) { 00526 if (colequ) { 00527 i__1 = *nrhs; 00528 for (j = 1; j <= i__1; ++j) { 00529 i__2 = *n; 00530 for (i = 1; i <= i__2; ++i) { 00531 x[i + j * x_dim1] = c[i] * x[i + j * x_dim1]; 00532 /* L70: */ 00533 } 00534 /* L80: */ 00535 } 00536 i__1 = *nrhs; 00537 for (j = 1; j <= i__1; ++j) { 00538 ferr[j] /= colcnd; 00539 /* L90: */ 00540 } 00541 } 00542 } else if (rowequ) { 00543 i__1 = *nrhs; 00544 for (j = 1; j <= i__1; ++j) { 00545 i__2 = *n; 00546 for (i = 1; i <= i__2; ++i) { 00547 x[i + j * x_dim1] = r[i] * x[i + j * x_dim1]; 00548 /* L100: */ 00549 } 00550 /* L110: */ 00551 } 00552 i__1 = *nrhs; 00553 for (j = 1; j <= i__1; ++j) { 00554 ferr[j] /= rowcnd; 00555 /* L120: */ 00556 } 00557 } 00558 00559 return 0; 00560 00561 /* End of DGESVX */ 00562 00563 } /* dgesvx_ */ 00564