Annotation of rpl/lapack/lapack/zhbgst.f, revision 1.1
1.1 ! bertrand 1: SUBROUTINE ZHBGST( VECT, UPLO, N, KA, KB, AB, LDAB, BB, LDBB, X,
! 2: $ LDX, WORK, RWORK, INFO )
! 3: *
! 4: * -- LAPACK 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 UPLO, VECT
! 11: INTEGER INFO, KA, KB, LDAB, LDBB, LDX, N
! 12: * ..
! 13: * .. Array Arguments ..
! 14: DOUBLE PRECISION RWORK( * )
! 15: COMPLEX*16 AB( LDAB, * ), BB( LDBB, * ), WORK( * ),
! 16: $ X( LDX, * )
! 17: * ..
! 18: *
! 19: * Purpose
! 20: * =======
! 21: *
! 22: * ZHBGST reduces a complex Hermitian-definite banded generalized
! 23: * eigenproblem A*x = lambda*B*x to standard form C*y = lambda*y,
! 24: * such that C has the same bandwidth as A.
! 25: *
! 26: * B must have been previously factorized as S**H*S by ZPBSTF, using a
! 27: * split Cholesky factorization. A is overwritten by C = X**H*A*X, where
! 28: * X = S**(-1)*Q and Q is a unitary matrix chosen to preserve the
! 29: * bandwidth of A.
! 30: *
! 31: * Arguments
! 32: * =========
! 33: *
! 34: * VECT (input) CHARACTER*1
! 35: * = 'N': do not form the transformation matrix X;
! 36: * = 'V': form X.
! 37: *
! 38: * UPLO (input) CHARACTER*1
! 39: * = 'U': Upper triangle of A is stored;
! 40: * = 'L': Lower triangle of A is stored.
! 41: *
! 42: * N (input) INTEGER
! 43: * The order of the matrices A and B. N >= 0.
! 44: *
! 45: * KA (input) INTEGER
! 46: * The number of superdiagonals of the matrix A if UPLO = 'U',
! 47: * or the number of subdiagonals if UPLO = 'L'. KA >= 0.
! 48: *
! 49: * KB (input) INTEGER
! 50: * The number of superdiagonals of the matrix B if UPLO = 'U',
! 51: * or the number of subdiagonals if UPLO = 'L'. KA >= KB >= 0.
! 52: *
! 53: * AB (input/output) COMPLEX*16 array, dimension (LDAB,N)
! 54: * On entry, the upper or lower triangle of the Hermitian band
! 55: * matrix A, stored in the first ka+1 rows of the array. The
! 56: * j-th column of A is stored in the j-th column of the array AB
! 57: * as follows:
! 58: * if UPLO = 'U', AB(ka+1+i-j,j) = A(i,j) for max(1,j-ka)<=i<=j;
! 59: * if UPLO = 'L', AB(1+i-j,j) = A(i,j) for j<=i<=min(n,j+ka).
! 60: *
! 61: * On exit, the transformed matrix X**H*A*X, stored in the same
! 62: * format as A.
! 63: *
! 64: * LDAB (input) INTEGER
! 65: * The leading dimension of the array AB. LDAB >= KA+1.
! 66: *
! 67: * BB (input) COMPLEX*16 array, dimension (LDBB,N)
! 68: * The banded factor S from the split Cholesky factorization of
! 69: * B, as returned by ZPBSTF, stored in the first kb+1 rows of
! 70: * the array.
! 71: *
! 72: * LDBB (input) INTEGER
! 73: * The leading dimension of the array BB. LDBB >= KB+1.
! 74: *
! 75: * X (output) COMPLEX*16 array, dimension (LDX,N)
! 76: * If VECT = 'V', the n-by-n matrix X.
! 77: * If VECT = 'N', the array X is not referenced.
! 78: *
! 79: * LDX (input) INTEGER
! 80: * The leading dimension of the array X.
! 81: * LDX >= max(1,N) if VECT = 'V'; LDX >= 1 otherwise.
! 82: *
! 83: * WORK (workspace) COMPLEX*16 array, dimension (N)
! 84: *
! 85: * RWORK (workspace) DOUBLE PRECISION array, dimension (N)
! 86: *
! 87: * INFO (output) INTEGER
! 88: * = 0: successful exit
! 89: * < 0: if INFO = -i, the i-th argument had an illegal value.
! 90: *
! 91: * =====================================================================
! 92: *
! 93: * .. Parameters ..
! 94: COMPLEX*16 CZERO, CONE
! 95: DOUBLE PRECISION ONE
! 96: PARAMETER ( CZERO = ( 0.0D+0, 0.0D+0 ),
! 97: $ CONE = ( 1.0D+0, 0.0D+0 ), ONE = 1.0D+0 )
! 98: * ..
! 99: * .. Local Scalars ..
! 100: LOGICAL UPDATE, UPPER, WANTX
! 101: INTEGER I, I0, I1, I2, INCA, J, J1, J1T, J2, J2T, K,
! 102: $ KA1, KB1, KBT, L, M, NR, NRT, NX
! 103: DOUBLE PRECISION BII
! 104: COMPLEX*16 RA, RA1, T
! 105: * ..
! 106: * .. External Functions ..
! 107: LOGICAL LSAME
! 108: EXTERNAL LSAME
! 109: * ..
! 110: * .. External Subroutines ..
! 111: EXTERNAL XERBLA, ZDSCAL, ZGERC, ZGERU, ZLACGV, ZLAR2V,
! 112: $ ZLARGV, ZLARTG, ZLARTV, ZLASET, ZROT
! 113: * ..
! 114: * .. Intrinsic Functions ..
! 115: INTRINSIC DBLE, DCONJG, MAX, MIN
! 116: * ..
! 117: * .. Executable Statements ..
! 118: *
! 119: * Test the input parameters
! 120: *
! 121: WANTX = LSAME( VECT, 'V' )
! 122: UPPER = LSAME( UPLO, 'U' )
! 123: KA1 = KA + 1
! 124: KB1 = KB + 1
! 125: INFO = 0
! 126: IF( .NOT.WANTX .AND. .NOT.LSAME( VECT, 'N' ) ) THEN
! 127: INFO = -1
! 128: ELSE IF( .NOT.UPPER .AND. .NOT.LSAME( UPLO, 'L' ) ) THEN
! 129: INFO = -2
! 130: ELSE IF( N.LT.0 ) THEN
! 131: INFO = -3
! 132: ELSE IF( KA.LT.0 ) THEN
! 133: INFO = -4
! 134: ELSE IF( KB.LT.0 .OR. KB.GT.KA ) THEN
! 135: INFO = -5
! 136: ELSE IF( LDAB.LT.KA+1 ) THEN
! 137: INFO = -7
! 138: ELSE IF( LDBB.LT.KB+1 ) THEN
! 139: INFO = -9
! 140: ELSE IF( LDX.LT.1 .OR. WANTX .AND. LDX.LT.MAX( 1, N ) ) THEN
! 141: INFO = -11
! 142: END IF
! 143: IF( INFO.NE.0 ) THEN
! 144: CALL XERBLA( 'ZHBGST', -INFO )
! 145: RETURN
! 146: END IF
! 147: *
! 148: * Quick return if possible
! 149: *
! 150: IF( N.EQ.0 )
! 151: $ RETURN
! 152: *
! 153: INCA = LDAB*KA1
! 154: *
! 155: * Initialize X to the unit matrix, if needed
! 156: *
! 157: IF( WANTX )
! 158: $ CALL ZLASET( 'Full', N, N, CZERO, CONE, X, LDX )
! 159: *
! 160: * Set M to the splitting point m. It must be the same value as is
! 161: * used in ZPBSTF. The chosen value allows the arrays WORK and RWORK
! 162: * to be of dimension (N).
! 163: *
! 164: M = ( N+KB ) / 2
! 165: *
! 166: * The routine works in two phases, corresponding to the two halves
! 167: * of the split Cholesky factorization of B as S**H*S where
! 168: *
! 169: * S = ( U )
! 170: * ( M L )
! 171: *
! 172: * with U upper triangular of order m, and L lower triangular of
! 173: * order n-m. S has the same bandwidth as B.
! 174: *
! 175: * S is treated as a product of elementary matrices:
! 176: *
! 177: * S = S(m)*S(m-1)*...*S(2)*S(1)*S(m+1)*S(m+2)*...*S(n-1)*S(n)
! 178: *
! 179: * where S(i) is determined by the i-th row of S.
! 180: *
! 181: * In phase 1, the index i takes the values n, n-1, ... , m+1;
! 182: * in phase 2, it takes the values 1, 2, ... , m.
! 183: *
! 184: * For each value of i, the current matrix A is updated by forming
! 185: * inv(S(i))**H*A*inv(S(i)). This creates a triangular bulge outside
! 186: * the band of A. The bulge is then pushed down toward the bottom of
! 187: * A in phase 1, and up toward the top of A in phase 2, by applying
! 188: * plane rotations.
! 189: *
! 190: * There are kb*(kb+1)/2 elements in the bulge, but at most 2*kb-1
! 191: * of them are linearly independent, so annihilating a bulge requires
! 192: * only 2*kb-1 plane rotations. The rotations are divided into a 1st
! 193: * set of kb-1 rotations, and a 2nd set of kb rotations.
! 194: *
! 195: * Wherever possible, rotations are generated and applied in vector
! 196: * operations of length NR between the indices J1 and J2 (sometimes
! 197: * replaced by modified values NRT, J1T or J2T).
! 198: *
! 199: * The real cosines and complex sines of the rotations are stored in
! 200: * the arrays RWORK and WORK, those of the 1st set in elements
! 201: * 2:m-kb-1, and those of the 2nd set in elements m-kb+1:n.
! 202: *
! 203: * The bulges are not formed explicitly; nonzero elements outside the
! 204: * band are created only when they are required for generating new
! 205: * rotations; they are stored in the array WORK, in positions where
! 206: * they are later overwritten by the sines of the rotations which
! 207: * annihilate them.
! 208: *
! 209: * **************************** Phase 1 *****************************
! 210: *
! 211: * The logical structure of this phase is:
! 212: *
! 213: * UPDATE = .TRUE.
! 214: * DO I = N, M + 1, -1
! 215: * use S(i) to update A and create a new bulge
! 216: * apply rotations to push all bulges KA positions downward
! 217: * END DO
! 218: * UPDATE = .FALSE.
! 219: * DO I = M + KA + 1, N - 1
! 220: * apply rotations to push all bulges KA positions downward
! 221: * END DO
! 222: *
! 223: * To avoid duplicating code, the two loops are merged.
! 224: *
! 225: UPDATE = .TRUE.
! 226: I = N + 1
! 227: 10 CONTINUE
! 228: IF( UPDATE ) THEN
! 229: I = I - 1
! 230: KBT = MIN( KB, I-1 )
! 231: I0 = I - 1
! 232: I1 = MIN( N, I+KA )
! 233: I2 = I - KBT + KA1
! 234: IF( I.LT.M+1 ) THEN
! 235: UPDATE = .FALSE.
! 236: I = I + 1
! 237: I0 = M
! 238: IF( KA.EQ.0 )
! 239: $ GO TO 480
! 240: GO TO 10
! 241: END IF
! 242: ELSE
! 243: I = I + KA
! 244: IF( I.GT.N-1 )
! 245: $ GO TO 480
! 246: END IF
! 247: *
! 248: IF( UPPER ) THEN
! 249: *
! 250: * Transform A, working with the upper triangle
! 251: *
! 252: IF( UPDATE ) THEN
! 253: *
! 254: * Form inv(S(i))**H * A * inv(S(i))
! 255: *
! 256: BII = DBLE( BB( KB1, I ) )
! 257: AB( KA1, I ) = ( DBLE( AB( KA1, I ) ) / BII ) / BII
! 258: DO 20 J = I + 1, I1
! 259: AB( I-J+KA1, J ) = AB( I-J+KA1, J ) / BII
! 260: 20 CONTINUE
! 261: DO 30 J = MAX( 1, I-KA ), I - 1
! 262: AB( J-I+KA1, I ) = AB( J-I+KA1, I ) / BII
! 263: 30 CONTINUE
! 264: DO 60 K = I - KBT, I - 1
! 265: DO 40 J = I - KBT, K
! 266: AB( J-K+KA1, K ) = AB( J-K+KA1, K ) -
! 267: $ BB( J-I+KB1, I )*
! 268: $ DCONJG( AB( K-I+KA1, I ) ) -
! 269: $ DCONJG( BB( K-I+KB1, I ) )*
! 270: $ AB( J-I+KA1, I ) +
! 271: $ DBLE( AB( KA1, I ) )*
! 272: $ BB( J-I+KB1, I )*
! 273: $ DCONJG( BB( K-I+KB1, I ) )
! 274: 40 CONTINUE
! 275: DO 50 J = MAX( 1, I-KA ), I - KBT - 1
! 276: AB( J-K+KA1, K ) = AB( J-K+KA1, K ) -
! 277: $ DCONJG( BB( K-I+KB1, I ) )*
! 278: $ AB( J-I+KA1, I )
! 279: 50 CONTINUE
! 280: 60 CONTINUE
! 281: DO 80 J = I, I1
! 282: DO 70 K = MAX( J-KA, I-KBT ), I - 1
! 283: AB( K-J+KA1, J ) = AB( K-J+KA1, J ) -
! 284: $ BB( K-I+KB1, I )*AB( I-J+KA1, J )
! 285: 70 CONTINUE
! 286: 80 CONTINUE
! 287: *
! 288: IF( WANTX ) THEN
! 289: *
! 290: * post-multiply X by inv(S(i))
! 291: *
! 292: CALL ZDSCAL( N-M, ONE / BII, X( M+1, I ), 1 )
! 293: IF( KBT.GT.0 )
! 294: $ CALL ZGERC( N-M, KBT, -CONE, X( M+1, I ), 1,
! 295: $ BB( KB1-KBT, I ), 1, X( M+1, I-KBT ),
! 296: $ LDX )
! 297: END IF
! 298: *
! 299: * store a(i,i1) in RA1 for use in next loop over K
! 300: *
! 301: RA1 = AB( I-I1+KA1, I1 )
! 302: END IF
! 303: *
! 304: * Generate and apply vectors of rotations to chase all the
! 305: * existing bulges KA positions down toward the bottom of the
! 306: * band
! 307: *
! 308: DO 130 K = 1, KB - 1
! 309: IF( UPDATE ) THEN
! 310: *
! 311: * Determine the rotations which would annihilate the bulge
! 312: * which has in theory just been created
! 313: *
! 314: IF( I-K+KA.LT.N .AND. I-K.GT.1 ) THEN
! 315: *
! 316: * generate rotation to annihilate a(i,i-k+ka+1)
! 317: *
! 318: CALL ZLARTG( AB( K+1, I-K+KA ), RA1,
! 319: $ RWORK( I-K+KA-M ), WORK( I-K+KA-M ), RA )
! 320: *
! 321: * create nonzero element a(i-k,i-k+ka+1) outside the
! 322: * band and store it in WORK(i-k)
! 323: *
! 324: T = -BB( KB1-K, I )*RA1
! 325: WORK( I-K ) = RWORK( I-K+KA-M )*T -
! 326: $ DCONJG( WORK( I-K+KA-M ) )*
! 327: $ AB( 1, I-K+KA )
! 328: AB( 1, I-K+KA ) = WORK( I-K+KA-M )*T +
! 329: $ RWORK( I-K+KA-M )*AB( 1, I-K+KA )
! 330: RA1 = RA
! 331: END IF
! 332: END IF
! 333: J2 = I - K - 1 + MAX( 1, K-I0+2 )*KA1
! 334: NR = ( N-J2+KA ) / KA1
! 335: J1 = J2 + ( NR-1 )*KA1
! 336: IF( UPDATE ) THEN
! 337: J2T = MAX( J2, I+2*KA-K+1 )
! 338: ELSE
! 339: J2T = J2
! 340: END IF
! 341: NRT = ( N-J2T+KA ) / KA1
! 342: DO 90 J = J2T, J1, KA1
! 343: *
! 344: * create nonzero element a(j-ka,j+1) outside the band
! 345: * and store it in WORK(j-m)
! 346: *
! 347: WORK( J-M ) = WORK( J-M )*AB( 1, J+1 )
! 348: AB( 1, J+1 ) = RWORK( J-M )*AB( 1, J+1 )
! 349: 90 CONTINUE
! 350: *
! 351: * generate rotations in 1st set to annihilate elements which
! 352: * have been created outside the band
! 353: *
! 354: IF( NRT.GT.0 )
! 355: $ CALL ZLARGV( NRT, AB( 1, J2T ), INCA, WORK( J2T-M ), KA1,
! 356: $ RWORK( J2T-M ), KA1 )
! 357: IF( NR.GT.0 ) THEN
! 358: *
! 359: * apply rotations in 1st set from the right
! 360: *
! 361: DO 100 L = 1, KA - 1
! 362: CALL ZLARTV( NR, AB( KA1-L, J2 ), INCA,
! 363: $ AB( KA-L, J2+1 ), INCA, RWORK( J2-M ),
! 364: $ WORK( J2-M ), KA1 )
! 365: 100 CONTINUE
! 366: *
! 367: * apply rotations in 1st set from both sides to diagonal
! 368: * blocks
! 369: *
! 370: CALL ZLAR2V( NR, AB( KA1, J2 ), AB( KA1, J2+1 ),
! 371: $ AB( KA, J2+1 ), INCA, RWORK( J2-M ),
! 372: $ WORK( J2-M ), KA1 )
! 373: *
! 374: CALL ZLACGV( NR, WORK( J2-M ), KA1 )
! 375: END IF
! 376: *
! 377: * start applying rotations in 1st set from the left
! 378: *
! 379: DO 110 L = KA - 1, KB - K + 1, -1
! 380: NRT = ( N-J2+L ) / KA1
! 381: IF( NRT.GT.0 )
! 382: $ CALL ZLARTV( NRT, AB( L, J2+KA1-L ), INCA,
! 383: $ AB( L+1, J2+KA1-L ), INCA, RWORK( J2-M ),
! 384: $ WORK( J2-M ), KA1 )
! 385: 110 CONTINUE
! 386: *
! 387: IF( WANTX ) THEN
! 388: *
! 389: * post-multiply X by product of rotations in 1st set
! 390: *
! 391: DO 120 J = J2, J1, KA1
! 392: CALL ZROT( N-M, X( M+1, J ), 1, X( M+1, J+1 ), 1,
! 393: $ RWORK( J-M ), DCONJG( WORK( J-M ) ) )
! 394: 120 CONTINUE
! 395: END IF
! 396: 130 CONTINUE
! 397: *
! 398: IF( UPDATE ) THEN
! 399: IF( I2.LE.N .AND. KBT.GT.0 ) THEN
! 400: *
! 401: * create nonzero element a(i-kbt,i-kbt+ka+1) outside the
! 402: * band and store it in WORK(i-kbt)
! 403: *
! 404: WORK( I-KBT ) = -BB( KB1-KBT, I )*RA1
! 405: END IF
! 406: END IF
! 407: *
! 408: DO 170 K = KB, 1, -1
! 409: IF( UPDATE ) THEN
! 410: J2 = I - K - 1 + MAX( 2, K-I0+1 )*KA1
! 411: ELSE
! 412: J2 = I - K - 1 + MAX( 1, K-I0+1 )*KA1
! 413: END IF
! 414: *
! 415: * finish applying rotations in 2nd set from the left
! 416: *
! 417: DO 140 L = KB - K, 1, -1
! 418: NRT = ( N-J2+KA+L ) / KA1
! 419: IF( NRT.GT.0 )
! 420: $ CALL ZLARTV( NRT, AB( L, J2-L+1 ), INCA,
! 421: $ AB( L+1, J2-L+1 ), INCA, RWORK( J2-KA ),
! 422: $ WORK( J2-KA ), KA1 )
! 423: 140 CONTINUE
! 424: NR = ( N-J2+KA ) / KA1
! 425: J1 = J2 + ( NR-1 )*KA1
! 426: DO 150 J = J1, J2, -KA1
! 427: WORK( J ) = WORK( J-KA )
! 428: RWORK( J ) = RWORK( J-KA )
! 429: 150 CONTINUE
! 430: DO 160 J = J2, J1, KA1
! 431: *
! 432: * create nonzero element a(j-ka,j+1) outside the band
! 433: * and store it in WORK(j)
! 434: *
! 435: WORK( J ) = WORK( J )*AB( 1, J+1 )
! 436: AB( 1, J+1 ) = RWORK( J )*AB( 1, J+1 )
! 437: 160 CONTINUE
! 438: IF( UPDATE ) THEN
! 439: IF( I-K.LT.N-KA .AND. K.LE.KBT )
! 440: $ WORK( I-K+KA ) = WORK( I-K )
! 441: END IF
! 442: 170 CONTINUE
! 443: *
! 444: DO 210 K = KB, 1, -1
! 445: J2 = I - K - 1 + MAX( 1, K-I0+1 )*KA1
! 446: NR = ( N-J2+KA ) / KA1
! 447: J1 = J2 + ( NR-1 )*KA1
! 448: IF( NR.GT.0 ) THEN
! 449: *
! 450: * generate rotations in 2nd set to annihilate elements
! 451: * which have been created outside the band
! 452: *
! 453: CALL ZLARGV( NR, AB( 1, J2 ), INCA, WORK( J2 ), KA1,
! 454: $ RWORK( J2 ), KA1 )
! 455: *
! 456: * apply rotations in 2nd set from the right
! 457: *
! 458: DO 180 L = 1, KA - 1
! 459: CALL ZLARTV( NR, AB( KA1-L, J2 ), INCA,
! 460: $ AB( KA-L, J2+1 ), INCA, RWORK( J2 ),
! 461: $ WORK( J2 ), KA1 )
! 462: 180 CONTINUE
! 463: *
! 464: * apply rotations in 2nd set from both sides to diagonal
! 465: * blocks
! 466: *
! 467: CALL ZLAR2V( NR, AB( KA1, J2 ), AB( KA1, J2+1 ),
! 468: $ AB( KA, J2+1 ), INCA, RWORK( J2 ),
! 469: $ WORK( J2 ), KA1 )
! 470: *
! 471: CALL ZLACGV( NR, WORK( J2 ), KA1 )
! 472: END IF
! 473: *
! 474: * start applying rotations in 2nd set from the left
! 475: *
! 476: DO 190 L = KA - 1, KB - K + 1, -1
! 477: NRT = ( N-J2+L ) / KA1
! 478: IF( NRT.GT.0 )
! 479: $ CALL ZLARTV( NRT, AB( L, J2+KA1-L ), INCA,
! 480: $ AB( L+1, J2+KA1-L ), INCA, RWORK( J2 ),
! 481: $ WORK( J2 ), KA1 )
! 482: 190 CONTINUE
! 483: *
! 484: IF( WANTX ) THEN
! 485: *
! 486: * post-multiply X by product of rotations in 2nd set
! 487: *
! 488: DO 200 J = J2, J1, KA1
! 489: CALL ZROT( N-M, X( M+1, J ), 1, X( M+1, J+1 ), 1,
! 490: $ RWORK( J ), DCONJG( WORK( J ) ) )
! 491: 200 CONTINUE
! 492: END IF
! 493: 210 CONTINUE
! 494: *
! 495: DO 230 K = 1, KB - 1
! 496: J2 = I - K - 1 + MAX( 1, K-I0+2 )*KA1
! 497: *
! 498: * finish applying rotations in 1st set from the left
! 499: *
! 500: DO 220 L = KB - K, 1, -1
! 501: NRT = ( N-J2+L ) / KA1
! 502: IF( NRT.GT.0 )
! 503: $ CALL ZLARTV( NRT, AB( L, J2+KA1-L ), INCA,
! 504: $ AB( L+1, J2+KA1-L ), INCA, RWORK( J2-M ),
! 505: $ WORK( J2-M ), KA1 )
! 506: 220 CONTINUE
! 507: 230 CONTINUE
! 508: *
! 509: IF( KB.GT.1 ) THEN
! 510: DO 240 J = N - 1, I2 + KA, -1
! 511: RWORK( J-M ) = RWORK( J-KA-M )
! 512: WORK( J-M ) = WORK( J-KA-M )
! 513: 240 CONTINUE
! 514: END IF
! 515: *
! 516: ELSE
! 517: *
! 518: * Transform A, working with the lower triangle
! 519: *
! 520: IF( UPDATE ) THEN
! 521: *
! 522: * Form inv(S(i))**H * A * inv(S(i))
! 523: *
! 524: BII = DBLE( BB( 1, I ) )
! 525: AB( 1, I ) = ( DBLE( AB( 1, I ) ) / BII ) / BII
! 526: DO 250 J = I + 1, I1
! 527: AB( J-I+1, I ) = AB( J-I+1, I ) / BII
! 528: 250 CONTINUE
! 529: DO 260 J = MAX( 1, I-KA ), I - 1
! 530: AB( I-J+1, J ) = AB( I-J+1, J ) / BII
! 531: 260 CONTINUE
! 532: DO 290 K = I - KBT, I - 1
! 533: DO 270 J = I - KBT, K
! 534: AB( K-J+1, J ) = AB( K-J+1, J ) -
! 535: $ BB( I-J+1, J )*DCONJG( AB( I-K+1,
! 536: $ K ) ) - DCONJG( BB( I-K+1, K ) )*
! 537: $ AB( I-J+1, J ) + DBLE( AB( 1, I ) )*
! 538: $ BB( I-J+1, J )*DCONJG( BB( I-K+1,
! 539: $ K ) )
! 540: 270 CONTINUE
! 541: DO 280 J = MAX( 1, I-KA ), I - KBT - 1
! 542: AB( K-J+1, J ) = AB( K-J+1, J ) -
! 543: $ DCONJG( BB( I-K+1, K ) )*
! 544: $ AB( I-J+1, J )
! 545: 280 CONTINUE
! 546: 290 CONTINUE
! 547: DO 310 J = I, I1
! 548: DO 300 K = MAX( J-KA, I-KBT ), I - 1
! 549: AB( J-K+1, K ) = AB( J-K+1, K ) -
! 550: $ BB( I-K+1, K )*AB( J-I+1, I )
! 551: 300 CONTINUE
! 552: 310 CONTINUE
! 553: *
! 554: IF( WANTX ) THEN
! 555: *
! 556: * post-multiply X by inv(S(i))
! 557: *
! 558: CALL ZDSCAL( N-M, ONE / BII, X( M+1, I ), 1 )
! 559: IF( KBT.GT.0 )
! 560: $ CALL ZGERU( N-M, KBT, -CONE, X( M+1, I ), 1,
! 561: $ BB( KBT+1, I-KBT ), LDBB-1,
! 562: $ X( M+1, I-KBT ), LDX )
! 563: END IF
! 564: *
! 565: * store a(i1,i) in RA1 for use in next loop over K
! 566: *
! 567: RA1 = AB( I1-I+1, I )
! 568: END IF
! 569: *
! 570: * Generate and apply vectors of rotations to chase all the
! 571: * existing bulges KA positions down toward the bottom of the
! 572: * band
! 573: *
! 574: DO 360 K = 1, KB - 1
! 575: IF( UPDATE ) THEN
! 576: *
! 577: * Determine the rotations which would annihilate the bulge
! 578: * which has in theory just been created
! 579: *
! 580: IF( I-K+KA.LT.N .AND. I-K.GT.1 ) THEN
! 581: *
! 582: * generate rotation to annihilate a(i-k+ka+1,i)
! 583: *
! 584: CALL ZLARTG( AB( KA1-K, I ), RA1, RWORK( I-K+KA-M ),
! 585: $ WORK( I-K+KA-M ), RA )
! 586: *
! 587: * create nonzero element a(i-k+ka+1,i-k) outside the
! 588: * band and store it in WORK(i-k)
! 589: *
! 590: T = -BB( K+1, I-K )*RA1
! 591: WORK( I-K ) = RWORK( I-K+KA-M )*T -
! 592: $ DCONJG( WORK( I-K+KA-M ) )*
! 593: $ AB( KA1, I-K )
! 594: AB( KA1, I-K ) = WORK( I-K+KA-M )*T +
! 595: $ RWORK( I-K+KA-M )*AB( KA1, I-K )
! 596: RA1 = RA
! 597: END IF
! 598: END IF
! 599: J2 = I - K - 1 + MAX( 1, K-I0+2 )*KA1
! 600: NR = ( N-J2+KA ) / KA1
! 601: J1 = J2 + ( NR-1 )*KA1
! 602: IF( UPDATE ) THEN
! 603: J2T = MAX( J2, I+2*KA-K+1 )
! 604: ELSE
! 605: J2T = J2
! 606: END IF
! 607: NRT = ( N-J2T+KA ) / KA1
! 608: DO 320 J = J2T, J1, KA1
! 609: *
! 610: * create nonzero element a(j+1,j-ka) outside the band
! 611: * and store it in WORK(j-m)
! 612: *
! 613: WORK( J-M ) = WORK( J-M )*AB( KA1, J-KA+1 )
! 614: AB( KA1, J-KA+1 ) = RWORK( J-M )*AB( KA1, J-KA+1 )
! 615: 320 CONTINUE
! 616: *
! 617: * generate rotations in 1st set to annihilate elements which
! 618: * have been created outside the band
! 619: *
! 620: IF( NRT.GT.0 )
! 621: $ CALL ZLARGV( NRT, AB( KA1, J2T-KA ), INCA, WORK( J2T-M ),
! 622: $ KA1, RWORK( J2T-M ), KA1 )
! 623: IF( NR.GT.0 ) THEN
! 624: *
! 625: * apply rotations in 1st set from the left
! 626: *
! 627: DO 330 L = 1, KA - 1
! 628: CALL ZLARTV( NR, AB( L+1, J2-L ), INCA,
! 629: $ AB( L+2, J2-L ), INCA, RWORK( J2-M ),
! 630: $ WORK( J2-M ), KA1 )
! 631: 330 CONTINUE
! 632: *
! 633: * apply rotations in 1st set from both sides to diagonal
! 634: * blocks
! 635: *
! 636: CALL ZLAR2V( NR, AB( 1, J2 ), AB( 1, J2+1 ), AB( 2, J2 ),
! 637: $ INCA, RWORK( J2-M ), WORK( J2-M ), KA1 )
! 638: *
! 639: CALL ZLACGV( NR, WORK( J2-M ), KA1 )
! 640: END IF
! 641: *
! 642: * start applying rotations in 1st set from the right
! 643: *
! 644: DO 340 L = KA - 1, KB - K + 1, -1
! 645: NRT = ( N-J2+L ) / KA1
! 646: IF( NRT.GT.0 )
! 647: $ CALL ZLARTV( NRT, AB( KA1-L+1, J2 ), INCA,
! 648: $ AB( KA1-L, J2+1 ), INCA, RWORK( J2-M ),
! 649: $ WORK( J2-M ), KA1 )
! 650: 340 CONTINUE
! 651: *
! 652: IF( WANTX ) THEN
! 653: *
! 654: * post-multiply X by product of rotations in 1st set
! 655: *
! 656: DO 350 J = J2, J1, KA1
! 657: CALL ZROT( N-M, X( M+1, J ), 1, X( M+1, J+1 ), 1,
! 658: $ RWORK( J-M ), WORK( J-M ) )
! 659: 350 CONTINUE
! 660: END IF
! 661: 360 CONTINUE
! 662: *
! 663: IF( UPDATE ) THEN
! 664: IF( I2.LE.N .AND. KBT.GT.0 ) THEN
! 665: *
! 666: * create nonzero element a(i-kbt+ka+1,i-kbt) outside the
! 667: * band and store it in WORK(i-kbt)
! 668: *
! 669: WORK( I-KBT ) = -BB( KBT+1, I-KBT )*RA1
! 670: END IF
! 671: END IF
! 672: *
! 673: DO 400 K = KB, 1, -1
! 674: IF( UPDATE ) THEN
! 675: J2 = I - K - 1 + MAX( 2, K-I0+1 )*KA1
! 676: ELSE
! 677: J2 = I - K - 1 + MAX( 1, K-I0+1 )*KA1
! 678: END IF
! 679: *
! 680: * finish applying rotations in 2nd set from the right
! 681: *
! 682: DO 370 L = KB - K, 1, -1
! 683: NRT = ( N-J2+KA+L ) / KA1
! 684: IF( NRT.GT.0 )
! 685: $ CALL ZLARTV( NRT, AB( KA1-L+1, J2-KA ), INCA,
! 686: $ AB( KA1-L, J2-KA+1 ), INCA,
! 687: $ RWORK( J2-KA ), WORK( J2-KA ), KA1 )
! 688: 370 CONTINUE
! 689: NR = ( N-J2+KA ) / KA1
! 690: J1 = J2 + ( NR-1 )*KA1
! 691: DO 380 J = J1, J2, -KA1
! 692: WORK( J ) = WORK( J-KA )
! 693: RWORK( J ) = RWORK( J-KA )
! 694: 380 CONTINUE
! 695: DO 390 J = J2, J1, KA1
! 696: *
! 697: * create nonzero element a(j+1,j-ka) outside the band
! 698: * and store it in WORK(j)
! 699: *
! 700: WORK( J ) = WORK( J )*AB( KA1, J-KA+1 )
! 701: AB( KA1, J-KA+1 ) = RWORK( J )*AB( KA1, J-KA+1 )
! 702: 390 CONTINUE
! 703: IF( UPDATE ) THEN
! 704: IF( I-K.LT.N-KA .AND. K.LE.KBT )
! 705: $ WORK( I-K+KA ) = WORK( I-K )
! 706: END IF
! 707: 400 CONTINUE
! 708: *
! 709: DO 440 K = KB, 1, -1
! 710: J2 = I - K - 1 + MAX( 1, K-I0+1 )*KA1
! 711: NR = ( N-J2+KA ) / KA1
! 712: J1 = J2 + ( NR-1 )*KA1
! 713: IF( NR.GT.0 ) THEN
! 714: *
! 715: * generate rotations in 2nd set to annihilate elements
! 716: * which have been created outside the band
! 717: *
! 718: CALL ZLARGV( NR, AB( KA1, J2-KA ), INCA, WORK( J2 ), KA1,
! 719: $ RWORK( J2 ), KA1 )
! 720: *
! 721: * apply rotations in 2nd set from the left
! 722: *
! 723: DO 410 L = 1, KA - 1
! 724: CALL ZLARTV( NR, AB( L+1, J2-L ), INCA,
! 725: $ AB( L+2, J2-L ), INCA, RWORK( J2 ),
! 726: $ WORK( J2 ), KA1 )
! 727: 410 CONTINUE
! 728: *
! 729: * apply rotations in 2nd set from both sides to diagonal
! 730: * blocks
! 731: *
! 732: CALL ZLAR2V( NR, AB( 1, J2 ), AB( 1, J2+1 ), AB( 2, J2 ),
! 733: $ INCA, RWORK( J2 ), WORK( J2 ), KA1 )
! 734: *
! 735: CALL ZLACGV( NR, WORK( J2 ), KA1 )
! 736: END IF
! 737: *
! 738: * start applying rotations in 2nd set from the right
! 739: *
! 740: DO 420 L = KA - 1, KB - K + 1, -1
! 741: NRT = ( N-J2+L ) / KA1
! 742: IF( NRT.GT.0 )
! 743: $ CALL ZLARTV( NRT, AB( KA1-L+1, J2 ), INCA,
! 744: $ AB( KA1-L, J2+1 ), INCA, RWORK( J2 ),
! 745: $ WORK( J2 ), KA1 )
! 746: 420 CONTINUE
! 747: *
! 748: IF( WANTX ) THEN
! 749: *
! 750: * post-multiply X by product of rotations in 2nd set
! 751: *
! 752: DO 430 J = J2, J1, KA1
! 753: CALL ZROT( N-M, X( M+1, J ), 1, X( M+1, J+1 ), 1,
! 754: $ RWORK( J ), WORK( J ) )
! 755: 430 CONTINUE
! 756: END IF
! 757: 440 CONTINUE
! 758: *
! 759: DO 460 K = 1, KB - 1
! 760: J2 = I - K - 1 + MAX( 1, K-I0+2 )*KA1
! 761: *
! 762: * finish applying rotations in 1st set from the right
! 763: *
! 764: DO 450 L = KB - K, 1, -1
! 765: NRT = ( N-J2+L ) / KA1
! 766: IF( NRT.GT.0 )
! 767: $ CALL ZLARTV( NRT, AB( KA1-L+1, J2 ), INCA,
! 768: $ AB( KA1-L, J2+1 ), INCA, RWORK( J2-M ),
! 769: $ WORK( J2-M ), KA1 )
! 770: 450 CONTINUE
! 771: 460 CONTINUE
! 772: *
! 773: IF( KB.GT.1 ) THEN
! 774: DO 470 J = N - 1, I2 + KA, -1
! 775: RWORK( J-M ) = RWORK( J-KA-M )
! 776: WORK( J-M ) = WORK( J-KA-M )
! 777: 470 CONTINUE
! 778: END IF
! 779: *
! 780: END IF
! 781: *
! 782: GO TO 10
! 783: *
! 784: 480 CONTINUE
! 785: *
! 786: * **************************** Phase 2 *****************************
! 787: *
! 788: * The logical structure of this phase is:
! 789: *
! 790: * UPDATE = .TRUE.
! 791: * DO I = 1, M
! 792: * use S(i) to update A and create a new bulge
! 793: * apply rotations to push all bulges KA positions upward
! 794: * END DO
! 795: * UPDATE = .FALSE.
! 796: * DO I = M - KA - 1, 2, -1
! 797: * apply rotations to push all bulges KA positions upward
! 798: * END DO
! 799: *
! 800: * To avoid duplicating code, the two loops are merged.
! 801: *
! 802: UPDATE = .TRUE.
! 803: I = 0
! 804: 490 CONTINUE
! 805: IF( UPDATE ) THEN
! 806: I = I + 1
! 807: KBT = MIN( KB, M-I )
! 808: I0 = I + 1
! 809: I1 = MAX( 1, I-KA )
! 810: I2 = I + KBT - KA1
! 811: IF( I.GT.M ) THEN
! 812: UPDATE = .FALSE.
! 813: I = I - 1
! 814: I0 = M + 1
! 815: IF( KA.EQ.0 )
! 816: $ RETURN
! 817: GO TO 490
! 818: END IF
! 819: ELSE
! 820: I = I - KA
! 821: IF( I.LT.2 )
! 822: $ RETURN
! 823: END IF
! 824: *
! 825: IF( I.LT.M-KBT ) THEN
! 826: NX = M
! 827: ELSE
! 828: NX = N
! 829: END IF
! 830: *
! 831: IF( UPPER ) THEN
! 832: *
! 833: * Transform A, working with the upper triangle
! 834: *
! 835: IF( UPDATE ) THEN
! 836: *
! 837: * Form inv(S(i))**H * A * inv(S(i))
! 838: *
! 839: BII = DBLE( BB( KB1, I ) )
! 840: AB( KA1, I ) = ( DBLE( AB( KA1, I ) ) / BII ) / BII
! 841: DO 500 J = I1, I - 1
! 842: AB( J-I+KA1, I ) = AB( J-I+KA1, I ) / BII
! 843: 500 CONTINUE
! 844: DO 510 J = I + 1, MIN( N, I+KA )
! 845: AB( I-J+KA1, J ) = AB( I-J+KA1, J ) / BII
! 846: 510 CONTINUE
! 847: DO 540 K = I + 1, I + KBT
! 848: DO 520 J = K, I + KBT
! 849: AB( K-J+KA1, J ) = AB( K-J+KA1, J ) -
! 850: $ BB( I-J+KB1, J )*
! 851: $ DCONJG( AB( I-K+KA1, K ) ) -
! 852: $ DCONJG( BB( I-K+KB1, K ) )*
! 853: $ AB( I-J+KA1, J ) +
! 854: $ DBLE( AB( KA1, I ) )*
! 855: $ BB( I-J+KB1, J )*
! 856: $ DCONJG( BB( I-K+KB1, K ) )
! 857: 520 CONTINUE
! 858: DO 530 J = I + KBT + 1, MIN( N, I+KA )
! 859: AB( K-J+KA1, J ) = AB( K-J+KA1, J ) -
! 860: $ DCONJG( BB( I-K+KB1, K ) )*
! 861: $ AB( I-J+KA1, J )
! 862: 530 CONTINUE
! 863: 540 CONTINUE
! 864: DO 560 J = I1, I
! 865: DO 550 K = I + 1, MIN( J+KA, I+KBT )
! 866: AB( J-K+KA1, K ) = AB( J-K+KA1, K ) -
! 867: $ BB( I-K+KB1, K )*AB( J-I+KA1, I )
! 868: 550 CONTINUE
! 869: 560 CONTINUE
! 870: *
! 871: IF( WANTX ) THEN
! 872: *
! 873: * post-multiply X by inv(S(i))
! 874: *
! 875: CALL ZDSCAL( NX, ONE / BII, X( 1, I ), 1 )
! 876: IF( KBT.GT.0 )
! 877: $ CALL ZGERU( NX, KBT, -CONE, X( 1, I ), 1,
! 878: $ BB( KB, I+1 ), LDBB-1, X( 1, I+1 ), LDX )
! 879: END IF
! 880: *
! 881: * store a(i1,i) in RA1 for use in next loop over K
! 882: *
! 883: RA1 = AB( I1-I+KA1, I )
! 884: END IF
! 885: *
! 886: * Generate and apply vectors of rotations to chase all the
! 887: * existing bulges KA positions up toward the top of the band
! 888: *
! 889: DO 610 K = 1, KB - 1
! 890: IF( UPDATE ) THEN
! 891: *
! 892: * Determine the rotations which would annihilate the bulge
! 893: * which has in theory just been created
! 894: *
! 895: IF( I+K-KA1.GT.0 .AND. I+K.LT.M ) THEN
! 896: *
! 897: * generate rotation to annihilate a(i+k-ka-1,i)
! 898: *
! 899: CALL ZLARTG( AB( K+1, I ), RA1, RWORK( I+K-KA ),
! 900: $ WORK( I+K-KA ), RA )
! 901: *
! 902: * create nonzero element a(i+k-ka-1,i+k) outside the
! 903: * band and store it in WORK(m-kb+i+k)
! 904: *
! 905: T = -BB( KB1-K, I+K )*RA1
! 906: WORK( M-KB+I+K ) = RWORK( I+K-KA )*T -
! 907: $ DCONJG( WORK( I+K-KA ) )*
! 908: $ AB( 1, I+K )
! 909: AB( 1, I+K ) = WORK( I+K-KA )*T +
! 910: $ RWORK( I+K-KA )*AB( 1, I+K )
! 911: RA1 = RA
! 912: END IF
! 913: END IF
! 914: J2 = I + K + 1 - MAX( 1, K+I0-M+1 )*KA1
! 915: NR = ( J2+KA-1 ) / KA1
! 916: J1 = J2 - ( NR-1 )*KA1
! 917: IF( UPDATE ) THEN
! 918: J2T = MIN( J2, I-2*KA+K-1 )
! 919: ELSE
! 920: J2T = J2
! 921: END IF
! 922: NRT = ( J2T+KA-1 ) / KA1
! 923: DO 570 J = J1, J2T, KA1
! 924: *
! 925: * create nonzero element a(j-1,j+ka) outside the band
! 926: * and store it in WORK(j)
! 927: *
! 928: WORK( J ) = WORK( J )*AB( 1, J+KA-1 )
! 929: AB( 1, J+KA-1 ) = RWORK( J )*AB( 1, J+KA-1 )
! 930: 570 CONTINUE
! 931: *
! 932: * generate rotations in 1st set to annihilate elements which
! 933: * have been created outside the band
! 934: *
! 935: IF( NRT.GT.0 )
! 936: $ CALL ZLARGV( NRT, AB( 1, J1+KA ), INCA, WORK( J1 ), KA1,
! 937: $ RWORK( J1 ), KA1 )
! 938: IF( NR.GT.0 ) THEN
! 939: *
! 940: * apply rotations in 1st set from the left
! 941: *
! 942: DO 580 L = 1, KA - 1
! 943: CALL ZLARTV( NR, AB( KA1-L, J1+L ), INCA,
! 944: $ AB( KA-L, J1+L ), INCA, RWORK( J1 ),
! 945: $ WORK( J1 ), KA1 )
! 946: 580 CONTINUE
! 947: *
! 948: * apply rotations in 1st set from both sides to diagonal
! 949: * blocks
! 950: *
! 951: CALL ZLAR2V( NR, AB( KA1, J1 ), AB( KA1, J1-1 ),
! 952: $ AB( KA, J1 ), INCA, RWORK( J1 ), WORK( J1 ),
! 953: $ KA1 )
! 954: *
! 955: CALL ZLACGV( NR, WORK( J1 ), KA1 )
! 956: END IF
! 957: *
! 958: * start applying rotations in 1st set from the right
! 959: *
! 960: DO 590 L = KA - 1, KB - K + 1, -1
! 961: NRT = ( J2+L-1 ) / KA1
! 962: J1T = J2 - ( NRT-1 )*KA1
! 963: IF( NRT.GT.0 )
! 964: $ CALL ZLARTV( NRT, AB( L, J1T ), INCA,
! 965: $ AB( L+1, J1T-1 ), INCA, RWORK( J1T ),
! 966: $ WORK( J1T ), KA1 )
! 967: 590 CONTINUE
! 968: *
! 969: IF( WANTX ) THEN
! 970: *
! 971: * post-multiply X by product of rotations in 1st set
! 972: *
! 973: DO 600 J = J1, J2, KA1
! 974: CALL ZROT( NX, X( 1, J ), 1, X( 1, J-1 ), 1,
! 975: $ RWORK( J ), WORK( J ) )
! 976: 600 CONTINUE
! 977: END IF
! 978: 610 CONTINUE
! 979: *
! 980: IF( UPDATE ) THEN
! 981: IF( I2.GT.0 .AND. KBT.GT.0 ) THEN
! 982: *
! 983: * create nonzero element a(i+kbt-ka-1,i+kbt) outside the
! 984: * band and store it in WORK(m-kb+i+kbt)
! 985: *
! 986: WORK( M-KB+I+KBT ) = -BB( KB1-KBT, I+KBT )*RA1
! 987: END IF
! 988: END IF
! 989: *
! 990: DO 650 K = KB, 1, -1
! 991: IF( UPDATE ) THEN
! 992: J2 = I + K + 1 - MAX( 2, K+I0-M )*KA1
! 993: ELSE
! 994: J2 = I + K + 1 - MAX( 1, K+I0-M )*KA1
! 995: END IF
! 996: *
! 997: * finish applying rotations in 2nd set from the right
! 998: *
! 999: DO 620 L = KB - K, 1, -1
! 1000: NRT = ( J2+KA+L-1 ) / KA1
! 1001: J1T = J2 - ( NRT-1 )*KA1
! 1002: IF( NRT.GT.0 )
! 1003: $ CALL ZLARTV( NRT, AB( L, J1T+KA ), INCA,
! 1004: $ AB( L+1, J1T+KA-1 ), INCA,
! 1005: $ RWORK( M-KB+J1T+KA ),
! 1006: $ WORK( M-KB+J1T+KA ), KA1 )
! 1007: 620 CONTINUE
! 1008: NR = ( J2+KA-1 ) / KA1
! 1009: J1 = J2 - ( NR-1 )*KA1
! 1010: DO 630 J = J1, J2, KA1
! 1011: WORK( M-KB+J ) = WORK( M-KB+J+KA )
! 1012: RWORK( M-KB+J ) = RWORK( M-KB+J+KA )
! 1013: 630 CONTINUE
! 1014: DO 640 J = J1, J2, KA1
! 1015: *
! 1016: * create nonzero element a(j-1,j+ka) outside the band
! 1017: * and store it in WORK(m-kb+j)
! 1018: *
! 1019: WORK( M-KB+J ) = WORK( M-KB+J )*AB( 1, J+KA-1 )
! 1020: AB( 1, J+KA-1 ) = RWORK( M-KB+J )*AB( 1, J+KA-1 )
! 1021: 640 CONTINUE
! 1022: IF( UPDATE ) THEN
! 1023: IF( I+K.GT.KA1 .AND. K.LE.KBT )
! 1024: $ WORK( M-KB+I+K-KA ) = WORK( M-KB+I+K )
! 1025: END IF
! 1026: 650 CONTINUE
! 1027: *
! 1028: DO 690 K = KB, 1, -1
! 1029: J2 = I + K + 1 - MAX( 1, K+I0-M )*KA1
! 1030: NR = ( J2+KA-1 ) / KA1
! 1031: J1 = J2 - ( NR-1 )*KA1
! 1032: IF( NR.GT.0 ) THEN
! 1033: *
! 1034: * generate rotations in 2nd set to annihilate elements
! 1035: * which have been created outside the band
! 1036: *
! 1037: CALL ZLARGV( NR, AB( 1, J1+KA ), INCA, WORK( M-KB+J1 ),
! 1038: $ KA1, RWORK( M-KB+J1 ), KA1 )
! 1039: *
! 1040: * apply rotations in 2nd set from the left
! 1041: *
! 1042: DO 660 L = 1, KA - 1
! 1043: CALL ZLARTV( NR, AB( KA1-L, J1+L ), INCA,
! 1044: $ AB( KA-L, J1+L ), INCA, RWORK( M-KB+J1 ),
! 1045: $ WORK( M-KB+J1 ), KA1 )
! 1046: 660 CONTINUE
! 1047: *
! 1048: * apply rotations in 2nd set from both sides to diagonal
! 1049: * blocks
! 1050: *
! 1051: CALL ZLAR2V( NR, AB( KA1, J1 ), AB( KA1, J1-1 ),
! 1052: $ AB( KA, J1 ), INCA, RWORK( M-KB+J1 ),
! 1053: $ WORK( M-KB+J1 ), KA1 )
! 1054: *
! 1055: CALL ZLACGV( NR, WORK( M-KB+J1 ), KA1 )
! 1056: END IF
! 1057: *
! 1058: * start applying rotations in 2nd set from the right
! 1059: *
! 1060: DO 670 L = KA - 1, KB - K + 1, -1
! 1061: NRT = ( J2+L-1 ) / KA1
! 1062: J1T = J2 - ( NRT-1 )*KA1
! 1063: IF( NRT.GT.0 )
! 1064: $ CALL ZLARTV( NRT, AB( L, J1T ), INCA,
! 1065: $ AB( L+1, J1T-1 ), INCA,
! 1066: $ RWORK( M-KB+J1T ), WORK( M-KB+J1T ),
! 1067: $ KA1 )
! 1068: 670 CONTINUE
! 1069: *
! 1070: IF( WANTX ) THEN
! 1071: *
! 1072: * post-multiply X by product of rotations in 2nd set
! 1073: *
! 1074: DO 680 J = J1, J2, KA1
! 1075: CALL ZROT( NX, X( 1, J ), 1, X( 1, J-1 ), 1,
! 1076: $ RWORK( M-KB+J ), WORK( M-KB+J ) )
! 1077: 680 CONTINUE
! 1078: END IF
! 1079: 690 CONTINUE
! 1080: *
! 1081: DO 710 K = 1, KB - 1
! 1082: J2 = I + K + 1 - MAX( 1, K+I0-M+1 )*KA1
! 1083: *
! 1084: * finish applying rotations in 1st set from the right
! 1085: *
! 1086: DO 700 L = KB - K, 1, -1
! 1087: NRT = ( J2+L-1 ) / KA1
! 1088: J1T = J2 - ( NRT-1 )*KA1
! 1089: IF( NRT.GT.0 )
! 1090: $ CALL ZLARTV( NRT, AB( L, J1T ), INCA,
! 1091: $ AB( L+1, J1T-1 ), INCA, RWORK( J1T ),
! 1092: $ WORK( J1T ), KA1 )
! 1093: 700 CONTINUE
! 1094: 710 CONTINUE
! 1095: *
! 1096: IF( KB.GT.1 ) THEN
! 1097: DO 720 J = 2, I2 - KA
! 1098: RWORK( J ) = RWORK( J+KA )
! 1099: WORK( J ) = WORK( J+KA )
! 1100: 720 CONTINUE
! 1101: END IF
! 1102: *
! 1103: ELSE
! 1104: *
! 1105: * Transform A, working with the lower triangle
! 1106: *
! 1107: IF( UPDATE ) THEN
! 1108: *
! 1109: * Form inv(S(i))**H * A * inv(S(i))
! 1110: *
! 1111: BII = DBLE( BB( 1, I ) )
! 1112: AB( 1, I ) = ( DBLE( AB( 1, I ) ) / BII ) / BII
! 1113: DO 730 J = I1, I - 1
! 1114: AB( I-J+1, J ) = AB( I-J+1, J ) / BII
! 1115: 730 CONTINUE
! 1116: DO 740 J = I + 1, MIN( N, I+KA )
! 1117: AB( J-I+1, I ) = AB( J-I+1, I ) / BII
! 1118: 740 CONTINUE
! 1119: DO 770 K = I + 1, I + KBT
! 1120: DO 750 J = K, I + KBT
! 1121: AB( J-K+1, K ) = AB( J-K+1, K ) -
! 1122: $ BB( J-I+1, I )*DCONJG( AB( K-I+1,
! 1123: $ I ) ) - DCONJG( BB( K-I+1, I ) )*
! 1124: $ AB( J-I+1, I ) + DBLE( AB( 1, I ) )*
! 1125: $ BB( J-I+1, I )*DCONJG( BB( K-I+1,
! 1126: $ I ) )
! 1127: 750 CONTINUE
! 1128: DO 760 J = I + KBT + 1, MIN( N, I+KA )
! 1129: AB( J-K+1, K ) = AB( J-K+1, K ) -
! 1130: $ DCONJG( BB( K-I+1, I ) )*
! 1131: $ AB( J-I+1, I )
! 1132: 760 CONTINUE
! 1133: 770 CONTINUE
! 1134: DO 790 J = I1, I
! 1135: DO 780 K = I + 1, MIN( J+KA, I+KBT )
! 1136: AB( K-J+1, J ) = AB( K-J+1, J ) -
! 1137: $ BB( K-I+1, I )*AB( I-J+1, J )
! 1138: 780 CONTINUE
! 1139: 790 CONTINUE
! 1140: *
! 1141: IF( WANTX ) THEN
! 1142: *
! 1143: * post-multiply X by inv(S(i))
! 1144: *
! 1145: CALL ZDSCAL( NX, ONE / BII, X( 1, I ), 1 )
! 1146: IF( KBT.GT.0 )
! 1147: $ CALL ZGERC( NX, KBT, -CONE, X( 1, I ), 1, BB( 2, I ),
! 1148: $ 1, X( 1, I+1 ), LDX )
! 1149: END IF
! 1150: *
! 1151: * store a(i,i1) in RA1 for use in next loop over K
! 1152: *
! 1153: RA1 = AB( I-I1+1, I1 )
! 1154: END IF
! 1155: *
! 1156: * Generate and apply vectors of rotations to chase all the
! 1157: * existing bulges KA positions up toward the top of the band
! 1158: *
! 1159: DO 840 K = 1, KB - 1
! 1160: IF( UPDATE ) THEN
! 1161: *
! 1162: * Determine the rotations which would annihilate the bulge
! 1163: * which has in theory just been created
! 1164: *
! 1165: IF( I+K-KA1.GT.0 .AND. I+K.LT.M ) THEN
! 1166: *
! 1167: * generate rotation to annihilate a(i,i+k-ka-1)
! 1168: *
! 1169: CALL ZLARTG( AB( KA1-K, I+K-KA ), RA1,
! 1170: $ RWORK( I+K-KA ), WORK( I+K-KA ), RA )
! 1171: *
! 1172: * create nonzero element a(i+k,i+k-ka-1) outside the
! 1173: * band and store it in WORK(m-kb+i+k)
! 1174: *
! 1175: T = -BB( K+1, I )*RA1
! 1176: WORK( M-KB+I+K ) = RWORK( I+K-KA )*T -
! 1177: $ DCONJG( WORK( I+K-KA ) )*
! 1178: $ AB( KA1, I+K-KA )
! 1179: AB( KA1, I+K-KA ) = WORK( I+K-KA )*T +
! 1180: $ RWORK( I+K-KA )*AB( KA1, I+K-KA )
! 1181: RA1 = RA
! 1182: END IF
! 1183: END IF
! 1184: J2 = I + K + 1 - MAX( 1, K+I0-M+1 )*KA1
! 1185: NR = ( J2+KA-1 ) / KA1
! 1186: J1 = J2 - ( NR-1 )*KA1
! 1187: IF( UPDATE ) THEN
! 1188: J2T = MIN( J2, I-2*KA+K-1 )
! 1189: ELSE
! 1190: J2T = J2
! 1191: END IF
! 1192: NRT = ( J2T+KA-1 ) / KA1
! 1193: DO 800 J = J1, J2T, KA1
! 1194: *
! 1195: * create nonzero element a(j+ka,j-1) outside the band
! 1196: * and store it in WORK(j)
! 1197: *
! 1198: WORK( J ) = WORK( J )*AB( KA1, J-1 )
! 1199: AB( KA1, J-1 ) = RWORK( J )*AB( KA1, J-1 )
! 1200: 800 CONTINUE
! 1201: *
! 1202: * generate rotations in 1st set to annihilate elements which
! 1203: * have been created outside the band
! 1204: *
! 1205: IF( NRT.GT.0 )
! 1206: $ CALL ZLARGV( NRT, AB( KA1, J1 ), INCA, WORK( J1 ), KA1,
! 1207: $ RWORK( J1 ), KA1 )
! 1208: IF( NR.GT.0 ) THEN
! 1209: *
! 1210: * apply rotations in 1st set from the right
! 1211: *
! 1212: DO 810 L = 1, KA - 1
! 1213: CALL ZLARTV( NR, AB( L+1, J1 ), INCA, AB( L+2, J1-1 ),
! 1214: $ INCA, RWORK( J1 ), WORK( J1 ), KA1 )
! 1215: 810 CONTINUE
! 1216: *
! 1217: * apply rotations in 1st set from both sides to diagonal
! 1218: * blocks
! 1219: *
! 1220: CALL ZLAR2V( NR, AB( 1, J1 ), AB( 1, J1-1 ),
! 1221: $ AB( 2, J1-1 ), INCA, RWORK( J1 ),
! 1222: $ WORK( J1 ), KA1 )
! 1223: *
! 1224: CALL ZLACGV( NR, WORK( J1 ), KA1 )
! 1225: END IF
! 1226: *
! 1227: * start applying rotations in 1st set from the left
! 1228: *
! 1229: DO 820 L = KA - 1, KB - K + 1, -1
! 1230: NRT = ( J2+L-1 ) / KA1
! 1231: J1T = J2 - ( NRT-1 )*KA1
! 1232: IF( NRT.GT.0 )
! 1233: $ CALL ZLARTV( NRT, AB( KA1-L+1, J1T-KA1+L ), INCA,
! 1234: $ AB( KA1-L, J1T-KA1+L ), INCA,
! 1235: $ RWORK( J1T ), WORK( J1T ), KA1 )
! 1236: 820 CONTINUE
! 1237: *
! 1238: IF( WANTX ) THEN
! 1239: *
! 1240: * post-multiply X by product of rotations in 1st set
! 1241: *
! 1242: DO 830 J = J1, J2, KA1
! 1243: CALL ZROT( NX, X( 1, J ), 1, X( 1, J-1 ), 1,
! 1244: $ RWORK( J ), DCONJG( WORK( J ) ) )
! 1245: 830 CONTINUE
! 1246: END IF
! 1247: 840 CONTINUE
! 1248: *
! 1249: IF( UPDATE ) THEN
! 1250: IF( I2.GT.0 .AND. KBT.GT.0 ) THEN
! 1251: *
! 1252: * create nonzero element a(i+kbt,i+kbt-ka-1) outside the
! 1253: * band and store it in WORK(m-kb+i+kbt)
! 1254: *
! 1255: WORK( M-KB+I+KBT ) = -BB( KBT+1, I )*RA1
! 1256: END IF
! 1257: END IF
! 1258: *
! 1259: DO 880 K = KB, 1, -1
! 1260: IF( UPDATE ) THEN
! 1261: J2 = I + K + 1 - MAX( 2, K+I0-M )*KA1
! 1262: ELSE
! 1263: J2 = I + K + 1 - MAX( 1, K+I0-M )*KA1
! 1264: END IF
! 1265: *
! 1266: * finish applying rotations in 2nd set from the left
! 1267: *
! 1268: DO 850 L = KB - K, 1, -1
! 1269: NRT = ( J2+KA+L-1 ) / KA1
! 1270: J1T = J2 - ( NRT-1 )*KA1
! 1271: IF( NRT.GT.0 )
! 1272: $ CALL ZLARTV( NRT, AB( KA1-L+1, J1T+L-1 ), INCA,
! 1273: $ AB( KA1-L, J1T+L-1 ), INCA,
! 1274: $ RWORK( M-KB+J1T+KA ),
! 1275: $ WORK( M-KB+J1T+KA ), KA1 )
! 1276: 850 CONTINUE
! 1277: NR = ( J2+KA-1 ) / KA1
! 1278: J1 = J2 - ( NR-1 )*KA1
! 1279: DO 860 J = J1, J2, KA1
! 1280: WORK( M-KB+J ) = WORK( M-KB+J+KA )
! 1281: RWORK( M-KB+J ) = RWORK( M-KB+J+KA )
! 1282: 860 CONTINUE
! 1283: DO 870 J = J1, J2, KA1
! 1284: *
! 1285: * create nonzero element a(j+ka,j-1) outside the band
! 1286: * and store it in WORK(m-kb+j)
! 1287: *
! 1288: WORK( M-KB+J ) = WORK( M-KB+J )*AB( KA1, J-1 )
! 1289: AB( KA1, J-1 ) = RWORK( M-KB+J )*AB( KA1, J-1 )
! 1290: 870 CONTINUE
! 1291: IF( UPDATE ) THEN
! 1292: IF( I+K.GT.KA1 .AND. K.LE.KBT )
! 1293: $ WORK( M-KB+I+K-KA ) = WORK( M-KB+I+K )
! 1294: END IF
! 1295: 880 CONTINUE
! 1296: *
! 1297: DO 920 K = KB, 1, -1
! 1298: J2 = I + K + 1 - MAX( 1, K+I0-M )*KA1
! 1299: NR = ( J2+KA-1 ) / KA1
! 1300: J1 = J2 - ( NR-1 )*KA1
! 1301: IF( NR.GT.0 ) THEN
! 1302: *
! 1303: * generate rotations in 2nd set to annihilate elements
! 1304: * which have been created outside the band
! 1305: *
! 1306: CALL ZLARGV( NR, AB( KA1, J1 ), INCA, WORK( M-KB+J1 ),
! 1307: $ KA1, RWORK( M-KB+J1 ), KA1 )
! 1308: *
! 1309: * apply rotations in 2nd set from the right
! 1310: *
! 1311: DO 890 L = 1, KA - 1
! 1312: CALL ZLARTV( NR, AB( L+1, J1 ), INCA, AB( L+2, J1-1 ),
! 1313: $ INCA, RWORK( M-KB+J1 ), WORK( M-KB+J1 ),
! 1314: $ KA1 )
! 1315: 890 CONTINUE
! 1316: *
! 1317: * apply rotations in 2nd set from both sides to diagonal
! 1318: * blocks
! 1319: *
! 1320: CALL ZLAR2V( NR, AB( 1, J1 ), AB( 1, J1-1 ),
! 1321: $ AB( 2, J1-1 ), INCA, RWORK( M-KB+J1 ),
! 1322: $ WORK( M-KB+J1 ), KA1 )
! 1323: *
! 1324: CALL ZLACGV( NR, WORK( M-KB+J1 ), KA1 )
! 1325: END IF
! 1326: *
! 1327: * start applying rotations in 2nd set from the left
! 1328: *
! 1329: DO 900 L = KA - 1, KB - K + 1, -1
! 1330: NRT = ( J2+L-1 ) / KA1
! 1331: J1T = J2 - ( NRT-1 )*KA1
! 1332: IF( NRT.GT.0 )
! 1333: $ CALL ZLARTV( NRT, AB( KA1-L+1, J1T-KA1+L ), INCA,
! 1334: $ AB( KA1-L, J1T-KA1+L ), INCA,
! 1335: $ RWORK( M-KB+J1T ), WORK( M-KB+J1T ),
! 1336: $ KA1 )
! 1337: 900 CONTINUE
! 1338: *
! 1339: IF( WANTX ) THEN
! 1340: *
! 1341: * post-multiply X by product of rotations in 2nd set
! 1342: *
! 1343: DO 910 J = J1, J2, KA1
! 1344: CALL ZROT( NX, X( 1, J ), 1, X( 1, J-1 ), 1,
! 1345: $ RWORK( M-KB+J ), DCONJG( WORK( M-KB+J ) ) )
! 1346: 910 CONTINUE
! 1347: END IF
! 1348: 920 CONTINUE
! 1349: *
! 1350: DO 940 K = 1, KB - 1
! 1351: J2 = I + K + 1 - MAX( 1, K+I0-M+1 )*KA1
! 1352: *
! 1353: * finish applying rotations in 1st set from the left
! 1354: *
! 1355: DO 930 L = KB - K, 1, -1
! 1356: NRT = ( J2+L-1 ) / KA1
! 1357: J1T = J2 - ( NRT-1 )*KA1
! 1358: IF( NRT.GT.0 )
! 1359: $ CALL ZLARTV( NRT, AB( KA1-L+1, J1T-KA1+L ), INCA,
! 1360: $ AB( KA1-L, J1T-KA1+L ), INCA,
! 1361: $ RWORK( J1T ), WORK( J1T ), KA1 )
! 1362: 930 CONTINUE
! 1363: 940 CONTINUE
! 1364: *
! 1365: IF( KB.GT.1 ) THEN
! 1366: DO 950 J = 2, I2 - KA
! 1367: RWORK( J ) = RWORK( J+KA )
! 1368: WORK( J ) = WORK( J+KA )
! 1369: 950 CONTINUE
! 1370: END IF
! 1371: *
! 1372: END IF
! 1373: *
! 1374: GO TO 490
! 1375: *
! 1376: * End of ZHBGST
! 1377: *
! 1378: END
CVSweb interface <joel.bertrand@systella.fr>