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


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