Annotation of rpl/lapack/lapack/zlatps.f, revision 1.1
1.1 ! bertrand 1: SUBROUTINE ZLATPS( UPLO, TRANS, DIAG, NORMIN, N, AP, X, SCALE,
! 2: $ CNORM, INFO )
! 3: *
! 4: * -- LAPACK auxiliary routine (version 3.2) --
! 5: * -- LAPACK is a software package provided by Univ. of Tennessee, --
! 6: * -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..--
! 7: * November 2006
! 8: *
! 9: * .. Scalar Arguments ..
! 10: CHARACTER DIAG, NORMIN, TRANS, UPLO
! 11: INTEGER INFO, N
! 12: DOUBLE PRECISION SCALE
! 13: * ..
! 14: * .. Array Arguments ..
! 15: DOUBLE PRECISION CNORM( * )
! 16: COMPLEX*16 AP( * ), X( * )
! 17: * ..
! 18: *
! 19: * Purpose
! 20: * =======
! 21: *
! 22: * ZLATPS solves one of the triangular systems
! 23: *
! 24: * A * x = s*b, A**T * x = s*b, or A**H * x = s*b,
! 25: *
! 26: * with scaling to prevent overflow, where A is an upper or lower
! 27: * triangular matrix stored in packed form. Here A**T denotes the
! 28: * transpose of A, A**H denotes the conjugate transpose of A, x and b
! 29: * are n-element vectors, and s is a scaling factor, usually less than
! 30: * or equal to 1, chosen so that the components of x will be less than
! 31: * the overflow threshold. If the unscaled problem will not cause
! 32: * overflow, the Level 2 BLAS routine ZTPSV is called. If the matrix A
! 33: * is singular (A(j,j) = 0 for some j), then s is set to 0 and a
! 34: * non-trivial solution to A*x = 0 is returned.
! 35: *
! 36: * Arguments
! 37: * =========
! 38: *
! 39: * UPLO (input) CHARACTER*1
! 40: * Specifies whether the matrix A is upper or lower triangular.
! 41: * = 'U': Upper triangular
! 42: * = 'L': Lower triangular
! 43: *
! 44: * TRANS (input) CHARACTER*1
! 45: * Specifies the operation applied to A.
! 46: * = 'N': Solve A * x = s*b (No transpose)
! 47: * = 'T': Solve A**T * x = s*b (Transpose)
! 48: * = 'C': Solve A**H * x = s*b (Conjugate transpose)
! 49: *
! 50: * DIAG (input) CHARACTER*1
! 51: * Specifies whether or not the matrix A is unit triangular.
! 52: * = 'N': Non-unit triangular
! 53: * = 'U': Unit triangular
! 54: *
! 55: * NORMIN (input) CHARACTER*1
! 56: * Specifies whether CNORM has been set or not.
! 57: * = 'Y': CNORM contains the column norms on entry
! 58: * = 'N': CNORM is not set on entry. On exit, the norms will
! 59: * be computed and stored in CNORM.
! 60: *
! 61: * N (input) INTEGER
! 62: * The order of the matrix A. N >= 0.
! 63: *
! 64: * AP (input) COMPLEX*16 array, dimension (N*(N+1)/2)
! 65: * The upper or lower triangular matrix A, packed columnwise in
! 66: * a linear array. The j-th column of A is stored in the array
! 67: * AP as follows:
! 68: * if UPLO = 'U', AP(i + (j-1)*j/2) = A(i,j) for 1<=i<=j;
! 69: * if UPLO = 'L', AP(i + (j-1)*(2n-j)/2) = A(i,j) for j<=i<=n.
! 70: *
! 71: * X (input/output) COMPLEX*16 array, dimension (N)
! 72: * On entry, the right hand side b of the triangular system.
! 73: * On exit, X is overwritten by the solution vector x.
! 74: *
! 75: * SCALE (output) DOUBLE PRECISION
! 76: * The scaling factor s for the triangular system
! 77: * A * x = s*b, A**T * x = s*b, or A**H * x = s*b.
! 78: * If SCALE = 0, the matrix A is singular or badly scaled, and
! 79: * the vector x is an exact or approximate solution to A*x = 0.
! 80: *
! 81: * CNORM (input or output) DOUBLE PRECISION array, dimension (N)
! 82: *
! 83: * If NORMIN = 'Y', CNORM is an input argument and CNORM(j)
! 84: * contains the norm of the off-diagonal part of the j-th column
! 85: * of A. If TRANS = 'N', CNORM(j) must be greater than or equal
! 86: * to the infinity-norm, and if TRANS = 'T' or 'C', CNORM(j)
! 87: * must be greater than or equal to the 1-norm.
! 88: *
! 89: * If NORMIN = 'N', CNORM is an output argument and CNORM(j)
! 90: * returns the 1-norm of the offdiagonal part of the j-th column
! 91: * of A.
! 92: *
! 93: * INFO (output) INTEGER
! 94: * = 0: successful exit
! 95: * < 0: if INFO = -k, the k-th argument had an illegal value
! 96: *
! 97: * Further Details
! 98: * ======= =======
! 99: *
! 100: * A rough bound on x is computed; if that is less than overflow, ZTPSV
! 101: * is called, otherwise, specific code is used which checks for possible
! 102: * overflow or divide-by-zero at every operation.
! 103: *
! 104: * A columnwise scheme is used for solving A*x = b. The basic algorithm
! 105: * if A is lower triangular is
! 106: *
! 107: * x[1:n] := b[1:n]
! 108: * for j = 1, ..., n
! 109: * x(j) := x(j) / A(j,j)
! 110: * x[j+1:n] := x[j+1:n] - x(j) * A[j+1:n,j]
! 111: * end
! 112: *
! 113: * Define bounds on the components of x after j iterations of the loop:
! 114: * M(j) = bound on x[1:j]
! 115: * G(j) = bound on x[j+1:n]
! 116: * Initially, let M(0) = 0 and G(0) = max{x(i), i=1,...,n}.
! 117: *
! 118: * Then for iteration j+1 we have
! 119: * M(j+1) <= G(j) / | A(j+1,j+1) |
! 120: * G(j+1) <= G(j) + M(j+1) * | A[j+2:n,j+1] |
! 121: * <= G(j) ( 1 + CNORM(j+1) / | A(j+1,j+1) | )
! 122: *
! 123: * where CNORM(j+1) is greater than or equal to the infinity-norm of
! 124: * column j+1 of A, not counting the diagonal. Hence
! 125: *
! 126: * G(j) <= G(0) product ( 1 + CNORM(i) / | A(i,i) | )
! 127: * 1<=i<=j
! 128: * and
! 129: *
! 130: * |x(j)| <= ( G(0) / |A(j,j)| ) product ( 1 + CNORM(i) / |A(i,i)| )
! 131: * 1<=i< j
! 132: *
! 133: * Since |x(j)| <= M(j), we use the Level 2 BLAS routine ZTPSV if the
! 134: * reciprocal of the largest M(j), j=1,..,n, is larger than
! 135: * max(underflow, 1/overflow).
! 136: *
! 137: * The bound on x(j) is also used to determine when a step in the
! 138: * columnwise method can be performed without fear of overflow. If
! 139: * the computed bound is greater than a large constant, x is scaled to
! 140: * prevent overflow, but if the bound overflows, x is set to 0, x(j) to
! 141: * 1, and scale to 0, and a non-trivial solution to A*x = 0 is found.
! 142: *
! 143: * Similarly, a row-wise scheme is used to solve A**T *x = b or
! 144: * A**H *x = b. The basic algorithm for A upper triangular is
! 145: *
! 146: * for j = 1, ..., n
! 147: * x(j) := ( b(j) - A[1:j-1,j]' * x[1:j-1] ) / A(j,j)
! 148: * end
! 149: *
! 150: * We simultaneously compute two bounds
! 151: * G(j) = bound on ( b(i) - A[1:i-1,i]' * x[1:i-1] ), 1<=i<=j
! 152: * M(j) = bound on x(i), 1<=i<=j
! 153: *
! 154: * The initial values are G(0) = 0, M(0) = max{b(i), i=1,..,n}, and we
! 155: * add the constraint G(j) >= G(j-1) and M(j) >= M(j-1) for j >= 1.
! 156: * Then the bound on x(j) is
! 157: *
! 158: * M(j) <= M(j-1) * ( 1 + CNORM(j) ) / | A(j,j) |
! 159: *
! 160: * <= M(0) * product ( ( 1 + CNORM(i) ) / |A(i,i)| )
! 161: * 1<=i<=j
! 162: *
! 163: * and we can safely call ZTPSV if 1/M(n) and 1/G(n) are both greater
! 164: * than max(underflow, 1/overflow).
! 165: *
! 166: * =====================================================================
! 167: *
! 168: * .. Parameters ..
! 169: DOUBLE PRECISION ZERO, HALF, ONE, TWO
! 170: PARAMETER ( ZERO = 0.0D+0, HALF = 0.5D+0, ONE = 1.0D+0,
! 171: $ TWO = 2.0D+0 )
! 172: * ..
! 173: * .. Local Scalars ..
! 174: LOGICAL NOTRAN, NOUNIT, UPPER
! 175: INTEGER I, IMAX, IP, J, JFIRST, JINC, JLAST, JLEN
! 176: DOUBLE PRECISION BIGNUM, GROW, REC, SMLNUM, TJJ, TMAX, TSCAL,
! 177: $ XBND, XJ, XMAX
! 178: COMPLEX*16 CSUMJ, TJJS, USCAL, ZDUM
! 179: * ..
! 180: * .. External Functions ..
! 181: LOGICAL LSAME
! 182: INTEGER IDAMAX, IZAMAX
! 183: DOUBLE PRECISION DLAMCH, DZASUM
! 184: COMPLEX*16 ZDOTC, ZDOTU, ZLADIV
! 185: EXTERNAL LSAME, IDAMAX, IZAMAX, DLAMCH, DZASUM, ZDOTC,
! 186: $ ZDOTU, ZLADIV
! 187: * ..
! 188: * .. External Subroutines ..
! 189: EXTERNAL DSCAL, XERBLA, ZAXPY, ZDSCAL, ZTPSV
! 190: * ..
! 191: * .. Intrinsic Functions ..
! 192: INTRINSIC ABS, DBLE, DCMPLX, DCONJG, DIMAG, MAX, MIN
! 193: * ..
! 194: * .. Statement Functions ..
! 195: DOUBLE PRECISION CABS1, CABS2
! 196: * ..
! 197: * .. Statement Function definitions ..
! 198: CABS1( ZDUM ) = ABS( DBLE( ZDUM ) ) + ABS( DIMAG( ZDUM ) )
! 199: CABS2( ZDUM ) = ABS( DBLE( ZDUM ) / 2.D0 ) +
! 200: $ ABS( DIMAG( ZDUM ) / 2.D0 )
! 201: * ..
! 202: * .. Executable Statements ..
! 203: *
! 204: INFO = 0
! 205: UPPER = LSAME( UPLO, 'U' )
! 206: NOTRAN = LSAME( TRANS, 'N' )
! 207: NOUNIT = LSAME( DIAG, 'N' )
! 208: *
! 209: * Test the input parameters.
! 210: *
! 211: IF( .NOT.UPPER .AND. .NOT.LSAME( UPLO, 'L' ) ) THEN
! 212: INFO = -1
! 213: ELSE IF( .NOT.NOTRAN .AND. .NOT.LSAME( TRANS, 'T' ) .AND. .NOT.
! 214: $ LSAME( TRANS, 'C' ) ) THEN
! 215: INFO = -2
! 216: ELSE IF( .NOT.NOUNIT .AND. .NOT.LSAME( DIAG, 'U' ) ) THEN
! 217: INFO = -3
! 218: ELSE IF( .NOT.LSAME( NORMIN, 'Y' ) .AND. .NOT.
! 219: $ LSAME( NORMIN, 'N' ) ) THEN
! 220: INFO = -4
! 221: ELSE IF( N.LT.0 ) THEN
! 222: INFO = -5
! 223: END IF
! 224: IF( INFO.NE.0 ) THEN
! 225: CALL XERBLA( 'ZLATPS', -INFO )
! 226: RETURN
! 227: END IF
! 228: *
! 229: * Quick return if possible
! 230: *
! 231: IF( N.EQ.0 )
! 232: $ RETURN
! 233: *
! 234: * Determine machine dependent parameters to control overflow.
! 235: *
! 236: SMLNUM = DLAMCH( 'Safe minimum' )
! 237: BIGNUM = ONE / SMLNUM
! 238: CALL DLABAD( SMLNUM, BIGNUM )
! 239: SMLNUM = SMLNUM / DLAMCH( 'Precision' )
! 240: BIGNUM = ONE / SMLNUM
! 241: SCALE = ONE
! 242: *
! 243: IF( LSAME( NORMIN, 'N' ) ) THEN
! 244: *
! 245: * Compute the 1-norm of each column, not including the diagonal.
! 246: *
! 247: IF( UPPER ) THEN
! 248: *
! 249: * A is upper triangular.
! 250: *
! 251: IP = 1
! 252: DO 10 J = 1, N
! 253: CNORM( J ) = DZASUM( J-1, AP( IP ), 1 )
! 254: IP = IP + J
! 255: 10 CONTINUE
! 256: ELSE
! 257: *
! 258: * A is lower triangular.
! 259: *
! 260: IP = 1
! 261: DO 20 J = 1, N - 1
! 262: CNORM( J ) = DZASUM( N-J, AP( IP+1 ), 1 )
! 263: IP = IP + N - J + 1
! 264: 20 CONTINUE
! 265: CNORM( N ) = ZERO
! 266: END IF
! 267: END IF
! 268: *
! 269: * Scale the column norms by TSCAL if the maximum element in CNORM is
! 270: * greater than BIGNUM/2.
! 271: *
! 272: IMAX = IDAMAX( N, CNORM, 1 )
! 273: TMAX = CNORM( IMAX )
! 274: IF( TMAX.LE.BIGNUM*HALF ) THEN
! 275: TSCAL = ONE
! 276: ELSE
! 277: TSCAL = HALF / ( SMLNUM*TMAX )
! 278: CALL DSCAL( N, TSCAL, CNORM, 1 )
! 279: END IF
! 280: *
! 281: * Compute a bound on the computed solution vector to see if the
! 282: * Level 2 BLAS routine ZTPSV can be used.
! 283: *
! 284: XMAX = ZERO
! 285: DO 30 J = 1, N
! 286: XMAX = MAX( XMAX, CABS2( X( J ) ) )
! 287: 30 CONTINUE
! 288: XBND = XMAX
! 289: IF( NOTRAN ) THEN
! 290: *
! 291: * Compute the growth in A * x = b.
! 292: *
! 293: IF( UPPER ) THEN
! 294: JFIRST = N
! 295: JLAST = 1
! 296: JINC = -1
! 297: ELSE
! 298: JFIRST = 1
! 299: JLAST = N
! 300: JINC = 1
! 301: END IF
! 302: *
! 303: IF( TSCAL.NE.ONE ) THEN
! 304: GROW = ZERO
! 305: GO TO 60
! 306: END IF
! 307: *
! 308: IF( NOUNIT ) THEN
! 309: *
! 310: * A is non-unit triangular.
! 311: *
! 312: * Compute GROW = 1/G(j) and XBND = 1/M(j).
! 313: * Initially, G(0) = max{x(i), i=1,...,n}.
! 314: *
! 315: GROW = HALF / MAX( XBND, SMLNUM )
! 316: XBND = GROW
! 317: IP = JFIRST*( JFIRST+1 ) / 2
! 318: JLEN = N
! 319: DO 40 J = JFIRST, JLAST, JINC
! 320: *
! 321: * Exit the loop if the growth factor is too small.
! 322: *
! 323: IF( GROW.LE.SMLNUM )
! 324: $ GO TO 60
! 325: *
! 326: TJJS = AP( IP )
! 327: TJJ = CABS1( TJJS )
! 328: *
! 329: IF( TJJ.GE.SMLNUM ) THEN
! 330: *
! 331: * M(j) = G(j-1) / abs(A(j,j))
! 332: *
! 333: XBND = MIN( XBND, MIN( ONE, TJJ )*GROW )
! 334: ELSE
! 335: *
! 336: * M(j) could overflow, set XBND to 0.
! 337: *
! 338: XBND = ZERO
! 339: END IF
! 340: *
! 341: IF( TJJ+CNORM( J ).GE.SMLNUM ) THEN
! 342: *
! 343: * G(j) = G(j-1)*( 1 + CNORM(j) / abs(A(j,j)) )
! 344: *
! 345: GROW = GROW*( TJJ / ( TJJ+CNORM( J ) ) )
! 346: ELSE
! 347: *
! 348: * G(j) could overflow, set GROW to 0.
! 349: *
! 350: GROW = ZERO
! 351: END IF
! 352: IP = IP + JINC*JLEN
! 353: JLEN = JLEN - 1
! 354: 40 CONTINUE
! 355: GROW = XBND
! 356: ELSE
! 357: *
! 358: * A is unit triangular.
! 359: *
! 360: * Compute GROW = 1/G(j), where G(0) = max{x(i), i=1,...,n}.
! 361: *
! 362: GROW = MIN( ONE, HALF / MAX( XBND, SMLNUM ) )
! 363: DO 50 J = JFIRST, JLAST, JINC
! 364: *
! 365: * Exit the loop if the growth factor is too small.
! 366: *
! 367: IF( GROW.LE.SMLNUM )
! 368: $ GO TO 60
! 369: *
! 370: * G(j) = G(j-1)*( 1 + CNORM(j) )
! 371: *
! 372: GROW = GROW*( ONE / ( ONE+CNORM( J ) ) )
! 373: 50 CONTINUE
! 374: END IF
! 375: 60 CONTINUE
! 376: *
! 377: ELSE
! 378: *
! 379: * Compute the growth in A**T * x = b or A**H * x = b.
! 380: *
! 381: IF( UPPER ) THEN
! 382: JFIRST = 1
! 383: JLAST = N
! 384: JINC = 1
! 385: ELSE
! 386: JFIRST = N
! 387: JLAST = 1
! 388: JINC = -1
! 389: END IF
! 390: *
! 391: IF( TSCAL.NE.ONE ) THEN
! 392: GROW = ZERO
! 393: GO TO 90
! 394: END IF
! 395: *
! 396: IF( NOUNIT ) THEN
! 397: *
! 398: * A is non-unit triangular.
! 399: *
! 400: * Compute GROW = 1/G(j) and XBND = 1/M(j).
! 401: * Initially, M(0) = max{x(i), i=1,...,n}.
! 402: *
! 403: GROW = HALF / MAX( XBND, SMLNUM )
! 404: XBND = GROW
! 405: IP = JFIRST*( JFIRST+1 ) / 2
! 406: JLEN = 1
! 407: DO 70 J = JFIRST, JLAST, JINC
! 408: *
! 409: * Exit the loop if the growth factor is too small.
! 410: *
! 411: IF( GROW.LE.SMLNUM )
! 412: $ GO TO 90
! 413: *
! 414: * G(j) = max( G(j-1), M(j-1)*( 1 + CNORM(j) ) )
! 415: *
! 416: XJ = ONE + CNORM( J )
! 417: GROW = MIN( GROW, XBND / XJ )
! 418: *
! 419: TJJS = AP( IP )
! 420: TJJ = CABS1( TJJS )
! 421: *
! 422: IF( TJJ.GE.SMLNUM ) THEN
! 423: *
! 424: * M(j) = M(j-1)*( 1 + CNORM(j) ) / abs(A(j,j))
! 425: *
! 426: IF( XJ.GT.TJJ )
! 427: $ XBND = XBND*( TJJ / XJ )
! 428: ELSE
! 429: *
! 430: * M(j) could overflow, set XBND to 0.
! 431: *
! 432: XBND = ZERO
! 433: END IF
! 434: JLEN = JLEN + 1
! 435: IP = IP + JINC*JLEN
! 436: 70 CONTINUE
! 437: GROW = MIN( GROW, XBND )
! 438: ELSE
! 439: *
! 440: * A is unit triangular.
! 441: *
! 442: * Compute GROW = 1/G(j), where G(0) = max{x(i), i=1,...,n}.
! 443: *
! 444: GROW = MIN( ONE, HALF / MAX( XBND, SMLNUM ) )
! 445: DO 80 J = JFIRST, JLAST, JINC
! 446: *
! 447: * Exit the loop if the growth factor is too small.
! 448: *
! 449: IF( GROW.LE.SMLNUM )
! 450: $ GO TO 90
! 451: *
! 452: * G(j) = ( 1 + CNORM(j) )*G(j-1)
! 453: *
! 454: XJ = ONE + CNORM( J )
! 455: GROW = GROW / XJ
! 456: 80 CONTINUE
! 457: END IF
! 458: 90 CONTINUE
! 459: END IF
! 460: *
! 461: IF( ( GROW*TSCAL ).GT.SMLNUM ) THEN
! 462: *
! 463: * Use the Level 2 BLAS solve if the reciprocal of the bound on
! 464: * elements of X is not too small.
! 465: *
! 466: CALL ZTPSV( UPLO, TRANS, DIAG, N, AP, X, 1 )
! 467: ELSE
! 468: *
! 469: * Use a Level 1 BLAS solve, scaling intermediate results.
! 470: *
! 471: IF( XMAX.GT.BIGNUM*HALF ) THEN
! 472: *
! 473: * Scale X so that its components are less than or equal to
! 474: * BIGNUM in absolute value.
! 475: *
! 476: SCALE = ( BIGNUM*HALF ) / XMAX
! 477: CALL ZDSCAL( N, SCALE, X, 1 )
! 478: XMAX = BIGNUM
! 479: ELSE
! 480: XMAX = XMAX*TWO
! 481: END IF
! 482: *
! 483: IF( NOTRAN ) THEN
! 484: *
! 485: * Solve A * x = b
! 486: *
! 487: IP = JFIRST*( JFIRST+1 ) / 2
! 488: DO 120 J = JFIRST, JLAST, JINC
! 489: *
! 490: * Compute x(j) = b(j) / A(j,j), scaling x if necessary.
! 491: *
! 492: XJ = CABS1( X( J ) )
! 493: IF( NOUNIT ) THEN
! 494: TJJS = AP( IP )*TSCAL
! 495: ELSE
! 496: TJJS = TSCAL
! 497: IF( TSCAL.EQ.ONE )
! 498: $ GO TO 110
! 499: END IF
! 500: TJJ = CABS1( TJJS )
! 501: IF( TJJ.GT.SMLNUM ) THEN
! 502: *
! 503: * abs(A(j,j)) > SMLNUM:
! 504: *
! 505: IF( TJJ.LT.ONE ) THEN
! 506: IF( XJ.GT.TJJ*BIGNUM ) THEN
! 507: *
! 508: * Scale x by 1/b(j).
! 509: *
! 510: REC = ONE / XJ
! 511: CALL ZDSCAL( N, REC, X, 1 )
! 512: SCALE = SCALE*REC
! 513: XMAX = XMAX*REC
! 514: END IF
! 515: END IF
! 516: X( J ) = ZLADIV( X( J ), TJJS )
! 517: XJ = CABS1( X( J ) )
! 518: ELSE IF( TJJ.GT.ZERO ) THEN
! 519: *
! 520: * 0 < abs(A(j,j)) <= SMLNUM:
! 521: *
! 522: IF( XJ.GT.TJJ*BIGNUM ) THEN
! 523: *
! 524: * Scale x by (1/abs(x(j)))*abs(A(j,j))*BIGNUM
! 525: * to avoid overflow when dividing by A(j,j).
! 526: *
! 527: REC = ( TJJ*BIGNUM ) / XJ
! 528: IF( CNORM( J ).GT.ONE ) THEN
! 529: *
! 530: * Scale by 1/CNORM(j) to avoid overflow when
! 531: * multiplying x(j) times column j.
! 532: *
! 533: REC = REC / CNORM( J )
! 534: END IF
! 535: CALL ZDSCAL( N, REC, X, 1 )
! 536: SCALE = SCALE*REC
! 537: XMAX = XMAX*REC
! 538: END IF
! 539: X( J ) = ZLADIV( X( J ), TJJS )
! 540: XJ = CABS1( X( J ) )
! 541: ELSE
! 542: *
! 543: * A(j,j) = 0: Set x(1:n) = 0, x(j) = 1, and
! 544: * scale = 0, and compute a solution to A*x = 0.
! 545: *
! 546: DO 100 I = 1, N
! 547: X( I ) = ZERO
! 548: 100 CONTINUE
! 549: X( J ) = ONE
! 550: XJ = ONE
! 551: SCALE = ZERO
! 552: XMAX = ZERO
! 553: END IF
! 554: 110 CONTINUE
! 555: *
! 556: * Scale x if necessary to avoid overflow when adding a
! 557: * multiple of column j of A.
! 558: *
! 559: IF( XJ.GT.ONE ) THEN
! 560: REC = ONE / XJ
! 561: IF( CNORM( J ).GT.( BIGNUM-XMAX )*REC ) THEN
! 562: *
! 563: * Scale x by 1/(2*abs(x(j))).
! 564: *
! 565: REC = REC*HALF
! 566: CALL ZDSCAL( N, REC, X, 1 )
! 567: SCALE = SCALE*REC
! 568: END IF
! 569: ELSE IF( XJ*CNORM( J ).GT.( BIGNUM-XMAX ) ) THEN
! 570: *
! 571: * Scale x by 1/2.
! 572: *
! 573: CALL ZDSCAL( N, HALF, X, 1 )
! 574: SCALE = SCALE*HALF
! 575: END IF
! 576: *
! 577: IF( UPPER ) THEN
! 578: IF( J.GT.1 ) THEN
! 579: *
! 580: * Compute the update
! 581: * x(1:j-1) := x(1:j-1) - x(j) * A(1:j-1,j)
! 582: *
! 583: CALL ZAXPY( J-1, -X( J )*TSCAL, AP( IP-J+1 ), 1, X,
! 584: $ 1 )
! 585: I = IZAMAX( J-1, X, 1 )
! 586: XMAX = CABS1( X( I ) )
! 587: END IF
! 588: IP = IP - J
! 589: ELSE
! 590: IF( J.LT.N ) THEN
! 591: *
! 592: * Compute the update
! 593: * x(j+1:n) := x(j+1:n) - x(j) * A(j+1:n,j)
! 594: *
! 595: CALL ZAXPY( N-J, -X( J )*TSCAL, AP( IP+1 ), 1,
! 596: $ X( J+1 ), 1 )
! 597: I = J + IZAMAX( N-J, X( J+1 ), 1 )
! 598: XMAX = CABS1( X( I ) )
! 599: END IF
! 600: IP = IP + N - J + 1
! 601: END IF
! 602: 120 CONTINUE
! 603: *
! 604: ELSE IF( LSAME( TRANS, 'T' ) ) THEN
! 605: *
! 606: * Solve A**T * x = b
! 607: *
! 608: IP = JFIRST*( JFIRST+1 ) / 2
! 609: JLEN = 1
! 610: DO 170 J = JFIRST, JLAST, JINC
! 611: *
! 612: * Compute x(j) = b(j) - sum A(k,j)*x(k).
! 613: * k<>j
! 614: *
! 615: XJ = CABS1( X( J ) )
! 616: USCAL = TSCAL
! 617: REC = ONE / MAX( XMAX, ONE )
! 618: IF( CNORM( J ).GT.( BIGNUM-XJ )*REC ) THEN
! 619: *
! 620: * If x(j) could overflow, scale x by 1/(2*XMAX).
! 621: *
! 622: REC = REC*HALF
! 623: IF( NOUNIT ) THEN
! 624: TJJS = AP( IP )*TSCAL
! 625: ELSE
! 626: TJJS = TSCAL
! 627: END IF
! 628: TJJ = CABS1( TJJS )
! 629: IF( TJJ.GT.ONE ) THEN
! 630: *
! 631: * Divide by A(j,j) when scaling x if A(j,j) > 1.
! 632: *
! 633: REC = MIN( ONE, REC*TJJ )
! 634: USCAL = ZLADIV( USCAL, TJJS )
! 635: END IF
! 636: IF( REC.LT.ONE ) THEN
! 637: CALL ZDSCAL( N, REC, X, 1 )
! 638: SCALE = SCALE*REC
! 639: XMAX = XMAX*REC
! 640: END IF
! 641: END IF
! 642: *
! 643: CSUMJ = ZERO
! 644: IF( USCAL.EQ.DCMPLX( ONE ) ) THEN
! 645: *
! 646: * If the scaling needed for A in the dot product is 1,
! 647: * call ZDOTU to perform the dot product.
! 648: *
! 649: IF( UPPER ) THEN
! 650: CSUMJ = ZDOTU( J-1, AP( IP-J+1 ), 1, X, 1 )
! 651: ELSE IF( J.LT.N ) THEN
! 652: CSUMJ = ZDOTU( N-J, AP( IP+1 ), 1, X( J+1 ), 1 )
! 653: END IF
! 654: ELSE
! 655: *
! 656: * Otherwise, use in-line code for the dot product.
! 657: *
! 658: IF( UPPER ) THEN
! 659: DO 130 I = 1, J - 1
! 660: CSUMJ = CSUMJ + ( AP( IP-J+I )*USCAL )*X( I )
! 661: 130 CONTINUE
! 662: ELSE IF( J.LT.N ) THEN
! 663: DO 140 I = 1, N - J
! 664: CSUMJ = CSUMJ + ( AP( IP+I )*USCAL )*X( J+I )
! 665: 140 CONTINUE
! 666: END IF
! 667: END IF
! 668: *
! 669: IF( USCAL.EQ.DCMPLX( TSCAL ) ) THEN
! 670: *
! 671: * Compute x(j) := ( x(j) - CSUMJ ) / A(j,j) if 1/A(j,j)
! 672: * was not used to scale the dotproduct.
! 673: *
! 674: X( J ) = X( J ) - CSUMJ
! 675: XJ = CABS1( X( J ) )
! 676: IF( NOUNIT ) THEN
! 677: *
! 678: * Compute x(j) = x(j) / A(j,j), scaling if necessary.
! 679: *
! 680: TJJS = AP( IP )*TSCAL
! 681: ELSE
! 682: TJJS = TSCAL
! 683: IF( TSCAL.EQ.ONE )
! 684: $ GO TO 160
! 685: END IF
! 686: TJJ = CABS1( TJJS )
! 687: IF( TJJ.GT.SMLNUM ) THEN
! 688: *
! 689: * abs(A(j,j)) > SMLNUM:
! 690: *
! 691: IF( TJJ.LT.ONE ) THEN
! 692: IF( XJ.GT.TJJ*BIGNUM ) THEN
! 693: *
! 694: * Scale X by 1/abs(x(j)).
! 695: *
! 696: REC = ONE / XJ
! 697: CALL ZDSCAL( N, REC, X, 1 )
! 698: SCALE = SCALE*REC
! 699: XMAX = XMAX*REC
! 700: END IF
! 701: END IF
! 702: X( J ) = ZLADIV( X( J ), TJJS )
! 703: ELSE IF( TJJ.GT.ZERO ) THEN
! 704: *
! 705: * 0 < abs(A(j,j)) <= SMLNUM:
! 706: *
! 707: IF( XJ.GT.TJJ*BIGNUM ) THEN
! 708: *
! 709: * Scale x by (1/abs(x(j)))*abs(A(j,j))*BIGNUM.
! 710: *
! 711: REC = ( TJJ*BIGNUM ) / XJ
! 712: CALL ZDSCAL( N, REC, X, 1 )
! 713: SCALE = SCALE*REC
! 714: XMAX = XMAX*REC
! 715: END IF
! 716: X( J ) = ZLADIV( X( J ), TJJS )
! 717: ELSE
! 718: *
! 719: * A(j,j) = 0: Set x(1:n) = 0, x(j) = 1, and
! 720: * scale = 0 and compute a solution to A**T *x = 0.
! 721: *
! 722: DO 150 I = 1, N
! 723: X( I ) = ZERO
! 724: 150 CONTINUE
! 725: X( J ) = ONE
! 726: SCALE = ZERO
! 727: XMAX = ZERO
! 728: END IF
! 729: 160 CONTINUE
! 730: ELSE
! 731: *
! 732: * Compute x(j) := x(j) / A(j,j) - CSUMJ if the dot
! 733: * product has already been divided by 1/A(j,j).
! 734: *
! 735: X( J ) = ZLADIV( X( J ), TJJS ) - CSUMJ
! 736: END IF
! 737: XMAX = MAX( XMAX, CABS1( X( J ) ) )
! 738: JLEN = JLEN + 1
! 739: IP = IP + JINC*JLEN
! 740: 170 CONTINUE
! 741: *
! 742: ELSE
! 743: *
! 744: * Solve A**H * x = b
! 745: *
! 746: IP = JFIRST*( JFIRST+1 ) / 2
! 747: JLEN = 1
! 748: DO 220 J = JFIRST, JLAST, JINC
! 749: *
! 750: * Compute x(j) = b(j) - sum A(k,j)*x(k).
! 751: * k<>j
! 752: *
! 753: XJ = CABS1( X( J ) )
! 754: USCAL = TSCAL
! 755: REC = ONE / MAX( XMAX, ONE )
! 756: IF( CNORM( J ).GT.( BIGNUM-XJ )*REC ) THEN
! 757: *
! 758: * If x(j) could overflow, scale x by 1/(2*XMAX).
! 759: *
! 760: REC = REC*HALF
! 761: IF( NOUNIT ) THEN
! 762: TJJS = DCONJG( AP( IP ) )*TSCAL
! 763: ELSE
! 764: TJJS = TSCAL
! 765: END IF
! 766: TJJ = CABS1( TJJS )
! 767: IF( TJJ.GT.ONE ) THEN
! 768: *
! 769: * Divide by A(j,j) when scaling x if A(j,j) > 1.
! 770: *
! 771: REC = MIN( ONE, REC*TJJ )
! 772: USCAL = ZLADIV( USCAL, TJJS )
! 773: END IF
! 774: IF( REC.LT.ONE ) THEN
! 775: CALL ZDSCAL( N, REC, X, 1 )
! 776: SCALE = SCALE*REC
! 777: XMAX = XMAX*REC
! 778: END IF
! 779: END IF
! 780: *
! 781: CSUMJ = ZERO
! 782: IF( USCAL.EQ.DCMPLX( ONE ) ) THEN
! 783: *
! 784: * If the scaling needed for A in the dot product is 1,
! 785: * call ZDOTC to perform the dot product.
! 786: *
! 787: IF( UPPER ) THEN
! 788: CSUMJ = ZDOTC( J-1, AP( IP-J+1 ), 1, X, 1 )
! 789: ELSE IF( J.LT.N ) THEN
! 790: CSUMJ = ZDOTC( N-J, AP( IP+1 ), 1, X( J+1 ), 1 )
! 791: END IF
! 792: ELSE
! 793: *
! 794: * Otherwise, use in-line code for the dot product.
! 795: *
! 796: IF( UPPER ) THEN
! 797: DO 180 I = 1, J - 1
! 798: CSUMJ = CSUMJ + ( DCONJG( AP( IP-J+I ) )*USCAL )
! 799: $ *X( I )
! 800: 180 CONTINUE
! 801: ELSE IF( J.LT.N ) THEN
! 802: DO 190 I = 1, N - J
! 803: CSUMJ = CSUMJ + ( DCONJG( AP( IP+I ) )*USCAL )*
! 804: $ X( J+I )
! 805: 190 CONTINUE
! 806: END IF
! 807: END IF
! 808: *
! 809: IF( USCAL.EQ.DCMPLX( TSCAL ) ) THEN
! 810: *
! 811: * Compute x(j) := ( x(j) - CSUMJ ) / A(j,j) if 1/A(j,j)
! 812: * was not used to scale the dotproduct.
! 813: *
! 814: X( J ) = X( J ) - CSUMJ
! 815: XJ = CABS1( X( J ) )
! 816: IF( NOUNIT ) THEN
! 817: *
! 818: * Compute x(j) = x(j) / A(j,j), scaling if necessary.
! 819: *
! 820: TJJS = DCONJG( AP( IP ) )*TSCAL
! 821: ELSE
! 822: TJJS = TSCAL
! 823: IF( TSCAL.EQ.ONE )
! 824: $ GO TO 210
! 825: END IF
! 826: TJJ = CABS1( TJJS )
! 827: IF( TJJ.GT.SMLNUM ) THEN
! 828: *
! 829: * abs(A(j,j)) > SMLNUM:
! 830: *
! 831: IF( TJJ.LT.ONE ) THEN
! 832: IF( XJ.GT.TJJ*BIGNUM ) THEN
! 833: *
! 834: * Scale X by 1/abs(x(j)).
! 835: *
! 836: REC = ONE / XJ
! 837: CALL ZDSCAL( N, REC, X, 1 )
! 838: SCALE = SCALE*REC
! 839: XMAX = XMAX*REC
! 840: END IF
! 841: END IF
! 842: X( J ) = ZLADIV( X( J ), TJJS )
! 843: ELSE IF( TJJ.GT.ZERO ) THEN
! 844: *
! 845: * 0 < abs(A(j,j)) <= SMLNUM:
! 846: *
! 847: IF( XJ.GT.TJJ*BIGNUM ) THEN
! 848: *
! 849: * Scale x by (1/abs(x(j)))*abs(A(j,j))*BIGNUM.
! 850: *
! 851: REC = ( TJJ*BIGNUM ) / XJ
! 852: CALL ZDSCAL( N, REC, X, 1 )
! 853: SCALE = SCALE*REC
! 854: XMAX = XMAX*REC
! 855: END IF
! 856: X( J ) = ZLADIV( X( J ), TJJS )
! 857: ELSE
! 858: *
! 859: * A(j,j) = 0: Set x(1:n) = 0, x(j) = 1, and
! 860: * scale = 0 and compute a solution to A**H *x = 0.
! 861: *
! 862: DO 200 I = 1, N
! 863: X( I ) = ZERO
! 864: 200 CONTINUE
! 865: X( J ) = ONE
! 866: SCALE = ZERO
! 867: XMAX = ZERO
! 868: END IF
! 869: 210 CONTINUE
! 870: ELSE
! 871: *
! 872: * Compute x(j) := x(j) / A(j,j) - CSUMJ if the dot
! 873: * product has already been divided by 1/A(j,j).
! 874: *
! 875: X( J ) = ZLADIV( X( J ), TJJS ) - CSUMJ
! 876: END IF
! 877: XMAX = MAX( XMAX, CABS1( X( J ) ) )
! 878: JLEN = JLEN + 1
! 879: IP = IP + JINC*JLEN
! 880: 220 CONTINUE
! 881: END IF
! 882: SCALE = SCALE / TSCAL
! 883: END IF
! 884: *
! 885: * Scale the column norms by 1/TSCAL for return.
! 886: *
! 887: IF( TSCAL.NE.ONE ) THEN
! 888: CALL DSCAL( N, ONE / TSCAL, CNORM, 1 )
! 889: END IF
! 890: *
! 891: RETURN
! 892: *
! 893: * End of ZLATPS
! 894: *
! 895: END
CVSweb interface <joel.bertrand@systella.fr>