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

dlatrs.c

Go to the documentation of this file.
00001 /* DLATRS.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 
00008 /* Table of constant values */
00009 
00010 static integer c__1 = 1;
00011 static doublereal c_b36 = .5;
00012 
00013 /* Subroutine */ int dlatrs_(uplo, trans, diag, normin, n, a, lda, x, scale, 
00014         cnorm, info, uplo_len, trans_len, diag_len, normin_len)
00015 char *uplo, *trans, *diag, *normin;
00016 integer *n;
00017 doublereal *a;
00018 integer *lda;
00019 doublereal *x, *scale, *cnorm;
00020 integer *info;
00021 ftnlen uplo_len;
00022 ftnlen trans_len;
00023 ftnlen diag_len;
00024 ftnlen normin_len;
00025 {
00026     /* System generated locals */
00027     integer a_dim1, a_offset, i__1, i__2, i__3;
00028     doublereal d__1, d__2, d__3;
00029 
00030     /* Local variables */
00031     static integer jinc;
00032     extern doublereal ddot_();
00033     static doublereal xbnd;
00034     static integer imax;
00035     static doublereal tmax, tjjs, xmax, grow, sumj;
00036     static integer i, j;
00037     extern /* Subroutine */ int dscal_();
00038     extern logical lsame_();
00039     static doublereal tscal, uscal;
00040     extern doublereal dasum_();
00041     static integer jlast;
00042     extern /* Subroutine */ int daxpy_();
00043     static logical upper;
00044     extern /* Subroutine */ int dtrsv_();
00045     extern doublereal dlamch_();
00046     static doublereal xj;
00047     extern integer idamax_();
00048     extern /* Subroutine */ int xerbla_();
00049     static doublereal bignum;
00050     static logical notran;
00051     static integer jfirst;
00052     static doublereal smlnum;
00053     static logical nounit;
00054     static doublereal rec, tjj;
00055 
00056 
00057 /*  -- LAPACK auxiliary routine (version 1.1) -- */
00058 /*     Univ. of Tennessee, Univ. of California Berkeley, NAG Ltd., */
00059 /*     Courant Institute, Argonne National Lab, and Rice University */
00060 /*     June 30, 1992 */
00061 
00062 /*     .. Scalar Arguments .. */
00063 /*     .. */
00064 /*     .. Array Arguments .. */
00065 /*     .. */
00066 
00067 /*  Purpose */
00068 /*  ======= */
00069 
00070 /*  DLATRS solves one of the triangular systems */
00071 
00072 /*     A *x = s*b  or  A'*x = s*b */
00073 
00074 /*  with scaling to prevent overflow.  Here A is an upper or lower */
00075 /*  triangular matrix, A' denotes the transpose of A, x and b are */
00076 /*  n-element vectors, and s is a scaling factor, usually less than */
00077 /*  or equal to 1, chosen so that the components of x will be less than */
00078 /*  the overflow threshold.  If the unscaled problem will not cause */
00079 /*  overflow, the Level 2 BLAS routine DTRSV is called.  If the matrix A 
00080 */
00081 /*  is singular (A(j,j) = 0 for some j), then s is set to 0 and a */
00082 /*  non-trivial solution to A*x = 0 is returned. */
00083 
00084 /*  Arguments */
00085 /*  ========= */
00086 
00087 /*  UPLO    (input) CHARACTER*1 */
00088 /*          Specifies whether the matrix A is upper or lower triangular. 
00089 */
00090 /*          = 'U':  Upper triangular */
00091 /*          = 'L':  Lower triangular */
00092 
00093 /*  TRANS   (input) CHARACTER*1 */
00094 /*          Specifies the operation applied to A. */
00095 /*          = 'N':  Solve A * x = s*b  (No transpose) */
00096 /*          = 'T':  Solve A'* x = s*b  (Transpose) */
00097 /*          = 'C':  Solve A'* x = s*b  (Conjugate transpose = Transpose) 
00098 */
00099 
00100 /*  DIAG    (input) CHARACTER*1 */
00101 /*          Specifies whether or not the matrix A is unit triangular. */
00102 /*          = 'N':  Non-unit triangular */
00103 /*          = 'U':  Unit triangular */
00104 
00105 /*  NORMIN  (input) CHARACTER*1 */
00106 /*          Specifies whether CNORM has been set or not. */
00107 /*          = 'Y':  CNORM contains the column norms on entry */
00108 /*          = 'N':  CNORM is not set on entry.  On exit, the norms will */
00109 /*                  be computed and stored in CNORM. */
00110 
00111 /*  N       (input) INTEGER */
00112 /*          The order of the matrix A.  N >= 0. */
00113 
00114 /*  A       (input) DOUBLE PRECISION array, dimension (LDA,N) */
00115 /*          The triangular matrix A.  If UPLO = 'U', the leading n by n */
00116 /*          upper triangular part of the array A contains the upper */
00117 /*          triangular matrix, and the strictly lower triangular part of 
00118 */
00119 /*          A is not referenced.  If UPLO = 'L', the leading n by n lower 
00120 */
00121 /*          triangular part of the array A contains the lower triangular 
00122 */
00123 /*          matrix, and the strictly upper triangular part of A is not */
00124 /*          referenced.  If DIAG = 'U', the diagonal elements of A are */
00125 /*          also not referenced and are assumed to be 1. */
00126 
00127 /*  LDA     (input) INTEGER */
00128 /*          The leading dimension of the array A.  LDA >= max (1,N). */
00129 
00130 /*  X       (input/output) DOUBLE PRECISION array, dimension (N) */
00131 /*          On entry, the right hand side b of the triangular system. */
00132 /*          On exit, X is overwritten by the solution vector x. */
00133 
00134 /*  SCALE   (output) DOUBLE PRECISION */
00135 /*          The scaling factor s for the triangular system */
00136 /*             A * x = s*b  or  A'* x = s*b. */
00137 /*          If SCALE = 0, the matrix A is singular or badly scaled, and */
00138 /*          the vector x is an exact or approximate solution to A*x = 0. 
00139 */
00140 
00141 /*  CNORM   (input or output) DOUBLE PRECISION array, dimension (N) */
00142 
00143 /*          If NORMIN = 'Y', CNORM is an input variable and CNORM(j) */
00144 /*          contains the norm of the off-diagonal part of the j-th column 
00145 */
00146 /*          of A.  If TRANS = 'N', CNORM(j) must be greater than or equal 
00147 */
00148 /*          to the infinity-norm, and if TRANS = 'T' or 'C', CNORM(j) */
00149 /*          must be greater than or equal to the 1-norm. */
00150 
00151 /*          If NORMIN = 'N', CNORM is an output variable and CNORM(j) */
00152 /*          returns the 1-norm of the offdiagonal part of the j-th column 
00153 */
00154 /*          of A. */
00155 
00156 /*  INFO    (output) INTEGER */
00157 /*          = 0:  successful exit */
00158 /*          < 0:  if INFO = -k, the k-th argument had an illegal value */
00159 
00160 /*  Further Details */
00161 /*  ======= ======= */
00162 
00163 /*  A rough bound on x is computed; if that is less than overflow, DTRSV 
00164 */
00165 /*  is called, otherwise, specific code is used which checks for possible 
00166 */
00167 /*  overflow or divide-by-zero at every operation. */
00168 
00169 /*  A columnwise scheme is used for solving A*x = b.  The basic algorithm 
00170 */
00171 /*  if A is lower triangular is */
00172 
00173 /*       x[1:n] := b[1:n] */
00174 /*       for j = 1, ..., n */
00175 /*            x(j) := x(j) / A(j,j) */
00176 /*            x[j+1:n] := x[j+1:n] - x(j) * A[j+1:n,j] */
00177 /*       end */
00178 
00179 /*  Define bounds on the components of x after j iterations of the loop: 
00180 */
00181 /*     M(j) = bound on x[1:j] */
00182 /*     G(j) = bound on x[j+1:n] */
00183 /*  Initially, let M(0) = 0 and G(0) = max{x(i), i=1,...,n}. */
00184 
00185 /*  Then for iteration j+1 we have */
00186 /*     M(j+1) <= G(j) / | A(j+1,j+1) | */
00187 /*     G(j+1) <= G(j) + M(j+1) * | A[j+2:n,j+1] | */
00188 /*            <= G(j) ( 1 + CNORM(j+1) / | A(j+1,j+1) | ) */
00189 
00190 /*  where CNORM(j+1) is greater than or equal to the infinity-norm of */
00191 /*  column j+1 of A, not counting the diagonal.  Hence */
00192 
00193 /*     G(j) <= G(0) product ( 1 + CNORM(i) / | A(i,i) | ) */
00194 /*                  1<=i<=j */
00195 /*  and */
00196 
00197 /*     |x(j)| <= ( G(0) / |A(j,j)| ) product ( 1 + CNORM(i) / |A(i,i)| ) 
00198 */
00199 /*                                   1<=i< j */
00200 
00201 /*  Since |x(j)| <= M(j), we use the Level 2 BLAS routine DTRSV if the */
00202 /*  reciprocal of the largest M(j), j=1,..,n, is larger than */
00203 /*  max(underflow, 1/overflow). */
00204 
00205 /*  The bound on x(j) is also used to determine when a step in the */
00206 /*  columnwise method can be performed without fear of overflow.  If */
00207 /*  the computed bound is greater than a large constant, x is scaled to */
00208 /*  prevent overflow, but if the bound overflows, x is set to 0, x(j) to 
00209 */
00210 /*  1, and scale to 0, and a non-trivial solution to A*x = 0 is found. */
00211 
00212 /*  Similarly, a row-wise scheme is used to solve A'*x = b.  The basic */
00213 /*  algorithm for A upper triangular is */
00214 
00215 /*       for j = 1, ..., n */
00216 /*            x(j) := ( b(j) - A[1:j-1,j]' * x[1:j-1] ) / A(j,j) */
00217 /*       end */
00218 
00219 /*  We simultaneously compute two bounds */
00220 /*       G(j) = bound on ( b(i) - A[1:i-1,i]' * x[1:i-1] ), 1<=i<=j */
00221 /*       M(j) = bound on x(i), 1<=i<=j */
00222 
00223 /*  The initial values are G(0) = 0, M(0) = max{b(i), i=1,..,n}, and we */
00224 /*  add the constraint G(j) >= G(j-1) and M(j) >= M(j-1) for j >= 1. */
00225 /*  Then the bound on x(j) is */
00226 
00227 /*       M(j) <= M(j-1) * ( 1 + CNORM(j) ) / | A(j,j) | */
00228 
00229 /*            <= M(0) * product ( ( 1 + CNORM(i) ) / |A(i,i)| ) */
00230 /*                      1<=i<=j */
00231 
00232 /*  and we can safely call DTRSV if 1/M(n) and 1/G(n) are both greater */
00233 /*  than max(underflow, 1/overflow). */
00234 
00235 /*  ===================================================================== 
00236 */
00237 
00238 /*     .. Parameters .. */
00239 /*     .. */
00240 /*     .. Local Scalars .. */
00241 /*     .. */
00242 /*     .. External Functions .. */
00243 /*     .. */
00244 /*     .. External Subroutines .. */
00245 /*     .. */
00246 /*     .. Intrinsic Functions .. */
00247 /*     .. */
00248 /*     .. Executable Statements .. */
00249 
00250     /* Parameter adjustments */
00251     a_dim1 = *lda;
00252     a_offset = a_dim1 + 1;
00253     a -= a_offset;
00254     --x;
00255     --cnorm;
00256 
00257     /* Function Body */
00258     *info = 0;
00259     upper = lsame_(uplo, "U", 1L, 1L);
00260     notran = lsame_(trans, "N", 1L, 1L);
00261     nounit = lsame_(diag, "N", 1L, 1L);
00262 
00263 /*     Test the input parameters. */
00264 
00265     if (! upper && ! lsame_(uplo, "L", 1L, 1L)) {
00266         *info = -1;
00267     } else if (! notran && ! lsame_(trans, "T", 1L, 1L) && ! lsame_(trans, 
00268             "C", 1L, 1L)) {
00269         *info = -2;
00270     } else if (! nounit && ! lsame_(diag, "U", 1L, 1L)) {
00271         *info = -3;
00272     } else if (! lsame_(normin, "Y", 1L, 1L) && ! lsame_(normin, "N", 1L, 1L))
00273              {
00274         *info = -4;
00275     } else if (*n < 0) {
00276         *info = -5;
00277     } else if (*lda < max(1,*n)) {
00278         *info = -7;
00279     }
00280     if (*info != 0) {
00281         i__1 = -(*info);
00282         xerbla_("DLATRS", &i__1, 6L);
00283         return 0;
00284     }
00285 
00286 /*     Quick return if possible */
00287 
00288     if (*n == 0) {
00289         return 0;
00290     }
00291 
00292 /*     Determine machine dependent parameters to control overflow. */
00293 
00294     smlnum = dlamch_("Safe minimum", 12L) / dlamch_("Precision", 9L);
00295     bignum = 1. / smlnum;
00296     *scale = 1.;
00297 
00298     if (lsame_(normin, "N", 1L, 1L)) {
00299 
00300 /*        Compute the 1-norm of each column, not including the diagona
00301 l. */
00302 
00303         if (upper) {
00304 
00305 /*           A is upper triangular. */
00306 
00307             i__1 = *n;
00308             for (j = 1; j <= i__1; ++j) {
00309                 i__2 = j - 1;
00310                 cnorm[j] = dasum_(&i__2, &a[j * a_dim1 + 1], &c__1);
00311 /* L10: */
00312             }
00313         } else {
00314 
00315 /*           A is lower triangular. */
00316 
00317             i__1 = *n - 1;
00318             for (j = 1; j <= i__1; ++j) {
00319                 i__2 = *n - j;
00320                 cnorm[j] = dasum_(&i__2, &a[j + 1 + j * a_dim1], &c__1);
00321 /* L20: */
00322             }
00323             cnorm[*n] = 0.;
00324         }
00325     }
00326 
00327 /*     Scale the column norms by TSCAL if the maximum entry in CNORM is */
00328 /*     greater than BIGNUM. */
00329 
00330     imax = idamax_(n, &cnorm[1], &c__1);
00331     tmax = cnorm[imax];
00332     if (tmax <= bignum) {
00333         tscal = 1.;
00334     } else {
00335         tscal = 1. / (smlnum * tmax);
00336         dscal_(n, &tscal, &cnorm[1], &c__1);
00337     }
00338 
00339 /*     Compute a bound on the computed solution vector to see if the */
00340 /*     Level 2 BLAS routine DTRSV can be used. */
00341 
00342     j = idamax_(n, &x[1], &c__1);
00343     xmax = (d__1 = x[j], abs(d__1));
00344     xbnd = xmax;
00345     if (notran) {
00346 
00347 /*        Compute the growth in A * x = b. */
00348 
00349         if (upper) {
00350             jfirst = *n;
00351             jlast = 1;
00352             jinc = -1;
00353         } else {
00354             jfirst = 1;
00355             jlast = *n;
00356             jinc = 1;
00357         }
00358 
00359         if (tscal != 1.) {
00360             grow = 0.;
00361             goto L50;
00362         }
00363 
00364         if (nounit) {
00365 
00366 /*           A is non-unit triangular. */
00367 
00368 /*           Compute GROW = 1/G(j) and XBND = 1/M(j). */
00369 /*           Initially, G(0) = max{x(i), i=1,...,n}. */
00370 
00371             grow = 1. / max(xbnd,smlnum);
00372             xbnd = grow;
00373             i__1 = jlast;
00374             i__2 = jinc;
00375             for (j = jfirst; i__2 < 0 ? j >= i__1 : j <= i__1; j += i__2) {
00376 
00377 /*              Exit the loop if the growth factor is too smal
00378 l. */
00379 
00380                 if (grow <= smlnum) {
00381                     goto L50;
00382                 }
00383 
00384 /*              M(j) = G(j-1) / abs(A(j,j)) */
00385 
00386                 tjj = (d__1 = a[j + j * a_dim1], abs(d__1));
00387 /* Computing MIN */
00388                 d__1 = xbnd, d__2 = min(1.,tjj) * grow;
00389                 xbnd = min(d__1,d__2);
00390                 if (tjj + cnorm[j] >= smlnum) {
00391 
00392 /*                 G(j) = G(j-1)*( 1 + CNORM(j) / abs(A(j,
00393 j)) ) */
00394 
00395                     grow *= tjj / (tjj + cnorm[j]);
00396                 } else {
00397 
00398 /*                 G(j) could overflow, set GROW to 0. */
00399 
00400                     grow = 0.;
00401                 }
00402 /* L30: */
00403             }
00404             grow = xbnd;
00405         } else {
00406 
00407 /*           A is unit triangular. */
00408 
00409 /*           Compute GROW = 1/G(j), where G(0) = max{x(i), i=1,...
00410 ,n}. */
00411 
00412 /* Computing MIN */
00413             d__1 = 1., d__2 = 1. / max(xbnd,smlnum);
00414             grow = min(d__1,d__2);
00415             i__2 = jlast;
00416             i__1 = jinc;
00417             for (j = jfirst; i__1 < 0 ? j >= i__2 : j <= i__2; j += i__1) {
00418 
00419 /*              Exit the loop if the growth factor is too smal
00420 l. */
00421 
00422                 if (grow <= smlnum) {
00423                     goto L50;
00424                 }
00425 
00426 /*              G(j) = G(j-1)*( 1 + CNORM(j) ) */
00427 
00428                 grow *= 1. / (cnorm[j] + 1.);
00429 /* L40: */
00430             }
00431         }
00432 L50:
00433 
00434         ;
00435     } else {
00436 
00437 /*        Compute the growth in A' * x = b. */
00438 
00439         if (upper) {
00440             jfirst = 1;
00441             jlast = *n;
00442             jinc = 1;
00443         } else {
00444             jfirst = *n;
00445             jlast = 1;
00446             jinc = -1;
00447         }
00448 
00449         if (tscal != 1.) {
00450             grow = 0.;
00451             goto L80;
00452         }
00453 
00454         if (nounit) {
00455 
00456 /*           A is non-unit triangular. */
00457 
00458 /*           Compute GROW = 1/G(j) and XBND = 1/M(j). */
00459 /*           Initially, M(0) = max{x(i), i=1,...,n}. */
00460 
00461             grow = 1. / max(xbnd,smlnum);
00462             xbnd = grow;
00463             i__1 = jlast;
00464             i__2 = jinc;
00465             for (j = jfirst; i__2 < 0 ? j >= i__1 : j <= i__1; j += i__2) {
00466 
00467 /*              Exit the loop if the growth factor is too smal
00468 l. */
00469 
00470                 if (grow <= smlnum) {
00471                     goto L80;
00472                 }
00473 
00474 /*              G(j) = max( G(j-1), M(j-1)*( 1 + CNORM(j) ) ) 
00475 */
00476 
00477                 xj = cnorm[j] + 1.;
00478 /* Computing MIN */
00479                 d__1 = grow, d__2 = xbnd / xj;
00480                 grow = min(d__1,d__2);
00481 
00482 /*              M(j) = M(j-1)*( 1 + CNORM(j) ) / abs(A(j,j)) 
00483 */
00484 
00485                 tjj = (d__1 = a[j + j * a_dim1], abs(d__1));
00486                 if (xj > tjj) {
00487                     xbnd *= tjj / xj;
00488                 }
00489 /* L60: */
00490             }
00491             grow = min(grow,xbnd);
00492         } else {
00493 
00494 /*           A is unit triangular. */
00495 
00496 /*           Compute GROW = 1/G(j), where G(0) = max{x(i), i=1,...
00497 ,n}. */
00498 
00499 /* Computing MIN */
00500             d__1 = 1., d__2 = 1. / max(xbnd,smlnum);
00501             grow = min(d__1,d__2);
00502             i__2 = jlast;
00503             i__1 = jinc;
00504             for (j = jfirst; i__1 < 0 ? j >= i__2 : j <= i__2; j += i__1) {
00505 
00506 /*              Exit the loop if the growth factor is too smal
00507 l. */
00508 
00509                 if (grow <= smlnum) {
00510                     goto L80;
00511                 }
00512 
00513 /*              G(j) = ( 1 + CNORM(j) )*G(j-1) */
00514 
00515                 xj = cnorm[j] + 1.;
00516                 grow /= xj;
00517 /* L70: */
00518             }
00519         }
00520 L80:
00521         ;
00522     }
00523 
00524     if (grow * tscal > smlnum) {
00525 
00526 /*        Use the Level 2 BLAS solve if the reciprocal of the bound on
00527  */
00528 /*        elements of X is not too small. */
00529 
00530         dtrsv_(uplo, trans, diag, n, &a[a_offset], lda, &x[1], &c__1, 1L, 1L, 
00531                 1L);
00532     } else {
00533 
00534 /*        Use a Level 1 BLAS solve, scaling intermediate results. */
00535 
00536         if (xmax > bignum) {
00537 
00538 /*           Scale X so that its components are less than or equal
00539  to */
00540 /*           BIGNUM in absolute value. */
00541 
00542             *scale = bignum / xmax;
00543             dscal_(n, scale, &x[1], &c__1);
00544             xmax = bignum;
00545         }
00546 
00547         if (notran) {
00548 
00549 /*           Solve A * x = b */
00550 
00551             i__1 = jlast;
00552             i__2 = jinc;
00553             for (j = jfirst; i__2 < 0 ? j >= i__1 : j <= i__1; j += i__2) {
00554 
00555 /*              Compute x(j) = b(j) / A(j,j), scaling x if nec
00556 essary. */
00557 
00558                 xj = (d__1 = x[j], abs(d__1));
00559                 if (nounit) {
00560                     tjjs = a[j + j * a_dim1] * tscal;
00561                 } else {
00562                     tjjs = tscal;
00563                     if (tscal == 1.) {
00564                         goto L100;
00565                     }
00566                 }
00567                 tjj = abs(tjjs);
00568                 if (tjj > smlnum) {
00569 
00570 /*                    abs(A(j,j)) > SMLNUM: */
00571 
00572                     if (tjj < 1.) {
00573                         if (xj > tjj * bignum) {
00574 
00575 /*                          Scale x by 1/b(j). */
00576 
00577                             rec = 1. / xj;
00578                             dscal_(n, &rec, &x[1], &c__1);
00579                             *scale *= rec;
00580                             xmax *= rec;
00581                         }
00582                     }
00583                     x[j] /= tjjs;
00584                     xj = (d__1 = x[j], abs(d__1));
00585                 } else if (tjj > 0.) {
00586 
00587 /*                    0 < abs(A(j,j)) <= SMLNUM: */
00588 
00589                     if (xj > tjj * bignum) {
00590 
00591 /*                       Scale x by (1/abs(x(j)))*abs(
00592 A(j,j))*BIGNUM */
00593 /*                       to avoid overflow when dividi
00594 ng by A(j,j). */
00595 
00596                         rec = tjj * bignum / xj;
00597                         if (cnorm[j] > 1.) {
00598 
00599 /*                          Scale by 1/CNORM(j) to
00600  avoid overflow when */
00601 /*                          multiplying x(j) times
00602  column j. */
00603 
00604                             rec /= cnorm[j];
00605                         }
00606                         dscal_(n, &rec, &x[1], &c__1);
00607                         *scale *= rec;
00608                         xmax *= rec;
00609                     }
00610                     x[j] /= tjjs;
00611                     xj = (d__1 = x[j], abs(d__1));
00612                 } else {
00613 
00614 /*                    A(j,j) = 0:  Set x(1:n) = 0, x(j) = 
00615 1, and */
00616 /*                    scale = 0, and compute a solution to
00617  A*x = 0. */
00618 
00619                     i__3 = *n;
00620                     for (i = 1; i <= i__3; ++i) {
00621                         x[i] = 0.;
00622 /* L90: */
00623                     }
00624                     x[j] = 1.;
00625                     xj = 1.;
00626                     *scale = 0.;
00627                     xmax = 0.;
00628                 }
00629 L100:
00630 
00631 /*              Scale x if necessary to avoid overflow when ad
00632 ding a */
00633 /*              multiple of column j of A. */
00634 
00635                 if (xj > 1.) {
00636                     rec = 1. / xj;
00637                     if (cnorm[j] > (bignum - xmax) * rec) {
00638 
00639 /*                    Scale x by 1/(2*abs(x(j))). */
00640 
00641                         rec *= .5;
00642                         dscal_(n, &rec, &x[1], &c__1);
00643                         *scale *= rec;
00644                     }
00645                 } else if (xj * cnorm[j] > bignum - xmax) {
00646 
00647 /*                 Scale x by 1/2. */
00648 
00649                     dscal_(n, &c_b36, &x[1], &c__1);
00650                     *scale *= .5;
00651                 }
00652 
00653                 if (upper) {
00654                     if (j > 1) {
00655 
00656 /*                    Compute the update */
00657 /*                       x(1:j-1) := x(1:j-1) - x(j) *
00658  A(1:j-1,j) */
00659 
00660                         i__3 = j - 1;
00661                         d__1 = -x[j] * tscal;
00662                         daxpy_(&i__3, &d__1, &a[j * a_dim1 + 1], &c__1, &x[1],
00663                                  &c__1);
00664                         i__3 = j - 1;
00665                         i = idamax_(&i__3, &x[1], &c__1);
00666                         xmax = (d__1 = x[i], abs(d__1));
00667                     }
00668                 } else {
00669                     if (j < *n) {
00670 
00671 /*                    Compute the update */
00672 /*                       x(j+1:n) := x(j+1:n) - x(j) *
00673  A(j+1:n,j) */
00674 
00675                         i__3 = *n - j;
00676                         d__1 = -x[j] * tscal;
00677                         daxpy_(&i__3, &d__1, &a[j + 1 + j * a_dim1], &c__1, &
00678                                 x[j + 1], &c__1);
00679                         i__3 = *n - j;
00680                         i = j + idamax_(&i__3, &x[j + 1], &c__1);
00681                         xmax = (d__1 = x[i], abs(d__1));
00682                     }
00683                 }
00684 /* L110: */
00685             }
00686 
00687         } else {
00688 
00689 /*           Solve A' * x = b */
00690 
00691             i__2 = jlast;
00692             i__1 = jinc;
00693             for (j = jfirst; i__1 < 0 ? j >= i__2 : j <= i__2; j += i__1) {
00694 
00695 /*              Compute x(j) = b(j) - sum A(k,j)*x(k). */
00696 /*                                    k<>j */
00697 
00698                 xj = (d__1 = x[j], abs(d__1));
00699                 uscal = tscal;
00700                 rec = 1. / max(xmax,1.);
00701                 if (cnorm[j] > (bignum - xj) * rec) {
00702 
00703 /*                 If x(j) could overflow, scale x by 1/(2
00704 *XMAX). */
00705 
00706                     rec *= .5;
00707                     if (nounit) {
00708                         tjjs = a[j + j * a_dim1] * tscal;
00709                     } else {
00710                         tjjs = tscal;
00711                     }
00712                     tjj = abs(tjjs);
00713                     if (tjj > 1.) {
00714 
00715 /*                       Divide by A(j,j) when scaling
00716  x if A(j,j) > 1. */
00717 
00718 /* Computing MIN */
00719                         d__1 = 1., d__2 = rec * tjj;
00720                         rec = min(d__1,d__2);
00721                         uscal /= tjjs;
00722                     }
00723                     if (rec < 1.) {
00724                         dscal_(n, &rec, &x[1], &c__1);
00725                         *scale *= rec;
00726                         xmax *= rec;
00727                     }
00728                 }
00729 
00730                 sumj = 0.;
00731                 if (uscal == 1.) {
00732 
00733 /*                 If the scaling needed for A in the dot 
00734 product is 1, */
00735 /*                 call DDOT to perform the dot product. 
00736 */
00737 
00738                     if (upper) {
00739                         i__3 = j - 1;
00740                         sumj = ddot_(&i__3, &a[j * a_dim1 + 1], &c__1, &x[1], 
00741                                 &c__1);
00742                     } else if (j < *n) {
00743                         i__3 = *n - j;
00744                         sumj = ddot_(&i__3, &a[j + 1 + j * a_dim1], &c__1, &x[
00745                                 j + 1], &c__1);
00746                     }
00747                 } else {
00748 
00749 /*                 Otherwise, use in-line code for the dot
00750  product. */
00751 
00752                     if (upper) {
00753                         i__3 = j - 1;
00754                         for (i = 1; i <= i__3; ++i) {
00755                             sumj += a[i + j * a_dim1] * uscal * x[i];
00756 /* L120: */
00757                         }
00758                     } else if (j < *n) {
00759                         i__3 = *n;
00760                         for (i = j + 1; i <= i__3; ++i) {
00761                             sumj += a[i + j * a_dim1] * uscal * x[i];
00762 /* L130: */
00763                         }
00764                     }
00765                 }
00766 
00767                 if (uscal == tscal) {
00768 
00769 /*                 Compute x(j) := ( x(j) - sumj ) / A(j,j
00770 ) if 1/A(j,j) */
00771 /*                 was not used to scale the dotproduct. 
00772 */
00773 
00774                     x[j] -= sumj;
00775                     xj = (d__1 = x[j], abs(d__1));
00776                     if (nounit) {
00777                         tjjs = a[j + j * a_dim1] * tscal;
00778                     } else {
00779                         tjjs = tscal;
00780                         if (tscal == 1.) {
00781                             goto L150;
00782                         }
00783                     }
00784 
00785 /*                    Compute x(j) = x(j) / A(j,j), scalin
00786 g if necessary. */
00787 
00788                     tjj = abs(tjjs);
00789                     if (tjj > smlnum) {
00790 
00791 /*                       abs(A(j,j)) > SMLNUM: */
00792 
00793                         if (tjj < 1.) {
00794                             if (xj > tjj * bignum) {
00795 
00796 /*                             Scale X by 1/ab
00797 s(x(j)). */
00798 
00799                                 rec = 1. / xj;
00800                                 dscal_(n, &rec, &x[1], &c__1);
00801                                 *scale *= rec;
00802                                 xmax *= rec;
00803                             }
00804                         }
00805                         x[j] /= tjjs;
00806                     } else if (tjj > 0.) {
00807 
00808 /*                       0 < abs(A(j,j)) <= SMLNUM: */
00809 
00810                         if (xj > tjj * bignum) {
00811 
00812 /*                          Scale x by (1/abs(x(j)
00813 ))*abs(A(j,j))*BIGNUM. */
00814 
00815                             rec = tjj * bignum / xj;
00816                             dscal_(n, &rec, &x[1], &c__1);
00817                             *scale *= rec;
00818                             xmax *= rec;
00819                         }
00820                         x[j] /= tjjs;
00821                     } else {
00822 
00823 /*                       A(j,j) = 0:  Set x(1:n) = 0, 
00824 x(j) = 1, and */
00825 /*                       scale = 0, and compute a solu
00826 tion to A'*x = 0. */
00827 
00828                         i__3 = *n;
00829                         for (i = 1; i <= i__3; ++i) {
00830                             x[i] = 0.;
00831 /* L140: */
00832                         }
00833                         x[j] = 1.;
00834                         *scale = 0.;
00835                         xmax = 0.;
00836                     }
00837 L150:
00838                     ;
00839                 } else {
00840 
00841 /*                 Compute x(j) := x(j) / A(j,j)  - sumj i
00842 f the dot */
00843 /*                 product has already been divided by 1/A
00844 (j,j). */
00845 
00846                     x[j] = x[j] / tjjs - sumj;
00847                 }
00848 /* Computing MAX */
00849                 d__2 = xmax, d__3 = (d__1 = x[j], abs(d__1));
00850                 xmax = max(d__2,d__3);
00851 /* L160: */
00852             }
00853         }
00854         *scale /= tscal;
00855     }
00856 
00857 /*     Scale the column norms by 1/TSCAL for return. */
00858 
00859     if (tscal != 1.) {
00860         d__1 = 1. / tscal;
00861         dscal_(n, &d__1, &cnorm[1], &c__1);
00862     }
00863 
00864     return 0;
00865 
00866 /*     End of DLATRS */
00867 
00868 } /* dlatrs_ */
00869 

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