Main Page | Modules | Namespace List | Class Hierarchy | Alphabetical List | Class List | Directories | File List | Namespace Members | Class Members | File Members | Related Pages | Examples

dgesvx.c

Go to the documentation of this file.
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 

Generated on Wed Sep 5 12:54:19 2007 for DSACSS Operational Code by  doxygen 1.3.9.1