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


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