clatps.c
Go to the documentation of this file.
00001 /* clatps.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 clatps_(char *uplo, char *trans, char *diag, char *
00022         normin, integer *n, complex *ap, complex *x, real *scale, real *cnorm, 
00023          integer *info)
00024 {
00025     /* System generated locals */
00026     integer i__1, i__2, i__3, i__4, i__5;
00027     real r__1, r__2, r__3, r__4;
00028     complex q__1, q__2, q__3, q__4;
00029 
00030     /* Builtin functions */
00031     double r_imag(complex *);
00032     void r_cnjg(complex *, complex *);
00033 
00034     /* Local variables */
00035     integer i__, j, ip;
00036     real xj, rec, tjj;
00037     integer jinc, jlen;
00038     real xbnd;
00039     integer imax;
00040     real tmax;
00041     complex tjjs;
00042     real xmax, grow;
00043     extern /* Complex */ VOID cdotc_(complex *, integer *, complex *, integer 
00044             *, complex *, integer *);
00045     extern logical lsame_(char *, char *);
00046     extern /* Subroutine */ int sscal_(integer *, real *, real *, integer *);
00047     real tscal;
00048     complex uscal;
00049     integer jlast;
00050     extern /* Complex */ VOID cdotu_(complex *, integer *, complex *, integer 
00051             *, complex *, integer *);
00052     complex csumj;
00053     extern /* Subroutine */ int caxpy_(integer *, complex *, complex *, 
00054             integer *, complex *, integer *);
00055     logical upper;
00056     extern /* Subroutine */ int ctpsv_(char *, char *, char *, integer *, 
00057             complex *, complex *, integer *), slabad_(
00058             real *, real *);
00059     extern integer icamax_(integer *, complex *, integer *);
00060     extern /* Complex */ VOID cladiv_(complex *, complex *, complex *);
00061     extern doublereal slamch_(char *);
00062     extern /* Subroutine */ int csscal_(integer *, real *, complex *, integer 
00063             *), xerbla_(char *, integer *);
00064     real bignum;
00065     extern integer isamax_(integer *, real *, integer *);
00066     extern doublereal scasum_(integer *, complex *, integer *);
00067     logical notran;
00068     integer jfirst;
00069     real smlnum;
00070     logical nounit;
00071 
00072 
00073 /*  -- LAPACK auxiliary routine (version 3.2) -- */
00074 /*     Univ. of Tennessee, Univ. of California Berkeley and NAG Ltd.. */
00075 /*     November 2006 */
00076 
00077 /*     .. Scalar Arguments .. */
00078 /*     .. */
00079 /*     .. Array Arguments .. */
00080 /*     .. */
00081 
00082 /*  Purpose */
00083 /*  ======= */
00084 
00085 /*  CLATPS solves one of the triangular systems */
00086 
00087 /*     A * x = s*b,  A**T * x = s*b,  or  A**H * x = s*b, */
00088 
00089 /*  with scaling to prevent overflow, where A is an upper or lower */
00090 /*  triangular matrix stored in packed form.  Here A**T denotes the */
00091 /*  transpose of A, A**H denotes the conjugate transpose of A, x and b */
00092 /*  are n-element vectors, and s is a scaling factor, usually less than */
00093 /*  or equal to 1, chosen so that the components of x will be less than */
00094 /*  the overflow threshold.  If the unscaled problem will not cause */
00095 /*  overflow, the Level 2 BLAS routine CTPSV is called. If the matrix A */
00096 /*  is singular (A(j,j) = 0 for some j), then s is set to 0 and a */
00097 /*  non-trivial solution to A*x = 0 is returned. */
00098 
00099 /*  Arguments */
00100 /*  ========= */
00101 
00102 /*  UPLO    (input) CHARACTER*1 */
00103 /*          Specifies whether the matrix A is upper or lower triangular. */
00104 /*          = 'U':  Upper triangular */
00105 /*          = 'L':  Lower triangular */
00106 
00107 /*  TRANS   (input) CHARACTER*1 */
00108 /*          Specifies the operation applied to A. */
00109 /*          = 'N':  Solve A * x = s*b     (No transpose) */
00110 /*          = 'T':  Solve A**T * x = s*b  (Transpose) */
00111 /*          = 'C':  Solve A**H * x = s*b  (Conjugate transpose) */
00112 
00113 /*  DIAG    (input) CHARACTER*1 */
00114 /*          Specifies whether or not the matrix A is unit triangular. */
00115 /*          = 'N':  Non-unit triangular */
00116 /*          = 'U':  Unit triangular */
00117 
00118 /*  NORMIN  (input) CHARACTER*1 */
00119 /*          Specifies whether CNORM has been set or not. */
00120 /*          = 'Y':  CNORM contains the column norms on entry */
00121 /*          = 'N':  CNORM is not set on entry.  On exit, the norms will */
00122 /*                  be computed and stored in CNORM. */
00123 
00124 /*  N       (input) INTEGER */
00125 /*          The order of the matrix A.  N >= 0. */
00126 
00127 /*  AP      (input) COMPLEX array, dimension (N*(N+1)/2) */
00128 /*          The upper or lower triangular matrix A, packed columnwise in */
00129 /*          a linear array.  The j-th column of A is stored in the array */
00130 /*          AP as follows: */
00131 /*          if UPLO = 'U', AP(i + (j-1)*j/2) = A(i,j) for 1<=i<=j; */
00132 /*          if UPLO = 'L', AP(i + (j-1)*(2n-j)/2) = A(i,j) for j<=i<=n. */
00133 
00134 /*  X       (input/output) COMPLEX array, dimension (N) */
00135 /*          On entry, the right hand side b of the triangular system. */
00136 /*          On exit, X is overwritten by the solution vector x. */
00137 
00138 /*  SCALE   (output) REAL */
00139 /*          The scaling factor s for the triangular system */
00140 /*             A * x = s*b,  A**T * x = s*b,  or  A**H * x = s*b. */
00141 /*          If SCALE = 0, the matrix A is singular or badly scaled, and */
00142 /*          the vector x is an exact or approximate solution to A*x = 0. */
00143 
00144 /*  CNORM   (input or output) REAL array, dimension (N) */
00145 
00146 /*          If NORMIN = 'Y', CNORM is an input argument and CNORM(j) */
00147 /*          contains the norm of the off-diagonal part of the j-th column */
00148 /*          of A.  If TRANS = 'N', CNORM(j) must be greater than or equal */
00149 /*          to the infinity-norm, and if TRANS = 'T' or 'C', CNORM(j) */
00150 /*          must be greater than or equal to the 1-norm. */
00151 
00152 /*          If NORMIN = 'N', CNORM is an output argument and CNORM(j) */
00153 /*          returns the 1-norm of the offdiagonal part of the j-th column */
00154 /*          of A. */
00155 
00156 /*  INFO    (output) INTEGER */
00157 /*          = 0:  successful exit */
00158 /*          < 0:  if INFO = -k, the k-th argument had an illegal value */
00159 
00160 /*  Further Details */
00161 /*  ======= ======= */
00162 
00163 /*  A rough bound on x is computed; if that is less than overflow, CTPSV */
00164 /*  is called, otherwise, specific code is used which checks for possible */
00165 /*  overflow or divide-by-zero at every operation. */
00166 
00167 /*  A columnwise scheme is used for solving A*x = b.  The basic algorithm */
00168 /*  if A is lower triangular is */
00169 
00170 /*       x[1:n] := b[1:n] */
00171 /*       for j = 1, ..., n */
00172 /*            x(j) := x(j) / A(j,j) */
00173 /*            x[j+1:n] := x[j+1:n] - x(j) * A[j+1:n,j] */
00174 /*       end */
00175 
00176 /*  Define bounds on the components of x after j iterations of the loop: */
00177 /*     M(j) = bound on x[1:j] */
00178 /*     G(j) = bound on x[j+1:n] */
00179 /*  Initially, let M(0) = 0 and G(0) = max{x(i), i=1,...,n}. */
00180 
00181 /*  Then for iteration j+1 we have */
00182 /*     M(j+1) <= G(j) / | A(j+1,j+1) | */
00183 /*     G(j+1) <= G(j) + M(j+1) * | A[j+2:n,j+1] | */
00184 /*            <= G(j) ( 1 + CNORM(j+1) / | A(j+1,j+1) | ) */
00185 
00186 /*  where CNORM(j+1) is greater than or equal to the infinity-norm of */
00187 /*  column j+1 of A, not counting the diagonal.  Hence */
00188 
00189 /*     G(j) <= G(0) product ( 1 + CNORM(i) / | A(i,i) | ) */
00190 /*                  1<=i<=j */
00191 /*  and */
00192 
00193 /*     |x(j)| <= ( G(0) / |A(j,j)| ) product ( 1 + CNORM(i) / |A(i,i)| ) */
00194 /*                                   1<=i< j */
00195 
00196 /*  Since |x(j)| <= M(j), we use the Level 2 BLAS routine CTPSV if the */
00197 /*  reciprocal of the largest M(j), j=1,..,n, is larger than */
00198 /*  max(underflow, 1/overflow). */
00199 
00200 /*  The bound on x(j) is also used to determine when a step in the */
00201 /*  columnwise method can be performed without fear of overflow.  If */
00202 /*  the computed bound is greater than a large constant, x is scaled to */
00203 /*  prevent overflow, but if the bound overflows, x is set to 0, x(j) to */
00204 /*  1, and scale to 0, and a non-trivial solution to A*x = 0 is found. */
00205 
00206 /*  Similarly, a row-wise scheme is used to solve A**T *x = b  or */
00207 /*  A**H *x = b.  The basic algorithm for A upper triangular is */
00208 
00209 /*       for j = 1, ..., n */
00210 /*            x(j) := ( b(j) - A[1:j-1,j]' * x[1:j-1] ) / A(j,j) */
00211 /*       end */
00212 
00213 /*  We simultaneously compute two bounds */
00214 /*       G(j) = bound on ( b(i) - A[1:i-1,i]' * x[1:i-1] ), 1<=i<=j */
00215 /*       M(j) = bound on x(i), 1<=i<=j */
00216 
00217 /*  The initial values are G(0) = 0, M(0) = max{b(i), i=1,..,n}, and we */
00218 /*  add the constraint G(j) >= G(j-1) and M(j) >= M(j-1) for j >= 1. */
00219 /*  Then the bound on x(j) is */
00220 
00221 /*       M(j) <= M(j-1) * ( 1 + CNORM(j) ) / | A(j,j) | */
00222 
00223 /*            <= M(0) * product ( ( 1 + CNORM(i) ) / |A(i,i)| ) */
00224 /*                      1<=i<=j */
00225 
00226 /*  and we can safely call CTPSV if 1/M(n) and 1/G(n) are both greater */
00227 /*  than max(underflow, 1/overflow). */
00228 
00229 /*  ===================================================================== */
00230 
00231 /*     .. Parameters .. */
00232 /*     .. */
00233 /*     .. Local Scalars .. */
00234 /*     .. */
00235 /*     .. External Functions .. */
00236 /*     .. */
00237 /*     .. External Subroutines .. */
00238 /*     .. */
00239 /*     .. Intrinsic Functions .. */
00240 /*     .. */
00241 /*     .. Statement Functions .. */
00242 /*     .. */
00243 /*     .. Statement Function definitions .. */
00244 /*     .. */
00245 /*     .. Executable Statements .. */
00246 
00247     /* Parameter adjustments */
00248     --cnorm;
00249     --x;
00250     --ap;
00251 
00252     /* Function Body */
00253     *info = 0;
00254     upper = lsame_(uplo, "U");
00255     notran = lsame_(trans, "N");
00256     nounit = lsame_(diag, "N");
00257 
00258 /*     Test the input parameters. */
00259 
00260     if (! upper && ! lsame_(uplo, "L")) {
00261         *info = -1;
00262     } else if (! notran && ! lsame_(trans, "T") && ! 
00263             lsame_(trans, "C")) {
00264         *info = -2;
00265     } else if (! nounit && ! lsame_(diag, "U")) {
00266         *info = -3;
00267     } else if (! lsame_(normin, "Y") && ! lsame_(normin, 
00268              "N")) {
00269         *info = -4;
00270     } else if (*n < 0) {
00271         *info = -5;
00272     }
00273     if (*info != 0) {
00274         i__1 = -(*info);
00275         xerbla_("CLATPS", &i__1);
00276         return 0;
00277     }
00278 
00279 /*     Quick return if possible */
00280 
00281     if (*n == 0) {
00282         return 0;
00283     }
00284 
00285 /*     Determine machine dependent parameters to control overflow. */
00286 
00287     smlnum = slamch_("Safe minimum");
00288     bignum = 1.f / smlnum;
00289     slabad_(&smlnum, &bignum);
00290     smlnum /= slamch_("Precision");
00291     bignum = 1.f / smlnum;
00292     *scale = 1.f;
00293 
00294     if (lsame_(normin, "N")) {
00295 
00296 /*        Compute the 1-norm of each column, not including the diagonal. */
00297 
00298         if (upper) {
00299 
00300 /*           A is upper triangular. */
00301 
00302             ip = 1;
00303             i__1 = *n;
00304             for (j = 1; j <= i__1; ++j) {
00305                 i__2 = j - 1;
00306                 cnorm[j] = scasum_(&i__2, &ap[ip], &c__1);
00307                 ip += j;
00308 /* L10: */
00309             }
00310         } else {
00311 
00312 /*           A is lower triangular. */
00313 
00314             ip = 1;
00315             i__1 = *n - 1;
00316             for (j = 1; j <= i__1; ++j) {
00317                 i__2 = *n - j;
00318                 cnorm[j] = scasum_(&i__2, &ap[ip + 1], &c__1);
00319                 ip = ip + *n - j + 1;
00320 /* L20: */
00321             }
00322             cnorm[*n] = 0.f;
00323         }
00324     }
00325 
00326 /*     Scale the column norms by TSCAL if the maximum element in CNORM is */
00327 /*     greater than BIGNUM/2. */
00328 
00329     imax = isamax_(n, &cnorm[1], &c__1);
00330     tmax = cnorm[imax];
00331     if (tmax <= bignum * .5f) {
00332         tscal = 1.f;
00333     } else {
00334         tscal = .5f / (smlnum * tmax);
00335         sscal_(n, &tscal, &cnorm[1], &c__1);
00336     }
00337 
00338 /*     Compute a bound on the computed solution vector to see if the */
00339 /*     Level 2 BLAS routine CTPSV can be used. */
00340 
00341     xmax = 0.f;
00342     i__1 = *n;
00343     for (j = 1; j <= i__1; ++j) {
00344 /* Computing MAX */
00345         i__2 = j;
00346         r__3 = xmax, r__4 = (r__1 = x[i__2].r / 2.f, dabs(r__1)) + (r__2 = 
00347                 r_imag(&x[j]) / 2.f, dabs(r__2));
00348         xmax = dmax(r__3,r__4);
00349 /* L30: */
00350     }
00351     xbnd = xmax;
00352     if (notran) {
00353 
00354 /*        Compute the growth in A * x = b. */
00355 
00356         if (upper) {
00357             jfirst = *n;
00358             jlast = 1;
00359             jinc = -1;
00360         } else {
00361             jfirst = 1;
00362             jlast = *n;
00363             jinc = 1;
00364         }
00365 
00366         if (tscal != 1.f) {
00367             grow = 0.f;
00368             goto L60;
00369         }
00370 
00371         if (nounit) {
00372 
00373 /*           A is non-unit triangular. */
00374 
00375 /*           Compute GROW = 1/G(j) and XBND = 1/M(j). */
00376 /*           Initially, G(0) = max{x(i), i=1,...,n}. */
00377 
00378             grow = .5f / dmax(xbnd,smlnum);
00379             xbnd = grow;
00380             ip = jfirst * (jfirst + 1) / 2;
00381             jlen = *n;
00382             i__1 = jlast;
00383             i__2 = jinc;
00384             for (j = jfirst; i__2 < 0 ? j >= i__1 : j <= i__1; j += i__2) {
00385 
00386 /*              Exit the loop if the growth factor is too small. */
00387 
00388                 if (grow <= smlnum) {
00389                     goto L60;
00390                 }
00391 
00392                 i__3 = ip;
00393                 tjjs.r = ap[i__3].r, tjjs.i = ap[i__3].i;
00394                 tjj = (r__1 = tjjs.r, dabs(r__1)) + (r__2 = r_imag(&tjjs), 
00395                         dabs(r__2));
00396 
00397                 if (tjj >= smlnum) {
00398 
00399 /*                 M(j) = G(j-1) / abs(A(j,j)) */
00400 
00401 /* Computing MIN */
00402                     r__1 = xbnd, r__2 = dmin(1.f,tjj) * grow;
00403                     xbnd = dmin(r__1,r__2);
00404                 } else {
00405 
00406 /*                 M(j) could overflow, set XBND to 0. */
00407 
00408                     xbnd = 0.f;
00409                 }
00410 
00411                 if (tjj + cnorm[j] >= smlnum) {
00412 
00413 /*                 G(j) = G(j-1)*( 1 + CNORM(j) / abs(A(j,j)) ) */
00414 
00415                     grow *= tjj / (tjj + cnorm[j]);
00416                 } else {
00417 
00418 /*                 G(j) could overflow, set GROW to 0. */
00419 
00420                     grow = 0.f;
00421                 }
00422                 ip += jinc * jlen;
00423                 --jlen;
00424 /* L40: */
00425             }
00426             grow = xbnd;
00427         } else {
00428 
00429 /*           A is unit triangular. */
00430 
00431 /*           Compute GROW = 1/G(j), where G(0) = max{x(i), i=1,...,n}. */
00432 
00433 /* Computing MIN */
00434             r__1 = 1.f, r__2 = .5f / dmax(xbnd,smlnum);
00435             grow = dmin(r__1,r__2);
00436             i__2 = jlast;
00437             i__1 = jinc;
00438             for (j = jfirst; i__1 < 0 ? j >= i__2 : j <= i__2; j += i__1) {
00439 
00440 /*              Exit the loop if the growth factor is too small. */
00441 
00442                 if (grow <= smlnum) {
00443                     goto L60;
00444                 }
00445 
00446 /*              G(j) = G(j-1)*( 1 + CNORM(j) ) */
00447 
00448                 grow *= 1.f / (cnorm[j] + 1.f);
00449 /* L50: */
00450             }
00451         }
00452 L60:
00453 
00454         ;
00455     } else {
00456 
00457 /*        Compute the growth in A**T * x = b  or  A**H * x = b. */
00458 
00459         if (upper) {
00460             jfirst = 1;
00461             jlast = *n;
00462             jinc = 1;
00463         } else {
00464             jfirst = *n;
00465             jlast = 1;
00466             jinc = -1;
00467         }
00468 
00469         if (tscal != 1.f) {
00470             grow = 0.f;
00471             goto L90;
00472         }
00473 
00474         if (nounit) {
00475 
00476 /*           A is non-unit triangular. */
00477 
00478 /*           Compute GROW = 1/G(j) and XBND = 1/M(j). */
00479 /*           Initially, M(0) = max{x(i), i=1,...,n}. */
00480 
00481             grow = .5f / dmax(xbnd,smlnum);
00482             xbnd = grow;
00483             ip = jfirst * (jfirst + 1) / 2;
00484             jlen = 1;
00485             i__1 = jlast;
00486             i__2 = jinc;
00487             for (j = jfirst; i__2 < 0 ? j >= i__1 : j <= i__1; j += i__2) {
00488 
00489 /*              Exit the loop if the growth factor is too small. */
00490 
00491                 if (grow <= smlnum) {
00492                     goto L90;
00493                 }
00494 
00495 /*              G(j) = max( G(j-1), M(j-1)*( 1 + CNORM(j) ) ) */
00496 
00497                 xj = cnorm[j] + 1.f;
00498 /* Computing MIN */
00499                 r__1 = grow, r__2 = xbnd / xj;
00500                 grow = dmin(r__1,r__2);
00501 
00502                 i__3 = ip;
00503                 tjjs.r = ap[i__3].r, tjjs.i = ap[i__3].i;
00504                 tjj = (r__1 = tjjs.r, dabs(r__1)) + (r__2 = r_imag(&tjjs), 
00505                         dabs(r__2));
00506 
00507                 if (tjj >= smlnum) {
00508 
00509 /*                 M(j) = M(j-1)*( 1 + CNORM(j) ) / abs(A(j,j)) */
00510 
00511                     if (xj > tjj) {
00512                         xbnd *= tjj / xj;
00513                     }
00514                 } else {
00515 
00516 /*                 M(j) could overflow, set XBND to 0. */
00517 
00518                     xbnd = 0.f;
00519                 }
00520                 ++jlen;
00521                 ip += jinc * jlen;
00522 /* L70: */
00523             }
00524             grow = dmin(grow,xbnd);
00525         } else {
00526 
00527 /*           A is unit triangular. */
00528 
00529 /*           Compute GROW = 1/G(j), where G(0) = max{x(i), i=1,...,n}. */
00530 
00531 /* Computing MIN */
00532             r__1 = 1.f, r__2 = .5f / dmax(xbnd,smlnum);
00533             grow = dmin(r__1,r__2);
00534             i__2 = jlast;
00535             i__1 = jinc;
00536             for (j = jfirst; i__1 < 0 ? j >= i__2 : j <= i__2; j += i__1) {
00537 
00538 /*              Exit the loop if the growth factor is too small. */
00539 
00540                 if (grow <= smlnum) {
00541                     goto L90;
00542                 }
00543 
00544 /*              G(j) = ( 1 + CNORM(j) )*G(j-1) */
00545 
00546                 xj = cnorm[j] + 1.f;
00547                 grow /= xj;
00548 /* L80: */
00549             }
00550         }
00551 L90:
00552         ;
00553     }
00554 
00555     if (grow * tscal > smlnum) {
00556 
00557 /*        Use the Level 2 BLAS solve if the reciprocal of the bound on */
00558 /*        elements of X is not too small. */
00559 
00560         ctpsv_(uplo, trans, diag, n, &ap[1], &x[1], &c__1);
00561     } else {
00562 
00563 /*        Use a Level 1 BLAS solve, scaling intermediate results. */
00564 
00565         if (xmax > bignum * .5f) {
00566 
00567 /*           Scale X so that its components are less than or equal to */
00568 /*           BIGNUM in absolute value. */
00569 
00570             *scale = bignum * .5f / xmax;
00571             csscal_(n, scale, &x[1], &c__1);
00572             xmax = bignum;
00573         } else {
00574             xmax *= 2.f;
00575         }
00576 
00577         if (notran) {
00578 
00579 /*           Solve A * x = b */
00580 
00581             ip = jfirst * (jfirst + 1) / 2;
00582             i__1 = jlast;
00583             i__2 = jinc;
00584             for (j = jfirst; i__2 < 0 ? j >= i__1 : j <= i__1; j += i__2) {
00585 
00586 /*              Compute x(j) = b(j) / A(j,j), scaling x if necessary. */
00587 
00588                 i__3 = j;
00589                 xj = (r__1 = x[i__3].r, dabs(r__1)) + (r__2 = r_imag(&x[j]), 
00590                         dabs(r__2));
00591                 if (nounit) {
00592                     i__3 = ip;
00593                     q__1.r = tscal * ap[i__3].r, q__1.i = tscal * ap[i__3].i;
00594                     tjjs.r = q__1.r, tjjs.i = q__1.i;
00595                 } else {
00596                     tjjs.r = tscal, tjjs.i = 0.f;
00597                     if (tscal == 1.f) {
00598                         goto L105;
00599                     }
00600                 }
00601                 tjj = (r__1 = tjjs.r, dabs(r__1)) + (r__2 = r_imag(&tjjs), 
00602                         dabs(r__2));
00603                 if (tjj > smlnum) {
00604 
00605 /*                    abs(A(j,j)) > SMLNUM: */
00606 
00607                     if (tjj < 1.f) {
00608                         if (xj > tjj * bignum) {
00609 
00610 /*                          Scale x by 1/b(j). */
00611 
00612                             rec = 1.f / xj;
00613                             csscal_(n, &rec, &x[1], &c__1);
00614                             *scale *= rec;
00615                             xmax *= rec;
00616                         }
00617                     }
00618                     i__3 = j;
00619                     cladiv_(&q__1, &x[j], &tjjs);
00620                     x[i__3].r = q__1.r, x[i__3].i = q__1.i;
00621                     i__3 = j;
00622                     xj = (r__1 = x[i__3].r, dabs(r__1)) + (r__2 = r_imag(&x[j]
00623                             ), dabs(r__2));
00624                 } else if (tjj > 0.f) {
00625 
00626 /*                    0 < abs(A(j,j)) <= SMLNUM: */
00627 
00628                     if (xj > tjj * bignum) {
00629 
00630 /*                       Scale x by (1/abs(x(j)))*abs(A(j,j))*BIGNUM */
00631 /*                       to avoid overflow when dividing by A(j,j). */
00632 
00633                         rec = tjj * bignum / xj;
00634                         if (cnorm[j] > 1.f) {
00635 
00636 /*                          Scale by 1/CNORM(j) to avoid overflow when */
00637 /*                          multiplying x(j) times column j. */
00638 
00639                             rec /= cnorm[j];
00640                         }
00641                         csscal_(n, &rec, &x[1], &c__1);
00642                         *scale *= rec;
00643                         xmax *= rec;
00644                     }
00645                     i__3 = j;
00646                     cladiv_(&q__1, &x[j], &tjjs);
00647                     x[i__3].r = q__1.r, x[i__3].i = q__1.i;
00648                     i__3 = j;
00649                     xj = (r__1 = x[i__3].r, dabs(r__1)) + (r__2 = r_imag(&x[j]
00650                             ), dabs(r__2));
00651                 } else {
00652 
00653 /*                    A(j,j) = 0:  Set x(1:n) = 0, x(j) = 1, and */
00654 /*                    scale = 0, and compute a solution to A*x = 0. */
00655 
00656                     i__3 = *n;
00657                     for (i__ = 1; i__ <= i__3; ++i__) {
00658                         i__4 = i__;
00659                         x[i__4].r = 0.f, x[i__4].i = 0.f;
00660 /* L100: */
00661                     }
00662                     i__3 = j;
00663                     x[i__3].r = 1.f, x[i__3].i = 0.f;
00664                     xj = 1.f;
00665                     *scale = 0.f;
00666                     xmax = 0.f;
00667                 }
00668 L105:
00669 
00670 /*              Scale x if necessary to avoid overflow when adding a */
00671 /*              multiple of column j of A. */
00672 
00673                 if (xj > 1.f) {
00674                     rec = 1.f / xj;
00675                     if (cnorm[j] > (bignum - xmax) * rec) {
00676 
00677 /*                    Scale x by 1/(2*abs(x(j))). */
00678 
00679                         rec *= .5f;
00680                         csscal_(n, &rec, &x[1], &c__1);
00681                         *scale *= rec;
00682                     }
00683                 } else if (xj * cnorm[j] > bignum - xmax) {
00684 
00685 /*                 Scale x by 1/2. */
00686 
00687                     csscal_(n, &c_b36, &x[1], &c__1);
00688                     *scale *= .5f;
00689                 }
00690 
00691                 if (upper) {
00692                     if (j > 1) {
00693 
00694 /*                    Compute the update */
00695 /*                       x(1:j-1) := x(1:j-1) - x(j) * A(1:j-1,j) */
00696 
00697                         i__3 = j - 1;
00698                         i__4 = j;
00699                         q__2.r = -x[i__4].r, q__2.i = -x[i__4].i;
00700                         q__1.r = tscal * q__2.r, q__1.i = tscal * q__2.i;
00701                         caxpy_(&i__3, &q__1, &ap[ip - j + 1], &c__1, &x[1], &
00702                                 c__1);
00703                         i__3 = j - 1;
00704                         i__ = icamax_(&i__3, &x[1], &c__1);
00705                         i__3 = i__;
00706                         xmax = (r__1 = x[i__3].r, dabs(r__1)) + (r__2 = 
00707                                 r_imag(&x[i__]), dabs(r__2));
00708                     }
00709                     ip -= j;
00710                 } else {
00711                     if (j < *n) {
00712 
00713 /*                    Compute the update */
00714 /*                       x(j+1:n) := x(j+1:n) - x(j) * A(j+1:n,j) */
00715 
00716                         i__3 = *n - j;
00717                         i__4 = j;
00718                         q__2.r = -x[i__4].r, q__2.i = -x[i__4].i;
00719                         q__1.r = tscal * q__2.r, q__1.i = tscal * q__2.i;
00720                         caxpy_(&i__3, &q__1, &ap[ip + 1], &c__1, &x[j + 1], &
00721                                 c__1);
00722                         i__3 = *n - j;
00723                         i__ = j + icamax_(&i__3, &x[j + 1], &c__1);
00724                         i__3 = i__;
00725                         xmax = (r__1 = x[i__3].r, dabs(r__1)) + (r__2 = 
00726                                 r_imag(&x[i__]), dabs(r__2));
00727                     }
00728                     ip = ip + *n - j + 1;
00729                 }
00730 /* L110: */
00731             }
00732 
00733         } else if (lsame_(trans, "T")) {
00734 
00735 /*           Solve A**T * x = b */
00736 
00737             ip = jfirst * (jfirst + 1) / 2;
00738             jlen = 1;
00739             i__2 = jlast;
00740             i__1 = jinc;
00741             for (j = jfirst; i__1 < 0 ? j >= i__2 : j <= i__2; j += i__1) {
00742 
00743 /*              Compute x(j) = b(j) - sum A(k,j)*x(k). */
00744 /*                                    k<>j */
00745 
00746                 i__3 = j;
00747                 xj = (r__1 = x[i__3].r, dabs(r__1)) + (r__2 = r_imag(&x[j]), 
00748                         dabs(r__2));
00749                 uscal.r = tscal, uscal.i = 0.f;
00750                 rec = 1.f / dmax(xmax,1.f);
00751                 if (cnorm[j] > (bignum - xj) * rec) {
00752 
00753 /*                 If x(j) could overflow, scale x by 1/(2*XMAX). */
00754 
00755                     rec *= .5f;
00756                     if (nounit) {
00757                         i__3 = ip;
00758                         q__1.r = tscal * ap[i__3].r, q__1.i = tscal * ap[i__3]
00759                                 .i;
00760                         tjjs.r = q__1.r, tjjs.i = q__1.i;
00761                     } else {
00762                         tjjs.r = tscal, tjjs.i = 0.f;
00763                     }
00764                     tjj = (r__1 = tjjs.r, dabs(r__1)) + (r__2 = r_imag(&tjjs),
00765                              dabs(r__2));
00766                     if (tjj > 1.f) {
00767 
00768 /*                       Divide by A(j,j) when scaling x if A(j,j) > 1. */
00769 
00770 /* Computing MIN */
00771                         r__1 = 1.f, r__2 = rec * tjj;
00772                         rec = dmin(r__1,r__2);
00773                         cladiv_(&q__1, &uscal, &tjjs);
00774                         uscal.r = q__1.r, uscal.i = q__1.i;
00775                     }
00776                     if (rec < 1.f) {
00777                         csscal_(n, &rec, &x[1], &c__1);
00778                         *scale *= rec;
00779                         xmax *= rec;
00780                     }
00781                 }
00782 
00783                 csumj.r = 0.f, csumj.i = 0.f;
00784                 if (uscal.r == 1.f && uscal.i == 0.f) {
00785 
00786 /*                 If the scaling needed for A in the dot product is 1, */
00787 /*                 call CDOTU to perform the dot product. */
00788 
00789                     if (upper) {
00790                         i__3 = j - 1;
00791                         cdotu_(&q__1, &i__3, &ap[ip - j + 1], &c__1, &x[1], &
00792                                 c__1);
00793                         csumj.r = q__1.r, csumj.i = q__1.i;
00794                     } else if (j < *n) {
00795                         i__3 = *n - j;
00796                         cdotu_(&q__1, &i__3, &ap[ip + 1], &c__1, &x[j + 1], &
00797                                 c__1);
00798                         csumj.r = q__1.r, csumj.i = q__1.i;
00799                     }
00800                 } else {
00801 
00802 /*                 Otherwise, use in-line code for the dot product. */
00803 
00804                     if (upper) {
00805                         i__3 = j - 1;
00806                         for (i__ = 1; i__ <= i__3; ++i__) {
00807                             i__4 = ip - j + i__;
00808                             q__3.r = ap[i__4].r * uscal.r - ap[i__4].i * 
00809                                     uscal.i, q__3.i = ap[i__4].r * uscal.i + 
00810                                     ap[i__4].i * uscal.r;
00811                             i__5 = i__;
00812                             q__2.r = q__3.r * x[i__5].r - q__3.i * x[i__5].i, 
00813                                     q__2.i = q__3.r * x[i__5].i + q__3.i * x[
00814                                     i__5].r;
00815                             q__1.r = csumj.r + q__2.r, q__1.i = csumj.i + 
00816                                     q__2.i;
00817                             csumj.r = q__1.r, csumj.i = q__1.i;
00818 /* L120: */
00819                         }
00820                     } else if (j < *n) {
00821                         i__3 = *n - j;
00822                         for (i__ = 1; i__ <= i__3; ++i__) {
00823                             i__4 = ip + i__;
00824                             q__3.r = ap[i__4].r * uscal.r - ap[i__4].i * 
00825                                     uscal.i, q__3.i = ap[i__4].r * uscal.i + 
00826                                     ap[i__4].i * uscal.r;
00827                             i__5 = j + i__;
00828                             q__2.r = q__3.r * x[i__5].r - q__3.i * x[i__5].i, 
00829                                     q__2.i = q__3.r * x[i__5].i + q__3.i * x[
00830                                     i__5].r;
00831                             q__1.r = csumj.r + q__2.r, q__1.i = csumj.i + 
00832                                     q__2.i;
00833                             csumj.r = q__1.r, csumj.i = q__1.i;
00834 /* L130: */
00835                         }
00836                     }
00837                 }
00838 
00839                 q__1.r = tscal, q__1.i = 0.f;
00840                 if (uscal.r == q__1.r && uscal.i == q__1.i) {
00841 
00842 /*                 Compute x(j) := ( x(j) - CSUMJ ) / A(j,j) if 1/A(j,j) */
00843 /*                 was not used to scale the dotproduct. */
00844 
00845                     i__3 = j;
00846                     i__4 = j;
00847                     q__1.r = x[i__4].r - csumj.r, q__1.i = x[i__4].i - 
00848                             csumj.i;
00849                     x[i__3].r = q__1.r, x[i__3].i = q__1.i;
00850                     i__3 = j;
00851                     xj = (r__1 = x[i__3].r, dabs(r__1)) + (r__2 = r_imag(&x[j]
00852                             ), dabs(r__2));
00853                     if (nounit) {
00854 
00855 /*                    Compute x(j) = x(j) / A(j,j), scaling if necessary. */
00856 
00857                         i__3 = ip;
00858                         q__1.r = tscal * ap[i__3].r, q__1.i = tscal * ap[i__3]
00859                                 .i;
00860                         tjjs.r = q__1.r, tjjs.i = q__1.i;
00861                     } else {
00862                         tjjs.r = tscal, tjjs.i = 0.f;
00863                         if (tscal == 1.f) {
00864                             goto L145;
00865                         }
00866                     }
00867                     tjj = (r__1 = tjjs.r, dabs(r__1)) + (r__2 = r_imag(&tjjs),
00868                              dabs(r__2));
00869                     if (tjj > smlnum) {
00870 
00871 /*                       abs(A(j,j)) > SMLNUM: */
00872 
00873                         if (tjj < 1.f) {
00874                             if (xj > tjj * bignum) {
00875 
00876 /*                             Scale X by 1/abs(x(j)). */
00877 
00878                                 rec = 1.f / xj;
00879                                 csscal_(n, &rec, &x[1], &c__1);
00880                                 *scale *= rec;
00881                                 xmax *= rec;
00882                             }
00883                         }
00884                         i__3 = j;
00885                         cladiv_(&q__1, &x[j], &tjjs);
00886                         x[i__3].r = q__1.r, x[i__3].i = q__1.i;
00887                     } else if (tjj > 0.f) {
00888 
00889 /*                       0 < abs(A(j,j)) <= SMLNUM: */
00890 
00891                         if (xj > tjj * bignum) {
00892 
00893 /*                          Scale x by (1/abs(x(j)))*abs(A(j,j))*BIGNUM. */
00894 
00895                             rec = tjj * bignum / xj;
00896                             csscal_(n, &rec, &x[1], &c__1);
00897                             *scale *= rec;
00898                             xmax *= rec;
00899                         }
00900                         i__3 = j;
00901                         cladiv_(&q__1, &x[j], &tjjs);
00902                         x[i__3].r = q__1.r, x[i__3].i = q__1.i;
00903                     } else {
00904 
00905 /*                       A(j,j) = 0:  Set x(1:n) = 0, x(j) = 1, and */
00906 /*                       scale = 0 and compute a solution to A**T *x = 0. */
00907 
00908                         i__3 = *n;
00909                         for (i__ = 1; i__ <= i__3; ++i__) {
00910                             i__4 = i__;
00911                             x[i__4].r = 0.f, x[i__4].i = 0.f;
00912 /* L140: */
00913                         }
00914                         i__3 = j;
00915                         x[i__3].r = 1.f, x[i__3].i = 0.f;
00916                         *scale = 0.f;
00917                         xmax = 0.f;
00918                     }
00919 L145:
00920                     ;
00921                 } else {
00922 
00923 /*                 Compute x(j) := x(j) / A(j,j) - CSUMJ if the dot */
00924 /*                 product has already been divided by 1/A(j,j). */
00925 
00926                     i__3 = j;
00927                     cladiv_(&q__2, &x[j], &tjjs);
00928                     q__1.r = q__2.r - csumj.r, q__1.i = q__2.i - csumj.i;
00929                     x[i__3].r = q__1.r, x[i__3].i = q__1.i;
00930                 }
00931 /* Computing MAX */
00932                 i__3 = j;
00933                 r__3 = xmax, r__4 = (r__1 = x[i__3].r, dabs(r__1)) + (r__2 = 
00934                         r_imag(&x[j]), dabs(r__2));
00935                 xmax = dmax(r__3,r__4);
00936                 ++jlen;
00937                 ip += jinc * jlen;
00938 /* L150: */
00939             }
00940 
00941         } else {
00942 
00943 /*           Solve A**H * x = b */
00944 
00945             ip = jfirst * (jfirst + 1) / 2;
00946             jlen = 1;
00947             i__1 = jlast;
00948             i__2 = jinc;
00949             for (j = jfirst; i__2 < 0 ? j >= i__1 : j <= i__1; j += i__2) {
00950 
00951 /*              Compute x(j) = b(j) - sum A(k,j)*x(k). */
00952 /*                                    k<>j */
00953 
00954                 i__3 = j;
00955                 xj = (r__1 = x[i__3].r, dabs(r__1)) + (r__2 = r_imag(&x[j]), 
00956                         dabs(r__2));
00957                 uscal.r = tscal, uscal.i = 0.f;
00958                 rec = 1.f / dmax(xmax,1.f);
00959                 if (cnorm[j] > (bignum - xj) * rec) {
00960 
00961 /*                 If x(j) could overflow, scale x by 1/(2*XMAX). */
00962 
00963                     rec *= .5f;
00964                     if (nounit) {
00965                         r_cnjg(&q__2, &ap[ip]);
00966                         q__1.r = tscal * q__2.r, q__1.i = tscal * q__2.i;
00967                         tjjs.r = q__1.r, tjjs.i = q__1.i;
00968                     } else {
00969                         tjjs.r = tscal, tjjs.i = 0.f;
00970                     }
00971                     tjj = (r__1 = tjjs.r, dabs(r__1)) + (r__2 = r_imag(&tjjs),
00972                              dabs(r__2));
00973                     if (tjj > 1.f) {
00974 
00975 /*                       Divide by A(j,j) when scaling x if A(j,j) > 1. */
00976 
00977 /* Computing MIN */
00978                         r__1 = 1.f, r__2 = rec * tjj;
00979                         rec = dmin(r__1,r__2);
00980                         cladiv_(&q__1, &uscal, &tjjs);
00981                         uscal.r = q__1.r, uscal.i = q__1.i;
00982                     }
00983                     if (rec < 1.f) {
00984                         csscal_(n, &rec, &x[1], &c__1);
00985                         *scale *= rec;
00986                         xmax *= rec;
00987                     }
00988                 }
00989 
00990                 csumj.r = 0.f, csumj.i = 0.f;
00991                 if (uscal.r == 1.f && uscal.i == 0.f) {
00992 
00993 /*                 If the scaling needed for A in the dot product is 1, */
00994 /*                 call CDOTC to perform the dot product. */
00995 
00996                     if (upper) {
00997                         i__3 = j - 1;
00998                         cdotc_(&q__1, &i__3, &ap[ip - j + 1], &c__1, &x[1], &
00999                                 c__1);
01000                         csumj.r = q__1.r, csumj.i = q__1.i;
01001                     } else if (j < *n) {
01002                         i__3 = *n - j;
01003                         cdotc_(&q__1, &i__3, &ap[ip + 1], &c__1, &x[j + 1], &
01004                                 c__1);
01005                         csumj.r = q__1.r, csumj.i = q__1.i;
01006                     }
01007                 } else {
01008 
01009 /*                 Otherwise, use in-line code for the dot product. */
01010 
01011                     if (upper) {
01012                         i__3 = j - 1;
01013                         for (i__ = 1; i__ <= i__3; ++i__) {
01014                             r_cnjg(&q__4, &ap[ip - j + i__]);
01015                             q__3.r = q__4.r * uscal.r - q__4.i * uscal.i, 
01016                                     q__3.i = q__4.r * uscal.i + q__4.i * 
01017                                     uscal.r;
01018                             i__4 = i__;
01019                             q__2.r = q__3.r * x[i__4].r - q__3.i * x[i__4].i, 
01020                                     q__2.i = q__3.r * x[i__4].i + q__3.i * x[
01021                                     i__4].r;
01022                             q__1.r = csumj.r + q__2.r, q__1.i = csumj.i + 
01023                                     q__2.i;
01024                             csumj.r = q__1.r, csumj.i = q__1.i;
01025 /* L160: */
01026                         }
01027                     } else if (j < *n) {
01028                         i__3 = *n - j;
01029                         for (i__ = 1; i__ <= i__3; ++i__) {
01030                             r_cnjg(&q__4, &ap[ip + i__]);
01031                             q__3.r = q__4.r * uscal.r - q__4.i * uscal.i, 
01032                                     q__3.i = q__4.r * uscal.i + q__4.i * 
01033                                     uscal.r;
01034                             i__4 = j + i__;
01035                             q__2.r = q__3.r * x[i__4].r - q__3.i * x[i__4].i, 
01036                                     q__2.i = q__3.r * x[i__4].i + q__3.i * x[
01037                                     i__4].r;
01038                             q__1.r = csumj.r + q__2.r, q__1.i = csumj.i + 
01039                                     q__2.i;
01040                             csumj.r = q__1.r, csumj.i = q__1.i;
01041 /* L170: */
01042                         }
01043                     }
01044                 }
01045 
01046                 q__1.r = tscal, q__1.i = 0.f;
01047                 if (uscal.r == q__1.r && uscal.i == q__1.i) {
01048 
01049 /*                 Compute x(j) := ( x(j) - CSUMJ ) / A(j,j) if 1/A(j,j) */
01050 /*                 was not used to scale the dotproduct. */
01051 
01052                     i__3 = j;
01053                     i__4 = j;
01054                     q__1.r = x[i__4].r - csumj.r, q__1.i = x[i__4].i - 
01055                             csumj.i;
01056                     x[i__3].r = q__1.r, x[i__3].i = q__1.i;
01057                     i__3 = j;
01058                     xj = (r__1 = x[i__3].r, dabs(r__1)) + (r__2 = r_imag(&x[j]
01059                             ), dabs(r__2));
01060                     if (nounit) {
01061 
01062 /*                    Compute x(j) = x(j) / A(j,j), scaling if necessary. */
01063 
01064                         r_cnjg(&q__2, &ap[ip]);
01065                         q__1.r = tscal * q__2.r, q__1.i = tscal * q__2.i;
01066                         tjjs.r = q__1.r, tjjs.i = q__1.i;
01067                     } else {
01068                         tjjs.r = tscal, tjjs.i = 0.f;
01069                         if (tscal == 1.f) {
01070                             goto L185;
01071                         }
01072                     }
01073                     tjj = (r__1 = tjjs.r, dabs(r__1)) + (r__2 = r_imag(&tjjs),
01074                              dabs(r__2));
01075                     if (tjj > smlnum) {
01076 
01077 /*                       abs(A(j,j)) > SMLNUM: */
01078 
01079                         if (tjj < 1.f) {
01080                             if (xj > tjj * bignum) {
01081 
01082 /*                             Scale X by 1/abs(x(j)). */
01083 
01084                                 rec = 1.f / xj;
01085                                 csscal_(n, &rec, &x[1], &c__1);
01086                                 *scale *= rec;
01087                                 xmax *= rec;
01088                             }
01089                         }
01090                         i__3 = j;
01091                         cladiv_(&q__1, &x[j], &tjjs);
01092                         x[i__3].r = q__1.r, x[i__3].i = q__1.i;
01093                     } else if (tjj > 0.f) {
01094 
01095 /*                       0 < abs(A(j,j)) <= SMLNUM: */
01096 
01097                         if (xj > tjj * bignum) {
01098 
01099 /*                          Scale x by (1/abs(x(j)))*abs(A(j,j))*BIGNUM. */
01100 
01101                             rec = tjj * bignum / xj;
01102                             csscal_(n, &rec, &x[1], &c__1);
01103                             *scale *= rec;
01104                             xmax *= rec;
01105                         }
01106                         i__3 = j;
01107                         cladiv_(&q__1, &x[j], &tjjs);
01108                         x[i__3].r = q__1.r, x[i__3].i = q__1.i;
01109                     } else {
01110 
01111 /*                       A(j,j) = 0:  Set x(1:n) = 0, x(j) = 1, and */
01112 /*                       scale = 0 and compute a solution to A**H *x = 0. */
01113 
01114                         i__3 = *n;
01115                         for (i__ = 1; i__ <= i__3; ++i__) {
01116                             i__4 = i__;
01117                             x[i__4].r = 0.f, x[i__4].i = 0.f;
01118 /* L180: */
01119                         }
01120                         i__3 = j;
01121                         x[i__3].r = 1.f, x[i__3].i = 0.f;
01122                         *scale = 0.f;
01123                         xmax = 0.f;
01124                     }
01125 L185:
01126                     ;
01127                 } else {
01128 
01129 /*                 Compute x(j) := x(j) / A(j,j) - CSUMJ if the dot */
01130 /*                 product has already been divided by 1/A(j,j). */
01131 
01132                     i__3 = j;
01133                     cladiv_(&q__2, &x[j], &tjjs);
01134                     q__1.r = q__2.r - csumj.r, q__1.i = q__2.i - csumj.i;
01135                     x[i__3].r = q__1.r, x[i__3].i = q__1.i;
01136                 }
01137 /* Computing MAX */
01138                 i__3 = j;
01139                 r__3 = xmax, r__4 = (r__1 = x[i__3].r, dabs(r__1)) + (r__2 = 
01140                         r_imag(&x[j]), dabs(r__2));
01141                 xmax = dmax(r__3,r__4);
01142                 ++jlen;
01143                 ip += jinc * jlen;
01144 /* L190: */
01145             }
01146         }
01147         *scale /= tscal;
01148     }
01149 
01150 /*     Scale the column norms by 1/TSCAL for return. */
01151 
01152     if (tscal != 1.f) {
01153         r__1 = 1.f / tscal;
01154         sscal_(n, &r__1, &cnorm[1], &c__1);
01155     }
01156 
01157     return 0;
01158 
01159 /*     End of CLATPS */
01160 
01161 } /* clatps_ */


swiftnav
Author(s):
autogenerated on Sat Jun 8 2019 18:55:32