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


swiftnav
Author(s):
autogenerated on Sat Jun 8 2019 18:56:12