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


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