1 SUBROUTINE DSBGST( VECT, UPLO, N, KA, KB, AB, LDAB, BB, LDBB, X, 2 $ LDX, WORK, INFO ) 3* 4* -- LAPACK routine (version 3.0) -- 5* Univ. of Tennessee, Univ. of California Berkeley, NAG Ltd., 6* Courant Institute, Argonne National Lab, and Rice University 7* June 30, 1999 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 ) 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 1347