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


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