LAPACK 3.3.0
|
00001 SUBROUTINE CHBGST( VECT, UPLO, N, KA, KB, AB, LDAB, BB, LDBB, X, 00002 $ LDX, WORK, RWORK, INFO ) 00003 * 00004 * -- LAPACK routine (version 3.2.2) -- 00005 * -- LAPACK is a software package provided by Univ. of Tennessee, -- 00006 * -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..-- 00007 * June 2010 00008 * 00009 * .. Scalar Arguments .. 00010 CHARACTER UPLO, VECT 00011 INTEGER INFO, KA, KB, LDAB, LDBB, LDX, N 00012 * .. 00013 * .. Array Arguments .. 00014 REAL RWORK( * ) 00015 COMPLEX AB( LDAB, * ), BB( LDBB, * ), WORK( * ), 00016 $ X( LDX, * ) 00017 * .. 00018 * 00019 * Purpose 00020 * ======= 00021 * 00022 * CHBGST reduces a complex Hermitian-definite banded generalized 00023 * eigenproblem A*x = lambda*B*x to standard form C*y = lambda*y, 00024 * such that C has the same bandwidth as A. 00025 * 00026 * B must have been previously factorized as S**H*S by CPBSTF, using a 00027 * split Cholesky factorization. A is overwritten by C = X**H*A*X, where 00028 * X = S**(-1)*Q and Q is a unitary matrix chosen to preserve the 00029 * bandwidth of A. 00030 * 00031 * Arguments 00032 * ========= 00033 * 00034 * VECT (input) CHARACTER*1 00035 * = 'N': do not form the transformation matrix X; 00036 * = 'V': form X. 00037 * 00038 * UPLO (input) CHARACTER*1 00039 * = 'U': Upper triangle of A is stored; 00040 * = 'L': Lower triangle of A is stored. 00041 * 00042 * N (input) INTEGER 00043 * The order of the matrices A and B. N >= 0. 00044 * 00045 * KA (input) INTEGER 00046 * The number of superdiagonals of the matrix A if UPLO = 'U', 00047 * or the number of subdiagonals if UPLO = 'L'. KA >= 0. 00048 * 00049 * KB (input) INTEGER 00050 * The number of superdiagonals of the matrix B if UPLO = 'U', 00051 * or the number of subdiagonals if UPLO = 'L'. KA >= KB >= 0. 00052 * 00053 * AB (input/output) COMPLEX array, dimension (LDAB,N) 00054 * On entry, the upper or lower triangle of the Hermitian band 00055 * matrix A, stored in the first ka+1 rows of the array. The 00056 * j-th column of A is stored in the j-th column of the array AB 00057 * as follows: 00058 * if UPLO = 'U', AB(ka+1+i-j,j) = A(i,j) for max(1,j-ka)<=i<=j; 00059 * if UPLO = 'L', AB(1+i-j,j) = A(i,j) for j<=i<=min(n,j+ka). 00060 * 00061 * On exit, the transformed matrix X**H*A*X, stored in the same 00062 * format as A. 00063 * 00064 * LDAB (input) INTEGER 00065 * The leading dimension of the array AB. LDAB >= KA+1. 00066 * 00067 * BB (input) COMPLEX array, dimension (LDBB,N) 00068 * The banded factor S from the split Cholesky factorization of 00069 * B, as returned by CPBSTF, stored in the first kb+1 rows of 00070 * the array. 00071 * 00072 * LDBB (input) INTEGER 00073 * The leading dimension of the array BB. LDBB >= KB+1. 00074 * 00075 * X (output) COMPLEX array, dimension (LDX,N) 00076 * If VECT = 'V', the n-by-n matrix X. 00077 * If VECT = 'N', the array X is not referenced. 00078 * 00079 * LDX (input) INTEGER 00080 * The leading dimension of the array X. 00081 * LDX >= max(1,N) if VECT = 'V'; LDX >= 1 otherwise. 00082 * 00083 * WORK (workspace) COMPLEX array, dimension (N) 00084 * 00085 * RWORK (workspace) REAL array, dimension (N) 00086 * 00087 * INFO (output) INTEGER 00088 * = 0: successful exit 00089 * < 0: if INFO = -i, the i-th argument had an illegal value. 00090 * 00091 * ===================================================================== 00092 * 00093 * .. Parameters .. 00094 COMPLEX CZERO, CONE 00095 REAL ONE 00096 PARAMETER ( CZERO = ( 0.0E+0, 0.0E+0 ), 00097 $ CONE = ( 1.0E+0, 0.0E+0 ), ONE = 1.0E+0 ) 00098 * .. 00099 * .. Local Scalars .. 00100 LOGICAL UPDATE, UPPER, WANTX 00101 INTEGER I, I0, I1, I2, INCA, J, J1, J1T, J2, J2T, K, 00102 $ KA1, KB1, KBT, L, M, NR, NRT, NX 00103 REAL BII 00104 COMPLEX RA, RA1, T 00105 * .. 00106 * .. External Functions .. 00107 LOGICAL LSAME 00108 EXTERNAL LSAME 00109 * .. 00110 * .. External Subroutines .. 00111 EXTERNAL CGERC, CGERU, CLACGV, CLAR2V, CLARGV, CLARTG, 00112 $ CLARTV, CLASET, CROT, CSSCAL, XERBLA 00113 * .. 00114 * .. Intrinsic Functions .. 00115 INTRINSIC CONJG, MAX, MIN, REAL 00116 * .. 00117 * .. Executable Statements .. 00118 * 00119 * Test the input parameters 00120 * 00121 WANTX = LSAME( VECT, 'V' ) 00122 UPPER = LSAME( UPLO, 'U' ) 00123 KA1 = KA + 1 00124 KB1 = KB + 1 00125 INFO = 0 00126 IF( .NOT.WANTX .AND. .NOT.LSAME( VECT, 'N' ) ) THEN 00127 INFO = -1 00128 ELSE IF( .NOT.UPPER .AND. .NOT.LSAME( UPLO, 'L' ) ) THEN 00129 INFO = -2 00130 ELSE IF( N.LT.0 ) THEN 00131 INFO = -3 00132 ELSE IF( KA.LT.0 ) THEN 00133 INFO = -4 00134 ELSE IF( KB.LT.0 .OR. KB.GT.KA ) THEN 00135 INFO = -5 00136 ELSE IF( LDAB.LT.KA+1 ) THEN 00137 INFO = -7 00138 ELSE IF( LDBB.LT.KB+1 ) THEN 00139 INFO = -9 00140 ELSE IF( LDX.LT.1 .OR. WANTX .AND. LDX.LT.MAX( 1, N ) ) THEN 00141 INFO = -11 00142 END IF 00143 IF( INFO.NE.0 ) THEN 00144 CALL XERBLA( 'CHBGST', -INFO ) 00145 RETURN 00146 END IF 00147 * 00148 * Quick return if possible 00149 * 00150 IF( N.EQ.0 ) 00151 $ RETURN 00152 * 00153 INCA = LDAB*KA1 00154 * 00155 * Initialize X to the unit matrix, if needed 00156 * 00157 IF( WANTX ) 00158 $ CALL CLASET( 'Full', N, N, CZERO, CONE, X, LDX ) 00159 * 00160 * Set M to the splitting point m. It must be the same value as is 00161 * used in CPBSTF. The chosen value allows the arrays WORK and RWORK 00162 * to be of dimension (N). 00163 * 00164 M = ( N+KB ) / 2 00165 * 00166 * The routine works in two phases, corresponding to the two halves 00167 * of the split Cholesky factorization of B as S**H*S where 00168 * 00169 * S = ( U ) 00170 * ( M L ) 00171 * 00172 * with U upper triangular of order m, and L lower triangular of 00173 * order n-m. S has the same bandwidth as B. 00174 * 00175 * S is treated as a product of elementary matrices: 00176 * 00177 * S = S(m)*S(m-1)*...*S(2)*S(1)*S(m+1)*S(m+2)*...*S(n-1)*S(n) 00178 * 00179 * where S(i) is determined by the i-th row of S. 00180 * 00181 * In phase 1, the index i takes the values n, n-1, ... , m+1; 00182 * in phase 2, it takes the values 1, 2, ... , m. 00183 * 00184 * For each value of i, the current matrix A is updated by forming 00185 * inv(S(i))**H*A*inv(S(i)). This creates a triangular bulge outside 00186 * the band of A. The bulge is then pushed down toward the bottom of 00187 * A in phase 1, and up toward the top of A in phase 2, by applying 00188 * plane rotations. 00189 * 00190 * There are kb*(kb+1)/2 elements in the bulge, but at most 2*kb-1 00191 * of them are linearly independent, so annihilating a bulge requires 00192 * only 2*kb-1 plane rotations. The rotations are divided into a 1st 00193 * set of kb-1 rotations, and a 2nd set of kb rotations. 00194 * 00195 * Wherever possible, rotations are generated and applied in vector 00196 * operations of length NR between the indices J1 and J2 (sometimes 00197 * replaced by modified values NRT, J1T or J2T). 00198 * 00199 * The real cosines and complex sines of the rotations are stored in 00200 * the arrays RWORK and WORK, those of the 1st set in elements 00201 * 2:m-kb-1, and those of the 2nd set in elements m-kb+1:n. 00202 * 00203 * The bulges are not formed explicitly; nonzero elements outside the 00204 * band are created only when they are required for generating new 00205 * rotations; they are stored in the array WORK, in positions where 00206 * they are later overwritten by the sines of the rotations which 00207 * annihilate them. 00208 * 00209 * **************************** Phase 1 ***************************** 00210 * 00211 * The logical structure of this phase is: 00212 * 00213 * UPDATE = .TRUE. 00214 * DO I = N, M + 1, -1 00215 * use S(i) to update A and create a new bulge 00216 * apply rotations to push all bulges KA positions downward 00217 * END DO 00218 * UPDATE = .FALSE. 00219 * DO I = M + KA + 1, N - 1 00220 * apply rotations to push all bulges KA positions downward 00221 * END DO 00222 * 00223 * To avoid duplicating code, the two loops are merged. 00224 * 00225 UPDATE = .TRUE. 00226 I = N + 1 00227 10 CONTINUE 00228 IF( UPDATE ) THEN 00229 I = I - 1 00230 KBT = MIN( KB, I-1 ) 00231 I0 = I - 1 00232 I1 = MIN( N, I+KA ) 00233 I2 = I - KBT + KA1 00234 IF( I.LT.M+1 ) THEN 00235 UPDATE = .FALSE. 00236 I = I + 1 00237 I0 = M 00238 IF( KA.EQ.0 ) 00239 $ GO TO 480 00240 GO TO 10 00241 END IF 00242 ELSE 00243 I = I + KA 00244 IF( I.GT.N-1 ) 00245 $ GO TO 480 00246 END IF 00247 * 00248 IF( UPPER ) THEN 00249 * 00250 * Transform A, working with the upper triangle 00251 * 00252 IF( UPDATE ) THEN 00253 * 00254 * Form inv(S(i))**H * A * inv(S(i)) 00255 * 00256 BII = REAL( BB( KB1, I ) ) 00257 AB( KA1, I ) = ( REAL( AB( KA1, I ) ) / BII ) / BII 00258 DO 20 J = I + 1, I1 00259 AB( I-J+KA1, J ) = AB( I-J+KA1, J ) / BII 00260 20 CONTINUE 00261 DO 30 J = MAX( 1, I-KA ), I - 1 00262 AB( J-I+KA1, I ) = AB( J-I+KA1, I ) / BII 00263 30 CONTINUE 00264 DO 60 K = I - KBT, I - 1 00265 DO 40 J = I - KBT, K 00266 AB( J-K+KA1, K ) = AB( J-K+KA1, K ) - 00267 $ BB( J-I+KB1, I )* 00268 $ CONJG( AB( K-I+KA1, I ) ) - 00269 $ CONJG( BB( K-I+KB1, I ) )* 00270 $ AB( J-I+KA1, I ) + 00271 $ REAL( AB( KA1, I ) )* 00272 $ BB( J-I+KB1, I )* 00273 $ CONJG( BB( K-I+KB1, I ) ) 00274 40 CONTINUE 00275 DO 50 J = MAX( 1, I-KA ), I - KBT - 1 00276 AB( J-K+KA1, K ) = AB( J-K+KA1, K ) - 00277 $ CONJG( BB( K-I+KB1, I ) )* 00278 $ AB( J-I+KA1, I ) 00279 50 CONTINUE 00280 60 CONTINUE 00281 DO 80 J = I, I1 00282 DO 70 K = MAX( J-KA, I-KBT ), I - 1 00283 AB( K-J+KA1, J ) = AB( K-J+KA1, J ) - 00284 $ BB( K-I+KB1, I )*AB( I-J+KA1, J ) 00285 70 CONTINUE 00286 80 CONTINUE 00287 * 00288 IF( WANTX ) THEN 00289 * 00290 * post-multiply X by inv(S(i)) 00291 * 00292 CALL CSSCAL( N-M, ONE / BII, X( M+1, I ), 1 ) 00293 IF( KBT.GT.0 ) 00294 $ CALL CGERC( N-M, KBT, -CONE, X( M+1, I ), 1, 00295 $ BB( KB1-KBT, I ), 1, X( M+1, I-KBT ), 00296 $ LDX ) 00297 END IF 00298 * 00299 * store a(i,i1) in RA1 for use in next loop over K 00300 * 00301 RA1 = AB( I-I1+KA1, I1 ) 00302 END IF 00303 * 00304 * Generate and apply vectors of rotations to chase all the 00305 * existing bulges KA positions down toward the bottom of the 00306 * band 00307 * 00308 DO 130 K = 1, KB - 1 00309 IF( UPDATE ) THEN 00310 * 00311 * Determine the rotations which would annihilate the bulge 00312 * which has in theory just been created 00313 * 00314 IF( I-K+KA.LT.N .AND. I-K.GT.1 ) THEN 00315 * 00316 * generate rotation to annihilate a(i,i-k+ka+1) 00317 * 00318 CALL CLARTG( AB( K+1, I-K+KA ), RA1, 00319 $ RWORK( I-K+KA-M ), WORK( I-K+KA-M ), RA ) 00320 * 00321 * create nonzero element a(i-k,i-k+ka+1) outside the 00322 * band and store it in WORK(i-k) 00323 * 00324 T = -BB( KB1-K, I )*RA1 00325 WORK( I-K ) = RWORK( I-K+KA-M )*T - 00326 $ CONJG( WORK( I-K+KA-M ) )* 00327 $ AB( 1, I-K+KA ) 00328 AB( 1, I-K+KA ) = WORK( I-K+KA-M )*T + 00329 $ RWORK( I-K+KA-M )*AB( 1, I-K+KA ) 00330 RA1 = RA 00331 END IF 00332 END IF 00333 J2 = I - K - 1 + MAX( 1, K-I0+2 )*KA1 00334 NR = ( N-J2+KA ) / KA1 00335 J1 = J2 + ( NR-1 )*KA1 00336 IF( UPDATE ) THEN 00337 J2T = MAX( J2, I+2*KA-K+1 ) 00338 ELSE 00339 J2T = J2 00340 END IF 00341 NRT = ( N-J2T+KA ) / KA1 00342 DO 90 J = J2T, J1, KA1 00343 * 00344 * create nonzero element a(j-ka,j+1) outside the band 00345 * and store it in WORK(j-m) 00346 * 00347 WORK( J-M ) = WORK( J-M )*AB( 1, J+1 ) 00348 AB( 1, J+1 ) = RWORK( J-M )*AB( 1, J+1 ) 00349 90 CONTINUE 00350 * 00351 * generate rotations in 1st set to annihilate elements which 00352 * have been created outside the band 00353 * 00354 IF( NRT.GT.0 ) 00355 $ CALL CLARGV( NRT, AB( 1, J2T ), INCA, WORK( J2T-M ), KA1, 00356 $ RWORK( J2T-M ), KA1 ) 00357 IF( NR.GT.0 ) THEN 00358 * 00359 * apply rotations in 1st set from the right 00360 * 00361 DO 100 L = 1, KA - 1 00362 CALL CLARTV( NR, AB( KA1-L, J2 ), INCA, 00363 $ AB( KA-L, J2+1 ), INCA, RWORK( J2-M ), 00364 $ WORK( J2-M ), KA1 ) 00365 100 CONTINUE 00366 * 00367 * apply rotations in 1st set from both sides to diagonal 00368 * blocks 00369 * 00370 CALL CLAR2V( NR, AB( KA1, J2 ), AB( KA1, J2+1 ), 00371 $ AB( KA, J2+1 ), INCA, RWORK( J2-M ), 00372 $ WORK( J2-M ), KA1 ) 00373 * 00374 CALL CLACGV( NR, WORK( J2-M ), KA1 ) 00375 END IF 00376 * 00377 * start applying rotations in 1st set from the left 00378 * 00379 DO 110 L = KA - 1, KB - K + 1, -1 00380 NRT = ( N-J2+L ) / KA1 00381 IF( NRT.GT.0 ) 00382 $ CALL CLARTV( NRT, AB( L, J2+KA1-L ), INCA, 00383 $ AB( L+1, J2+KA1-L ), INCA, RWORK( J2-M ), 00384 $ WORK( J2-M ), KA1 ) 00385 110 CONTINUE 00386 * 00387 IF( WANTX ) THEN 00388 * 00389 * post-multiply X by product of rotations in 1st set 00390 * 00391 DO 120 J = J2, J1, KA1 00392 CALL CROT( N-M, X( M+1, J ), 1, X( M+1, J+1 ), 1, 00393 $ RWORK( J-M ), CONJG( WORK( J-M ) ) ) 00394 120 CONTINUE 00395 END IF 00396 130 CONTINUE 00397 * 00398 IF( UPDATE ) THEN 00399 IF( I2.LE.N .AND. KBT.GT.0 ) THEN 00400 * 00401 * create nonzero element a(i-kbt,i-kbt+ka+1) outside the 00402 * band and store it in WORK(i-kbt) 00403 * 00404 WORK( I-KBT ) = -BB( KB1-KBT, I )*RA1 00405 END IF 00406 END IF 00407 * 00408 DO 170 K = KB, 1, -1 00409 IF( UPDATE ) THEN 00410 J2 = I - K - 1 + MAX( 2, K-I0+1 )*KA1 00411 ELSE 00412 J2 = I - K - 1 + MAX( 1, K-I0+1 )*KA1 00413 END IF 00414 * 00415 * finish applying rotations in 2nd set from the left 00416 * 00417 DO 140 L = KB - K, 1, -1 00418 NRT = ( N-J2+KA+L ) / KA1 00419 IF( NRT.GT.0 ) 00420 $ CALL CLARTV( NRT, AB( L, J2-L+1 ), INCA, 00421 $ AB( L+1, J2-L+1 ), INCA, RWORK( J2-KA ), 00422 $ WORK( J2-KA ), KA1 ) 00423 140 CONTINUE 00424 NR = ( N-J2+KA ) / KA1 00425 J1 = J2 + ( NR-1 )*KA1 00426 DO 150 J = J1, J2, -KA1 00427 WORK( J ) = WORK( J-KA ) 00428 RWORK( J ) = RWORK( J-KA ) 00429 150 CONTINUE 00430 DO 160 J = J2, J1, KA1 00431 * 00432 * create nonzero element a(j-ka,j+1) outside the band 00433 * and store it in WORK(j) 00434 * 00435 WORK( J ) = WORK( J )*AB( 1, J+1 ) 00436 AB( 1, J+1 ) = RWORK( J )*AB( 1, J+1 ) 00437 160 CONTINUE 00438 IF( UPDATE ) THEN 00439 IF( I-K.LT.N-KA .AND. K.LE.KBT ) 00440 $ WORK( I-K+KA ) = WORK( I-K ) 00441 END IF 00442 170 CONTINUE 00443 * 00444 DO 210 K = KB, 1, -1 00445 J2 = I - K - 1 + MAX( 1, K-I0+1 )*KA1 00446 NR = ( N-J2+KA ) / KA1 00447 J1 = J2 + ( NR-1 )*KA1 00448 IF( NR.GT.0 ) THEN 00449 * 00450 * generate rotations in 2nd set to annihilate elements 00451 * which have been created outside the band 00452 * 00453 CALL CLARGV( NR, AB( 1, J2 ), INCA, WORK( J2 ), KA1, 00454 $ RWORK( J2 ), KA1 ) 00455 * 00456 * apply rotations in 2nd set from the right 00457 * 00458 DO 180 L = 1, KA - 1 00459 CALL CLARTV( NR, AB( KA1-L, J2 ), INCA, 00460 $ AB( KA-L, J2+1 ), INCA, RWORK( J2 ), 00461 $ WORK( J2 ), KA1 ) 00462 180 CONTINUE 00463 * 00464 * apply rotations in 2nd set from both sides to diagonal 00465 * blocks 00466 * 00467 CALL CLAR2V( NR, AB( KA1, J2 ), AB( KA1, J2+1 ), 00468 $ AB( KA, J2+1 ), INCA, RWORK( J2 ), 00469 $ WORK( J2 ), KA1 ) 00470 * 00471 CALL CLACGV( NR, WORK( J2 ), KA1 ) 00472 END IF 00473 * 00474 * start applying rotations in 2nd set from the left 00475 * 00476 DO 190 L = KA - 1, KB - K + 1, -1 00477 NRT = ( N-J2+L ) / KA1 00478 IF( NRT.GT.0 ) 00479 $ CALL CLARTV( NRT, AB( L, J2+KA1-L ), INCA, 00480 $ AB( L+1, J2+KA1-L ), INCA, RWORK( J2 ), 00481 $ WORK( J2 ), KA1 ) 00482 190 CONTINUE 00483 * 00484 IF( WANTX ) THEN 00485 * 00486 * post-multiply X by product of rotations in 2nd set 00487 * 00488 DO 200 J = J2, J1, KA1 00489 CALL CROT( N-M, X( M+1, J ), 1, X( M+1, J+1 ), 1, 00490 $ RWORK( J ), CONJG( WORK( J ) ) ) 00491 200 CONTINUE 00492 END IF 00493 210 CONTINUE 00494 * 00495 DO 230 K = 1, KB - 1 00496 J2 = I - K - 1 + MAX( 1, K-I0+2 )*KA1 00497 * 00498 * finish applying rotations in 1st set from the left 00499 * 00500 DO 220 L = KB - K, 1, -1 00501 NRT = ( N-J2+L ) / KA1 00502 IF( NRT.GT.0 ) 00503 $ CALL CLARTV( NRT, AB( L, J2+KA1-L ), INCA, 00504 $ AB( L+1, J2+KA1-L ), INCA, RWORK( J2-M ), 00505 $ WORK( J2-M ), KA1 ) 00506 220 CONTINUE 00507 230 CONTINUE 00508 * 00509 IF( KB.GT.1 ) THEN 00510 DO 240 J = N - 1, J2 + KA, -1 00511 RWORK( J-M ) = RWORK( J-KA-M ) 00512 WORK( J-M ) = WORK( J-KA-M ) 00513 240 CONTINUE 00514 END IF 00515 * 00516 ELSE 00517 * 00518 * Transform A, working with the lower triangle 00519 * 00520 IF( UPDATE ) THEN 00521 * 00522 * Form inv(S(i))**H * A * inv(S(i)) 00523 * 00524 BII = REAL( BB( 1, I ) ) 00525 AB( 1, I ) = ( REAL( AB( 1, I ) ) / BII ) / BII 00526 DO 250 J = I + 1, I1 00527 AB( J-I+1, I ) = AB( J-I+1, I ) / BII 00528 250 CONTINUE 00529 DO 260 J = MAX( 1, I-KA ), I - 1 00530 AB( I-J+1, J ) = AB( I-J+1, J ) / BII 00531 260 CONTINUE 00532 DO 290 K = I - KBT, I - 1 00533 DO 270 J = I - KBT, K 00534 AB( K-J+1, J ) = AB( K-J+1, J ) - 00535 $ BB( I-J+1, J )*CONJG( AB( I-K+1, 00536 $ K ) ) - CONJG( BB( I-K+1, K ) )* 00537 $ AB( I-J+1, J ) + REAL( AB( 1, I ) )* 00538 $ BB( I-J+1, J )*CONJG( BB( I-K+1, 00539 $ K ) ) 00540 270 CONTINUE 00541 DO 280 J = MAX( 1, I-KA ), I - KBT - 1 00542 AB( K-J+1, J ) = AB( K-J+1, J ) - 00543 $ CONJG( BB( I-K+1, K ) )* 00544 $ AB( I-J+1, J ) 00545 280 CONTINUE 00546 290 CONTINUE 00547 DO 310 J = I, I1 00548 DO 300 K = MAX( J-KA, I-KBT ), I - 1 00549 AB( J-K+1, K ) = AB( J-K+1, K ) - 00550 $ BB( I-K+1, K )*AB( J-I+1, I ) 00551 300 CONTINUE 00552 310 CONTINUE 00553 * 00554 IF( WANTX ) THEN 00555 * 00556 * post-multiply X by inv(S(i)) 00557 * 00558 CALL CSSCAL( N-M, ONE / BII, X( M+1, I ), 1 ) 00559 IF( KBT.GT.0 ) 00560 $ CALL CGERU( N-M, KBT, -CONE, X( M+1, I ), 1, 00561 $ BB( KBT+1, I-KBT ), LDBB-1, 00562 $ X( M+1, I-KBT ), LDX ) 00563 END IF 00564 * 00565 * store a(i1,i) in RA1 for use in next loop over K 00566 * 00567 RA1 = AB( I1-I+1, I ) 00568 END IF 00569 * 00570 * Generate and apply vectors of rotations to chase all the 00571 * existing bulges KA positions down toward the bottom of the 00572 * band 00573 * 00574 DO 360 K = 1, KB - 1 00575 IF( UPDATE ) THEN 00576 * 00577 * Determine the rotations which would annihilate the bulge 00578 * which has in theory just been created 00579 * 00580 IF( I-K+KA.LT.N .AND. I-K.GT.1 ) THEN 00581 * 00582 * generate rotation to annihilate a(i-k+ka+1,i) 00583 * 00584 CALL CLARTG( AB( KA1-K, I ), RA1, RWORK( I-K+KA-M ), 00585 $ WORK( I-K+KA-M ), RA ) 00586 * 00587 * create nonzero element a(i-k+ka+1,i-k) outside the 00588 * band and store it in WORK(i-k) 00589 * 00590 T = -BB( K+1, I-K )*RA1 00591 WORK( I-K ) = RWORK( I-K+KA-M )*T - 00592 $ CONJG( WORK( I-K+KA-M ) )*AB( KA1, I-K ) 00593 AB( KA1, I-K ) = WORK( I-K+KA-M )*T + 00594 $ RWORK( I-K+KA-M )*AB( KA1, I-K ) 00595 RA1 = RA 00596 END IF 00597 END IF 00598 J2 = I - K - 1 + MAX( 1, K-I0+2 )*KA1 00599 NR = ( N-J2+KA ) / KA1 00600 J1 = J2 + ( NR-1 )*KA1 00601 IF( UPDATE ) THEN 00602 J2T = MAX( J2, I+2*KA-K+1 ) 00603 ELSE 00604 J2T = J2 00605 END IF 00606 NRT = ( N-J2T+KA ) / KA1 00607 DO 320 J = J2T, J1, KA1 00608 * 00609 * create nonzero element a(j+1,j-ka) outside the band 00610 * and store it in WORK(j-m) 00611 * 00612 WORK( J-M ) = WORK( J-M )*AB( KA1, J-KA+1 ) 00613 AB( KA1, J-KA+1 ) = RWORK( J-M )*AB( KA1, J-KA+1 ) 00614 320 CONTINUE 00615 * 00616 * generate rotations in 1st set to annihilate elements which 00617 * have been created outside the band 00618 * 00619 IF( NRT.GT.0 ) 00620 $ CALL CLARGV( NRT, AB( KA1, J2T-KA ), INCA, WORK( J2T-M ), 00621 $ KA1, RWORK( J2T-M ), KA1 ) 00622 IF( NR.GT.0 ) THEN 00623 * 00624 * apply rotations in 1st set from the left 00625 * 00626 DO 330 L = 1, KA - 1 00627 CALL CLARTV( NR, AB( L+1, J2-L ), INCA, 00628 $ AB( L+2, J2-L ), INCA, RWORK( J2-M ), 00629 $ WORK( J2-M ), KA1 ) 00630 330 CONTINUE 00631 * 00632 * apply rotations in 1st set from both sides to diagonal 00633 * blocks 00634 * 00635 CALL CLAR2V( NR, AB( 1, J2 ), AB( 1, J2+1 ), AB( 2, J2 ), 00636 $ INCA, RWORK( J2-M ), WORK( J2-M ), KA1 ) 00637 * 00638 CALL CLACGV( NR, WORK( J2-M ), KA1 ) 00639 END IF 00640 * 00641 * start applying rotations in 1st set from the right 00642 * 00643 DO 340 L = KA - 1, KB - K + 1, -1 00644 NRT = ( N-J2+L ) / KA1 00645 IF( NRT.GT.0 ) 00646 $ CALL CLARTV( NRT, AB( KA1-L+1, J2 ), INCA, 00647 $ AB( KA1-L, J2+1 ), INCA, RWORK( J2-M ), 00648 $ WORK( J2-M ), KA1 ) 00649 340 CONTINUE 00650 * 00651 IF( WANTX ) THEN 00652 * 00653 * post-multiply X by product of rotations in 1st set 00654 * 00655 DO 350 J = J2, J1, KA1 00656 CALL CROT( N-M, X( M+1, J ), 1, X( M+1, J+1 ), 1, 00657 $ RWORK( J-M ), WORK( J-M ) ) 00658 350 CONTINUE 00659 END IF 00660 360 CONTINUE 00661 * 00662 IF( UPDATE ) THEN 00663 IF( I2.LE.N .AND. KBT.GT.0 ) THEN 00664 * 00665 * create nonzero element a(i-kbt+ka+1,i-kbt) outside the 00666 * band and store it in WORK(i-kbt) 00667 * 00668 WORK( I-KBT ) = -BB( KBT+1, I-KBT )*RA1 00669 END IF 00670 END IF 00671 * 00672 DO 400 K = KB, 1, -1 00673 IF( UPDATE ) THEN 00674 J2 = I - K - 1 + MAX( 2, K-I0+1 )*KA1 00675 ELSE 00676 J2 = I - K - 1 + MAX( 1, K-I0+1 )*KA1 00677 END IF 00678 * 00679 * finish applying rotations in 2nd set from the right 00680 * 00681 DO 370 L = KB - K, 1, -1 00682 NRT = ( N-J2+KA+L ) / KA1 00683 IF( NRT.GT.0 ) 00684 $ CALL CLARTV( NRT, AB( KA1-L+1, J2-KA ), INCA, 00685 $ AB( KA1-L, J2-KA+1 ), INCA, 00686 $ RWORK( J2-KA ), WORK( J2-KA ), KA1 ) 00687 370 CONTINUE 00688 NR = ( N-J2+KA ) / KA1 00689 J1 = J2 + ( NR-1 )*KA1 00690 DO 380 J = J1, J2, -KA1 00691 WORK( J ) = WORK( J-KA ) 00692 RWORK( J ) = RWORK( J-KA ) 00693 380 CONTINUE 00694 DO 390 J = J2, J1, KA1 00695 * 00696 * create nonzero element a(j+1,j-ka) outside the band 00697 * and store it in WORK(j) 00698 * 00699 WORK( J ) = WORK( J )*AB( KA1, J-KA+1 ) 00700 AB( KA1, J-KA+1 ) = RWORK( J )*AB( KA1, J-KA+1 ) 00701 390 CONTINUE 00702 IF( UPDATE ) THEN 00703 IF( I-K.LT.N-KA .AND. K.LE.KBT ) 00704 $ WORK( I-K+KA ) = WORK( I-K ) 00705 END IF 00706 400 CONTINUE 00707 * 00708 DO 440 K = KB, 1, -1 00709 J2 = I - K - 1 + MAX( 1, K-I0+1 )*KA1 00710 NR = ( N-J2+KA ) / KA1 00711 J1 = J2 + ( NR-1 )*KA1 00712 IF( NR.GT.0 ) THEN 00713 * 00714 * generate rotations in 2nd set to annihilate elements 00715 * which have been created outside the band 00716 * 00717 CALL CLARGV( NR, AB( KA1, J2-KA ), INCA, WORK( J2 ), KA1, 00718 $ RWORK( J2 ), KA1 ) 00719 * 00720 * apply rotations in 2nd set from the left 00721 * 00722 DO 410 L = 1, KA - 1 00723 CALL CLARTV( NR, AB( L+1, J2-L ), INCA, 00724 $ AB( L+2, J2-L ), INCA, RWORK( J2 ), 00725 $ WORK( J2 ), KA1 ) 00726 410 CONTINUE 00727 * 00728 * apply rotations in 2nd set from both sides to diagonal 00729 * blocks 00730 * 00731 CALL CLAR2V( NR, AB( 1, J2 ), AB( 1, J2+1 ), AB( 2, J2 ), 00732 $ INCA, RWORK( J2 ), WORK( J2 ), KA1 ) 00733 * 00734 CALL CLACGV( NR, WORK( J2 ), KA1 ) 00735 END IF 00736 * 00737 * start applying rotations in 2nd set from the right 00738 * 00739 DO 420 L = KA - 1, KB - K + 1, -1 00740 NRT = ( N-J2+L ) / KA1 00741 IF( NRT.GT.0 ) 00742 $ CALL CLARTV( NRT, AB( KA1-L+1, J2 ), INCA, 00743 $ AB( KA1-L, J2+1 ), INCA, RWORK( J2 ), 00744 $ WORK( J2 ), KA1 ) 00745 420 CONTINUE 00746 * 00747 IF( WANTX ) THEN 00748 * 00749 * post-multiply X by product of rotations in 2nd set 00750 * 00751 DO 430 J = J2, J1, KA1 00752 CALL CROT( N-M, X( M+1, J ), 1, X( M+1, J+1 ), 1, 00753 $ RWORK( J ), WORK( J ) ) 00754 430 CONTINUE 00755 END IF 00756 440 CONTINUE 00757 * 00758 DO 460 K = 1, KB - 1 00759 J2 = I - K - 1 + MAX( 1, K-I0+2 )*KA1 00760 * 00761 * finish applying rotations in 1st set from the right 00762 * 00763 DO 450 L = KB - K, 1, -1 00764 NRT = ( N-J2+L ) / KA1 00765 IF( NRT.GT.0 ) 00766 $ CALL CLARTV( NRT, AB( KA1-L+1, J2 ), INCA, 00767 $ AB( KA1-L, J2+1 ), INCA, RWORK( J2-M ), 00768 $ WORK( J2-M ), KA1 ) 00769 450 CONTINUE 00770 460 CONTINUE 00771 * 00772 IF( KB.GT.1 ) THEN 00773 DO 470 J = N - 1, J2 + KA, -1 00774 RWORK( J-M ) = RWORK( J-KA-M ) 00775 WORK( J-M ) = WORK( J-KA-M ) 00776 470 CONTINUE 00777 END IF 00778 * 00779 END IF 00780 * 00781 GO TO 10 00782 * 00783 480 CONTINUE 00784 * 00785 * **************************** Phase 2 ***************************** 00786 * 00787 * The logical structure of this phase is: 00788 * 00789 * UPDATE = .TRUE. 00790 * DO I = 1, M 00791 * use S(i) to update A and create a new bulge 00792 * apply rotations to push all bulges KA positions upward 00793 * END DO 00794 * UPDATE = .FALSE. 00795 * DO I = M - KA - 1, 2, -1 00796 * apply rotations to push all bulges KA positions upward 00797 * END DO 00798 * 00799 * To avoid duplicating code, the two loops are merged. 00800 * 00801 UPDATE = .TRUE. 00802 I = 0 00803 490 CONTINUE 00804 IF( UPDATE ) THEN 00805 I = I + 1 00806 KBT = MIN( KB, M-I ) 00807 I0 = I + 1 00808 I1 = MAX( 1, I-KA ) 00809 I2 = I + KBT - KA1 00810 IF( I.GT.M ) THEN 00811 UPDATE = .FALSE. 00812 I = I - 1 00813 I0 = M + 1 00814 IF( KA.EQ.0 ) 00815 $ RETURN 00816 GO TO 490 00817 END IF 00818 ELSE 00819 I = I - KA 00820 IF( I.LT.2 ) 00821 $ RETURN 00822 END IF 00823 * 00824 IF( I.LT.M-KBT ) THEN 00825 NX = M 00826 ELSE 00827 NX = N 00828 END IF 00829 * 00830 IF( UPPER ) THEN 00831 * 00832 * Transform A, working with the upper triangle 00833 * 00834 IF( UPDATE ) THEN 00835 * 00836 * Form inv(S(i))**H * A * inv(S(i)) 00837 * 00838 BII = REAL( BB( KB1, I ) ) 00839 AB( KA1, I ) = ( REAL( AB( KA1, I ) ) / BII ) / BII 00840 DO 500 J = I1, I - 1 00841 AB( J-I+KA1, I ) = AB( J-I+KA1, I ) / BII 00842 500 CONTINUE 00843 DO 510 J = I + 1, MIN( N, I+KA ) 00844 AB( I-J+KA1, J ) = AB( I-J+KA1, J ) / BII 00845 510 CONTINUE 00846 DO 540 K = I + 1, I + KBT 00847 DO 520 J = K, I + KBT 00848 AB( K-J+KA1, J ) = AB( K-J+KA1, J ) - 00849 $ BB( I-J+KB1, J )* 00850 $ CONJG( AB( I-K+KA1, K ) ) - 00851 $ CONJG( BB( I-K+KB1, K ) )* 00852 $ AB( I-J+KA1, J ) + 00853 $ REAL( AB( KA1, I ) )* 00854 $ BB( I-J+KB1, J )* 00855 $ CONJG( BB( I-K+KB1, K ) ) 00856 520 CONTINUE 00857 DO 530 J = I + KBT + 1, MIN( N, I+KA ) 00858 AB( K-J+KA1, J ) = AB( K-J+KA1, J ) - 00859 $ CONJG( BB( I-K+KB1, K ) )* 00860 $ AB( I-J+KA1, J ) 00861 530 CONTINUE 00862 540 CONTINUE 00863 DO 560 J = I1, I 00864 DO 550 K = I + 1, MIN( J+KA, I+KBT ) 00865 AB( J-K+KA1, K ) = AB( J-K+KA1, K ) - 00866 $ BB( I-K+KB1, K )*AB( J-I+KA1, I ) 00867 550 CONTINUE 00868 560 CONTINUE 00869 * 00870 IF( WANTX ) THEN 00871 * 00872 * post-multiply X by inv(S(i)) 00873 * 00874 CALL CSSCAL( NX, ONE / BII, X( 1, I ), 1 ) 00875 IF( KBT.GT.0 ) 00876 $ CALL CGERU( NX, KBT, -CONE, X( 1, I ), 1, 00877 $ BB( KB, I+1 ), LDBB-1, X( 1, I+1 ), LDX ) 00878 END IF 00879 * 00880 * store a(i1,i) in RA1 for use in next loop over K 00881 * 00882 RA1 = AB( I1-I+KA1, I ) 00883 END IF 00884 * 00885 * Generate and apply vectors of rotations to chase all the 00886 * existing bulges KA positions up toward the top of the band 00887 * 00888 DO 610 K = 1, KB - 1 00889 IF( UPDATE ) THEN 00890 * 00891 * Determine the rotations which would annihilate the bulge 00892 * which has in theory just been created 00893 * 00894 IF( I+K-KA1.GT.0 .AND. I+K.LT.M ) THEN 00895 * 00896 * generate rotation to annihilate a(i+k-ka-1,i) 00897 * 00898 CALL CLARTG( AB( K+1, I ), RA1, RWORK( I+K-KA ), 00899 $ WORK( I+K-KA ), RA ) 00900 * 00901 * create nonzero element a(i+k-ka-1,i+k) outside the 00902 * band and store it in WORK(m-kb+i+k) 00903 * 00904 T = -BB( KB1-K, I+K )*RA1 00905 WORK( M-KB+I+K ) = RWORK( I+K-KA )*T - 00906 $ CONJG( WORK( I+K-KA ) )* 00907 $ AB( 1, I+K ) 00908 AB( 1, I+K ) = WORK( I+K-KA )*T + 00909 $ RWORK( I+K-KA )*AB( 1, I+K ) 00910 RA1 = RA 00911 END IF 00912 END IF 00913 J2 = I + K + 1 - MAX( 1, K+I0-M+1 )*KA1 00914 NR = ( J2+KA-1 ) / KA1 00915 J1 = J2 - ( NR-1 )*KA1 00916 IF( UPDATE ) THEN 00917 J2T = MIN( J2, I-2*KA+K-1 ) 00918 ELSE 00919 J2T = J2 00920 END IF 00921 NRT = ( J2T+KA-1 ) / KA1 00922 DO 570 J = J1, J2T, KA1 00923 * 00924 * create nonzero element a(j-1,j+ka) outside the band 00925 * and store it in WORK(j) 00926 * 00927 WORK( J ) = WORK( J )*AB( 1, J+KA-1 ) 00928 AB( 1, J+KA-1 ) = RWORK( J )*AB( 1, J+KA-1 ) 00929 570 CONTINUE 00930 * 00931 * generate rotations in 1st set to annihilate elements which 00932 * have been created outside the band 00933 * 00934 IF( NRT.GT.0 ) 00935 $ CALL CLARGV( NRT, AB( 1, J1+KA ), INCA, WORK( J1 ), KA1, 00936 $ RWORK( J1 ), KA1 ) 00937 IF( NR.GT.0 ) THEN 00938 * 00939 * apply rotations in 1st set from the left 00940 * 00941 DO 580 L = 1, KA - 1 00942 CALL CLARTV( NR, AB( KA1-L, J1+L ), INCA, 00943 $ AB( KA-L, J1+L ), INCA, RWORK( J1 ), 00944 $ WORK( J1 ), KA1 ) 00945 580 CONTINUE 00946 * 00947 * apply rotations in 1st set from both sides to diagonal 00948 * blocks 00949 * 00950 CALL CLAR2V( NR, AB( KA1, J1 ), AB( KA1, J1-1 ), 00951 $ AB( KA, J1 ), INCA, RWORK( J1 ), WORK( J1 ), 00952 $ KA1 ) 00953 * 00954 CALL CLACGV( NR, WORK( J1 ), KA1 ) 00955 END IF 00956 * 00957 * start applying rotations in 1st set from the right 00958 * 00959 DO 590 L = KA - 1, KB - K + 1, -1 00960 NRT = ( J2+L-1 ) / KA1 00961 J1T = J2 - ( NRT-1 )*KA1 00962 IF( NRT.GT.0 ) 00963 $ CALL CLARTV( NRT, AB( L, J1T ), INCA, 00964 $ AB( L+1, J1T-1 ), INCA, RWORK( J1T ), 00965 $ WORK( J1T ), KA1 ) 00966 590 CONTINUE 00967 * 00968 IF( WANTX ) THEN 00969 * 00970 * post-multiply X by product of rotations in 1st set 00971 * 00972 DO 600 J = J1, J2, KA1 00973 CALL CROT( NX, X( 1, J ), 1, X( 1, J-1 ), 1, 00974 $ RWORK( J ), WORK( J ) ) 00975 600 CONTINUE 00976 END IF 00977 610 CONTINUE 00978 * 00979 IF( UPDATE ) THEN 00980 IF( I2.GT.0 .AND. KBT.GT.0 ) THEN 00981 * 00982 * create nonzero element a(i+kbt-ka-1,i+kbt) outside the 00983 * band and store it in WORK(m-kb+i+kbt) 00984 * 00985 WORK( M-KB+I+KBT ) = -BB( KB1-KBT, I+KBT )*RA1 00986 END IF 00987 END IF 00988 * 00989 DO 650 K = KB, 1, -1 00990 IF( UPDATE ) THEN 00991 J2 = I + K + 1 - MAX( 2, K+I0-M )*KA1 00992 ELSE 00993 J2 = I + K + 1 - MAX( 1, K+I0-M )*KA1 00994 END IF 00995 * 00996 * finish applying rotations in 2nd set from the right 00997 * 00998 DO 620 L = KB - K, 1, -1 00999 NRT = ( J2+KA+L-1 ) / KA1 01000 J1T = J2 - ( NRT-1 )*KA1 01001 IF( NRT.GT.0 ) 01002 $ CALL CLARTV( NRT, AB( L, J1T+KA ), INCA, 01003 $ AB( L+1, J1T+KA-1 ), INCA, 01004 $ RWORK( M-KB+J1T+KA ), 01005 $ WORK( M-KB+J1T+KA ), KA1 ) 01006 620 CONTINUE 01007 NR = ( J2+KA-1 ) / KA1 01008 J1 = J2 - ( NR-1 )*KA1 01009 DO 630 J = J1, J2, KA1 01010 WORK( M-KB+J ) = WORK( M-KB+J+KA ) 01011 RWORK( M-KB+J ) = RWORK( M-KB+J+KA ) 01012 630 CONTINUE 01013 DO 640 J = J1, J2, KA1 01014 * 01015 * create nonzero element a(j-1,j+ka) outside the band 01016 * and store it in WORK(m-kb+j) 01017 * 01018 WORK( M-KB+J ) = WORK( M-KB+J )*AB( 1, J+KA-1 ) 01019 AB( 1, J+KA-1 ) = RWORK( M-KB+J )*AB( 1, J+KA-1 ) 01020 640 CONTINUE 01021 IF( UPDATE ) THEN 01022 IF( I+K.GT.KA1 .AND. K.LE.KBT ) 01023 $ WORK( M-KB+I+K-KA ) = WORK( M-KB+I+K ) 01024 END IF 01025 650 CONTINUE 01026 * 01027 DO 690 K = KB, 1, -1 01028 J2 = I + K + 1 - MAX( 1, K+I0-M )*KA1 01029 NR = ( J2+KA-1 ) / KA1 01030 J1 = J2 - ( NR-1 )*KA1 01031 IF( NR.GT.0 ) THEN 01032 * 01033 * generate rotations in 2nd set to annihilate elements 01034 * which have been created outside the band 01035 * 01036 CALL CLARGV( NR, AB( 1, J1+KA ), INCA, WORK( M-KB+J1 ), 01037 $ KA1, RWORK( M-KB+J1 ), KA1 ) 01038 * 01039 * apply rotations in 2nd set from the left 01040 * 01041 DO 660 L = 1, KA - 1 01042 CALL CLARTV( NR, AB( KA1-L, J1+L ), INCA, 01043 $ AB( KA-L, J1+L ), INCA, RWORK( M-KB+J1 ), 01044 $ WORK( M-KB+J1 ), KA1 ) 01045 660 CONTINUE 01046 * 01047 * apply rotations in 2nd set from both sides to diagonal 01048 * blocks 01049 * 01050 CALL CLAR2V( NR, AB( KA1, J1 ), AB( KA1, J1-1 ), 01051 $ AB( KA, J1 ), INCA, RWORK( M-KB+J1 ), 01052 $ WORK( M-KB+J1 ), KA1 ) 01053 * 01054 CALL CLACGV( NR, WORK( M-KB+J1 ), KA1 ) 01055 END IF 01056 * 01057 * start applying rotations in 2nd set from the right 01058 * 01059 DO 670 L = KA - 1, KB - K + 1, -1 01060 NRT = ( J2+L-1 ) / KA1 01061 J1T = J2 - ( NRT-1 )*KA1 01062 IF( NRT.GT.0 ) 01063 $ CALL CLARTV( NRT, AB( L, J1T ), INCA, 01064 $ AB( L+1, J1T-1 ), INCA, 01065 $ RWORK( M-KB+J1T ), WORK( M-KB+J1T ), 01066 $ KA1 ) 01067 670 CONTINUE 01068 * 01069 IF( WANTX ) THEN 01070 * 01071 * post-multiply X by product of rotations in 2nd set 01072 * 01073 DO 680 J = J1, J2, KA1 01074 CALL CROT( NX, X( 1, J ), 1, X( 1, J-1 ), 1, 01075 $ RWORK( M-KB+J ), WORK( M-KB+J ) ) 01076 680 CONTINUE 01077 END IF 01078 690 CONTINUE 01079 * 01080 DO 710 K = 1, KB - 1 01081 J2 = I + K + 1 - MAX( 1, K+I0-M+1 )*KA1 01082 * 01083 * finish applying rotations in 1st set from the right 01084 * 01085 DO 700 L = KB - K, 1, -1 01086 NRT = ( J2+L-1 ) / KA1 01087 J1T = J2 - ( NRT-1 )*KA1 01088 IF( NRT.GT.0 ) 01089 $ CALL CLARTV( NRT, AB( L, J1T ), INCA, 01090 $ AB( L+1, J1T-1 ), INCA, RWORK( J1T ), 01091 $ WORK( J1T ), KA1 ) 01092 700 CONTINUE 01093 710 CONTINUE 01094 * 01095 IF( KB.GT.1 ) THEN 01096 DO 720 J = 2, I2 - KA 01097 RWORK( J ) = RWORK( J+KA ) 01098 WORK( J ) = WORK( J+KA ) 01099 720 CONTINUE 01100 END IF 01101 * 01102 ELSE 01103 * 01104 * Transform A, working with the lower triangle 01105 * 01106 IF( UPDATE ) THEN 01107 * 01108 * Form inv(S(i))**H * A * inv(S(i)) 01109 * 01110 BII = REAL( BB( 1, I ) ) 01111 AB( 1, I ) = ( REAL( AB( 1, I ) ) / BII ) / BII 01112 DO 730 J = I1, I - 1 01113 AB( I-J+1, J ) = AB( I-J+1, J ) / BII 01114 730 CONTINUE 01115 DO 740 J = I + 1, MIN( N, I+KA ) 01116 AB( J-I+1, I ) = AB( J-I+1, I ) / BII 01117 740 CONTINUE 01118 DO 770 K = I + 1, I + KBT 01119 DO 750 J = K, I + KBT 01120 AB( J-K+1, K ) = AB( J-K+1, K ) - 01121 $ BB( J-I+1, I )*CONJG( AB( K-I+1, 01122 $ I ) ) - CONJG( BB( K-I+1, I ) )* 01123 $ AB( J-I+1, I ) + REAL( AB( 1, I ) )* 01124 $ BB( J-I+1, I )*CONJG( BB( K-I+1, 01125 $ I ) ) 01126 750 CONTINUE 01127 DO 760 J = I + KBT + 1, MIN( N, I+KA ) 01128 AB( J-K+1, K ) = AB( J-K+1, K ) - 01129 $ CONJG( BB( K-I+1, I ) )* 01130 $ AB( J-I+1, I ) 01131 760 CONTINUE 01132 770 CONTINUE 01133 DO 790 J = I1, I 01134 DO 780 K = I + 1, MIN( J+KA, I+KBT ) 01135 AB( K-J+1, J ) = AB( K-J+1, J ) - 01136 $ BB( K-I+1, I )*AB( I-J+1, J ) 01137 780 CONTINUE 01138 790 CONTINUE 01139 * 01140 IF( WANTX ) THEN 01141 * 01142 * post-multiply X by inv(S(i)) 01143 * 01144 CALL CSSCAL( NX, ONE / BII, X( 1, I ), 1 ) 01145 IF( KBT.GT.0 ) 01146 $ CALL CGERC( NX, KBT, -CONE, X( 1, I ), 1, BB( 2, I ), 01147 $ 1, X( 1, I+1 ), LDX ) 01148 END IF 01149 * 01150 * store a(i,i1) in RA1 for use in next loop over K 01151 * 01152 RA1 = AB( I-I1+1, I1 ) 01153 END IF 01154 * 01155 * Generate and apply vectors of rotations to chase all the 01156 * existing bulges KA positions up toward the top of the band 01157 * 01158 DO 840 K = 1, KB - 1 01159 IF( UPDATE ) THEN 01160 * 01161 * Determine the rotations which would annihilate the bulge 01162 * which has in theory just been created 01163 * 01164 IF( I+K-KA1.GT.0 .AND. I+K.LT.M ) THEN 01165 * 01166 * generate rotation to annihilate a(i,i+k-ka-1) 01167 * 01168 CALL CLARTG( AB( KA1-K, I+K-KA ), RA1, 01169 $ RWORK( I+K-KA ), WORK( I+K-KA ), RA ) 01170 * 01171 * create nonzero element a(i+k,i+k-ka-1) outside the 01172 * band and store it in WORK(m-kb+i+k) 01173 * 01174 T = -BB( K+1, I )*RA1 01175 WORK( M-KB+I+K ) = RWORK( I+K-KA )*T - 01176 $ CONJG( WORK( I+K-KA ) )* 01177 $ AB( KA1, I+K-KA ) 01178 AB( KA1, I+K-KA ) = WORK( I+K-KA )*T + 01179 $ RWORK( I+K-KA )*AB( KA1, I+K-KA ) 01180 RA1 = RA 01181 END IF 01182 END IF 01183 J2 = I + K + 1 - MAX( 1, K+I0-M+1 )*KA1 01184 NR = ( J2+KA-1 ) / KA1 01185 J1 = J2 - ( NR-1 )*KA1 01186 IF( UPDATE ) THEN 01187 J2T = MIN( J2, I-2*KA+K-1 ) 01188 ELSE 01189 J2T = J2 01190 END IF 01191 NRT = ( J2T+KA-1 ) / KA1 01192 DO 800 J = J1, J2T, KA1 01193 * 01194 * create nonzero element a(j+ka,j-1) outside the band 01195 * and store it in WORK(j) 01196 * 01197 WORK( J ) = WORK( J )*AB( KA1, J-1 ) 01198 AB( KA1, J-1 ) = RWORK( J )*AB( KA1, J-1 ) 01199 800 CONTINUE 01200 * 01201 * generate rotations in 1st set to annihilate elements which 01202 * have been created outside the band 01203 * 01204 IF( NRT.GT.0 ) 01205 $ CALL CLARGV( NRT, AB( KA1, J1 ), INCA, WORK( J1 ), KA1, 01206 $ RWORK( J1 ), KA1 ) 01207 IF( NR.GT.0 ) THEN 01208 * 01209 * apply rotations in 1st set from the right 01210 * 01211 DO 810 L = 1, KA - 1 01212 CALL CLARTV( NR, AB( L+1, J1 ), INCA, AB( L+2, J1-1 ), 01213 $ INCA, RWORK( J1 ), WORK( J1 ), KA1 ) 01214 810 CONTINUE 01215 * 01216 * apply rotations in 1st set from both sides to diagonal 01217 * blocks 01218 * 01219 CALL CLAR2V( NR, AB( 1, J1 ), AB( 1, J1-1 ), 01220 $ AB( 2, J1-1 ), INCA, RWORK( J1 ), 01221 $ WORK( J1 ), KA1 ) 01222 * 01223 CALL CLACGV( NR, WORK( J1 ), KA1 ) 01224 END IF 01225 * 01226 * start applying rotations in 1st set from the left 01227 * 01228 DO 820 L = KA - 1, KB - K + 1, -1 01229 NRT = ( J2+L-1 ) / KA1 01230 J1T = J2 - ( NRT-1 )*KA1 01231 IF( NRT.GT.0 ) 01232 $ CALL CLARTV( NRT, AB( KA1-L+1, J1T-KA1+L ), INCA, 01233 $ AB( KA1-L, J1T-KA1+L ), INCA, 01234 $ RWORK( J1T ), WORK( J1T ), KA1 ) 01235 820 CONTINUE 01236 * 01237 IF( WANTX ) THEN 01238 * 01239 * post-multiply X by product of rotations in 1st set 01240 * 01241 DO 830 J = J1, J2, KA1 01242 CALL CROT( NX, X( 1, J ), 1, X( 1, J-1 ), 1, 01243 $ RWORK( J ), CONJG( WORK( J ) ) ) 01244 830 CONTINUE 01245 END IF 01246 840 CONTINUE 01247 * 01248 IF( UPDATE ) THEN 01249 IF( I2.GT.0 .AND. KBT.GT.0 ) THEN 01250 * 01251 * create nonzero element a(i+kbt,i+kbt-ka-1) outside the 01252 * band and store it in WORK(m-kb+i+kbt) 01253 * 01254 WORK( M-KB+I+KBT ) = -BB( KBT+1, I )*RA1 01255 END IF 01256 END IF 01257 * 01258 DO 880 K = KB, 1, -1 01259 IF( UPDATE ) THEN 01260 J2 = I + K + 1 - MAX( 2, K+I0-M )*KA1 01261 ELSE 01262 J2 = I + K + 1 - MAX( 1, K+I0-M )*KA1 01263 END IF 01264 * 01265 * finish applying rotations in 2nd set from the left 01266 * 01267 DO 850 L = KB - K, 1, -1 01268 NRT = ( J2+KA+L-1 ) / KA1 01269 J1T = J2 - ( NRT-1 )*KA1 01270 IF( NRT.GT.0 ) 01271 $ CALL CLARTV( NRT, AB( KA1-L+1, J1T+L-1 ), INCA, 01272 $ AB( KA1-L, J1T+L-1 ), INCA, 01273 $ RWORK( M-KB+J1T+KA ), 01274 $ WORK( M-KB+J1T+KA ), KA1 ) 01275 850 CONTINUE 01276 NR = ( J2+KA-1 ) / KA1 01277 J1 = J2 - ( NR-1 )*KA1 01278 DO 860 J = J1, J2, KA1 01279 WORK( M-KB+J ) = WORK( M-KB+J+KA ) 01280 RWORK( M-KB+J ) = RWORK( M-KB+J+KA ) 01281 860 CONTINUE 01282 DO 870 J = J1, J2, KA1 01283 * 01284 * create nonzero element a(j+ka,j-1) outside the band 01285 * and store it in WORK(m-kb+j) 01286 * 01287 WORK( M-KB+J ) = WORK( M-KB+J )*AB( KA1, J-1 ) 01288 AB( KA1, J-1 ) = RWORK( M-KB+J )*AB( KA1, J-1 ) 01289 870 CONTINUE 01290 IF( UPDATE ) THEN 01291 IF( I+K.GT.KA1 .AND. K.LE.KBT ) 01292 $ WORK( M-KB+I+K-KA ) = WORK( M-KB+I+K ) 01293 END IF 01294 880 CONTINUE 01295 * 01296 DO 920 K = KB, 1, -1 01297 J2 = I + K + 1 - MAX( 1, K+I0-M )*KA1 01298 NR = ( J2+KA-1 ) / KA1 01299 J1 = J2 - ( NR-1 )*KA1 01300 IF( NR.GT.0 ) THEN 01301 * 01302 * generate rotations in 2nd set to annihilate elements 01303 * which have been created outside the band 01304 * 01305 CALL CLARGV( NR, AB( KA1, J1 ), INCA, WORK( M-KB+J1 ), 01306 $ KA1, RWORK( M-KB+J1 ), KA1 ) 01307 * 01308 * apply rotations in 2nd set from the right 01309 * 01310 DO 890 L = 1, KA - 1 01311 CALL CLARTV( NR, AB( L+1, J1 ), INCA, AB( L+2, J1-1 ), 01312 $ INCA, RWORK( M-KB+J1 ), WORK( M-KB+J1 ), 01313 $ KA1 ) 01314 890 CONTINUE 01315 * 01316 * apply rotations in 2nd set from both sides to diagonal 01317 * blocks 01318 * 01319 CALL CLAR2V( NR, AB( 1, J1 ), AB( 1, J1-1 ), 01320 $ AB( 2, J1-1 ), INCA, RWORK( M-KB+J1 ), 01321 $ WORK( M-KB+J1 ), KA1 ) 01322 * 01323 CALL CLACGV( NR, WORK( M-KB+J1 ), KA1 ) 01324 END IF 01325 * 01326 * start applying rotations in 2nd set from the left 01327 * 01328 DO 900 L = KA - 1, KB - K + 1, -1 01329 NRT = ( J2+L-1 ) / KA1 01330 J1T = J2 - ( NRT-1 )*KA1 01331 IF( NRT.GT.0 ) 01332 $ CALL CLARTV( NRT, AB( KA1-L+1, J1T-KA1+L ), INCA, 01333 $ AB( KA1-L, J1T-KA1+L ), INCA, 01334 $ RWORK( M-KB+J1T ), WORK( M-KB+J1T ), 01335 $ KA1 ) 01336 900 CONTINUE 01337 * 01338 IF( WANTX ) THEN 01339 * 01340 * post-multiply X by product of rotations in 2nd set 01341 * 01342 DO 910 J = J1, J2, KA1 01343 CALL CROT( NX, X( 1, J ), 1, X( 1, J-1 ), 1, 01344 $ RWORK( M-KB+J ), CONJG( WORK( M-KB+J ) ) ) 01345 910 CONTINUE 01346 END IF 01347 920 CONTINUE 01348 * 01349 DO 940 K = 1, KB - 1 01350 J2 = I + K + 1 - MAX( 1, K+I0-M+1 )*KA1 01351 * 01352 * finish applying rotations in 1st set from the left 01353 * 01354 DO 930 L = KB - K, 1, -1 01355 NRT = ( J2+L-1 ) / KA1 01356 J1T = J2 - ( NRT-1 )*KA1 01357 IF( NRT.GT.0 ) 01358 $ CALL CLARTV( NRT, AB( KA1-L+1, J1T-KA1+L ), INCA, 01359 $ AB( KA1-L, J1T-KA1+L ), INCA, 01360 $ RWORK( J1T ), WORK( J1T ), KA1 ) 01361 930 CONTINUE 01362 940 CONTINUE 01363 * 01364 IF( KB.GT.1 ) THEN 01365 DO 950 J = 2, I2 - KA 01366 RWORK( J ) = RWORK( J+KA ) 01367 WORK( J ) = WORK( J+KA ) 01368 950 CONTINUE 01369 END IF 01370 * 01371 END IF 01372 * 01373 GO TO 490 01374 * 01375 * End of CHBGST 01376 * 01377 END