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