3 * =========== DOCUMENTATION ===========
5 * Online html documentation available at
6 * http://www.netlib.org/lapack/explore-html/
9 *> Download ZHBGST + dependencies
10 *> <a href="http://www.netlib.org/cgi-bin/netlibfiles.tgz?format=tgz&filename=/lapack/lapack_routine/zhbgst.f">
12 *> <a href="http://www.netlib.org/cgi-bin/netlibfiles.zip?format=zip&filename=/lapack/lapack_routine/zhbgst.f">
14 *> <a href="http://www.netlib.org/cgi-bin/netlibfiles.txt?format=txt&filename=/lapack/lapack_routine/zhbgst.f">
21 * SUBROUTINE ZHBGST( VECT, UPLO, N, KA, KB, AB, LDAB, BB, LDBB, X,
22 * LDX, WORK, RWORK, INFO )
24 * .. Scalar Arguments ..
25 * CHARACTER UPLO, VECT
26 * INTEGER INFO, KA, KB, LDAB, LDBB, LDX, N
28 * .. Array Arguments ..
29 * DOUBLE PRECISION RWORK( * )
30 * COMPLEX*16 AB( LDAB, * ), BB( LDBB, * ), WORK( * ),
40 *> ZHBGST reduces a complex Hermitian-definite banded generalized
41 *> eigenproblem A*x = lambda*B*x to standard form C*y = lambda*y,
42 *> such that C has the same bandwidth as A.
44 *> B must have been previously factorized as S**H*S by ZPBSTF, using a
45 *> split Cholesky factorization. A is overwritten by C = X**H*A*X, where
46 *> X = S**(-1)*Q and Q is a unitary matrix chosen to preserve the
55 *> VECT is CHARACTER*1
56 *> = 'N': do not form the transformation matrix X;
62 *> UPLO is CHARACTER*1
63 *> = 'U': Upper triangle of A is stored;
64 *> = 'L': Lower triangle of A is stored.
70 *> The order of the matrices A and B. N >= 0.
76 *> The number of superdiagonals of the matrix A if UPLO = 'U',
77 *> or the number of subdiagonals if UPLO = 'L'. KA >= 0.
83 *> The number of superdiagonals of the matrix B if UPLO = 'U',
84 *> or the number of subdiagonals if UPLO = 'L'. KA >= KB >= 0.
89 *> AB is COMPLEX*16 array, dimension (LDAB,N)
90 *> On entry, the upper or lower triangle of the Hermitian band
91 *> matrix A, stored in the first ka+1 rows of the array. The
92 *> j-th column of A is stored in the j-th column of the array AB
94 *> if UPLO = 'U', AB(ka+1+i-j,j) = A(i,j) for max(1,j-ka)<=i<=j;
95 *> if UPLO = 'L', AB(1+i-j,j) = A(i,j) for j<=i<=min(n,j+ka).
97 *> On exit, the transformed matrix X**H*A*X, stored in the same
104 *> The leading dimension of the array AB. LDAB >= KA+1.
109 *> BB is COMPLEX*16 array, dimension (LDBB,N)
110 *> The banded factor S from the split Cholesky factorization of
111 *> B, as returned by ZPBSTF, stored in the first kb+1 rows of
118 *> The leading dimension of the array BB. LDBB >= KB+1.
123 *> X is COMPLEX*16 array, dimension (LDX,N)
124 *> If VECT = 'V', the n-by-n matrix X.
125 *> If VECT = 'N', the array X is not referenced.
131 *> The leading dimension of the array X.
132 *> LDX >= max(1,N) if VECT = 'V'; LDX >= 1 otherwise.
137 *> WORK is COMPLEX*16 array, dimension (N)
142 *> RWORK is DOUBLE PRECISION array, dimension (N)
148 *> = 0: successful exit
149 *> < 0: if INFO = -i, the i-th argument had an illegal value.
155 *> \author Univ. of Tennessee
156 *> \author Univ. of California Berkeley
157 *> \author Univ. of Colorado Denver
160 *> \date November 2011
162 *> \ingroup complex16OTHERcomputational
164 * =====================================================================
165 SUBROUTINE ZHBGST( VECT, UPLO, N, KA, KB, AB, LDAB, BB, LDBB, X,
166 $ LDX, WORK, RWORK, INFO )
168 * -- LAPACK computational routine (version 3.4.0) --
169 * -- LAPACK is a software package provided by Univ. of Tennessee, --
170 * -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..--
173 * .. Scalar Arguments ..
175 INTEGER INFO, KA, KB, LDAB, LDBB, LDX, N
177 * .. Array Arguments ..
178 DOUBLE PRECISION RWORK( * )
179 COMPLEX*16 AB( LDAB, * ), BB( LDBB, * ), WORK( * ),
183 * =====================================================================
186 COMPLEX*16 CZERO, CONE
188 PARAMETER ( CZERO = ( 0.0D+0, 0.0D+0 ),
189 $ CONE = ( 1.0D+0, 0.0D+0 ), ONE = 1.0D+0 )
191 * .. Local Scalars ..
192 LOGICAL UPDATE, UPPER, WANTX
193 INTEGER I, I0, I1, I2, INCA, J, J1, J1T, J2, J2T, K,
194 $ KA1, KB1, KBT, L, M, NR, NRT, NX
196 COMPLEX*16 RA, RA1, T
198 * .. External Functions ..
202 * .. External Subroutines ..
203 EXTERNAL XERBLA, ZDSCAL, ZGERC, ZGERU, ZLACGV, ZLAR2V,
204 $ ZLARGV, ZLARTG, ZLARTV, ZLASET, ZROT
206 * .. Intrinsic Functions ..
207 INTRINSIC DBLE, DCONJG, MAX, MIN
209 * .. Executable Statements ..
211 * Test the input parameters
213 WANTX = LSAME( VECT, 'V' )
214 UPPER = LSAME( UPLO, 'U' )
218 IF( .NOT.WANTX .AND. .NOT.LSAME( VECT, 'N' ) ) THEN
220 ELSE IF( .NOT.UPPER .AND. .NOT.LSAME( UPLO, 'L' ) ) THEN
222 ELSE IF( N.LT.0 ) THEN
224 ELSE IF( KA.LT.0 ) THEN
226 ELSE IF( KB.LT.0 .OR. KB.GT.KA ) THEN
228 ELSE IF( LDAB.LT.KA+1 ) THEN
230 ELSE IF( LDBB.LT.KB+1 ) THEN
232 ELSE IF( LDX.LT.1 .OR. WANTX .AND. LDX.LT.MAX( 1, N ) ) THEN
236 CALL XERBLA( 'ZHBGST', -INFO )
240 * Quick return if possible
247 * Initialize X to the unit matrix, if needed
250 $ CALL ZLASET( 'Full', N, N, CZERO, CONE, X, LDX )
252 * Set M to the splitting point m. It must be the same value as is
253 * used in ZPBSTF. The chosen value allows the arrays WORK and RWORK
254 * to be of dimension (N).
258 * The routine works in two phases, corresponding to the two halves
259 * of the split Cholesky factorization of B as S**H*S where
264 * with U upper triangular of order m, and L lower triangular of
265 * order n-m. S has the same bandwidth as B.
267 * S is treated as a product of elementary matrices:
269 * S = S(m)*S(m-1)*...*S(2)*S(1)*S(m+1)*S(m+2)*...*S(n-1)*S(n)
271 * where S(i) is determined by the i-th row of S.
273 * In phase 1, the index i takes the values n, n-1, ... , m+1;
274 * in phase 2, it takes the values 1, 2, ... , m.
276 * For each value of i, the current matrix A is updated by forming
277 * inv(S(i))**H*A*inv(S(i)). This creates a triangular bulge outside
278 * the band of A. The bulge is then pushed down toward the bottom of
279 * A in phase 1, and up toward the top of A in phase 2, by applying
282 * There are kb*(kb+1)/2 elements in the bulge, but at most 2*kb-1
283 * of them are linearly independent, so annihilating a bulge requires
284 * only 2*kb-1 plane rotations. The rotations are divided into a 1st
285 * set of kb-1 rotations, and a 2nd set of kb rotations.
287 * Wherever possible, rotations are generated and applied in vector
288 * operations of length NR between the indices J1 and J2 (sometimes
289 * replaced by modified values NRT, J1T or J2T).
291 * The real cosines and complex sines of the rotations are stored in
292 * the arrays RWORK and WORK, those of the 1st set in elements
293 * 2:m-kb-1, and those of the 2nd set in elements m-kb+1:n.
295 * The bulges are not formed explicitly; nonzero elements outside the
296 * band are created only when they are required for generating new
297 * rotations; they are stored in the array WORK, in positions where
298 * they are later overwritten by the sines of the rotations which
301 * **************************** Phase 1 *****************************
303 * The logical structure of this phase is:
306 * DO I = N, M + 1, -1
307 * use S(i) to update A and create a new bulge
308 * apply rotations to push all bulges KA positions downward
311 * DO I = M + KA + 1, N - 1
312 * apply rotations to push all bulges KA positions downward
315 * To avoid duplicating code, the two loops are merged.
342 * Transform A, working with the upper triangle
346 * Form inv(S(i))**H * A * inv(S(i))
348 BII = DBLE( BB( KB1, I ) )
349 AB( KA1, I ) = ( DBLE( AB( KA1, I ) ) / BII ) / BII
351 AB( I-J+KA1, J ) = AB( I-J+KA1, J ) / BII
353 DO 30 J = MAX( 1, I-KA ), I - 1
354 AB( J-I+KA1, I ) = AB( J-I+KA1, I ) / BII
356 DO 60 K = I - KBT, I - 1
358 AB( J-K+KA1, K ) = AB( J-K+KA1, K ) -
360 $ DCONJG( AB( K-I+KA1, I ) ) -
361 $ DCONJG( BB( K-I+KB1, I ) )*
363 $ DBLE( AB( KA1, I ) )*
365 $ DCONJG( BB( K-I+KB1, I ) )
367 DO 50 J = MAX( 1, I-KA ), I - KBT - 1
368 AB( J-K+KA1, K ) = AB( J-K+KA1, K ) -
369 $ DCONJG( BB( K-I+KB1, I ) )*
374 DO 70 K = MAX( J-KA, I-KBT ), I - 1
375 AB( K-J+KA1, J ) = AB( K-J+KA1, J ) -
376 $ BB( K-I+KB1, I )*AB( I-J+KA1, J )
382 * post-multiply X by inv(S(i))
384 CALL ZDSCAL( N-M, ONE / BII, X( M+1, I ), 1 )
386 $ CALL ZGERC( N-M, KBT, -CONE, X( M+1, I ), 1,
387 $ BB( KB1-KBT, I ), 1, X( M+1, I-KBT ),
391 * store a(i,i1) in RA1 for use in next loop over K
393 RA1 = AB( I-I1+KA1, I1 )
396 * Generate and apply vectors of rotations to chase all the
397 * existing bulges KA positions down toward the bottom of the
403 * Determine the rotations which would annihilate the bulge
404 * which has in theory just been created
406 IF( I-K+KA.LT.N .AND. I-K.GT.1 ) THEN
408 * generate rotation to annihilate a(i,i-k+ka+1)
410 CALL ZLARTG( AB( K+1, I-K+KA ), RA1,
411 $ RWORK( I-K+KA-M ), WORK( I-K+KA-M ), RA )
413 * create nonzero element a(i-k,i-k+ka+1) outside the
414 * band and store it in WORK(i-k)
416 T = -BB( KB1-K, I )*RA1
417 WORK( I-K ) = RWORK( I-K+KA-M )*T -
418 $ DCONJG( WORK( I-K+KA-M ) )*
420 AB( 1, I-K+KA ) = WORK( I-K+KA-M )*T +
421 $ RWORK( I-K+KA-M )*AB( 1, I-K+KA )
425 J2 = I - K - 1 + MAX( 1, K-I0+2 )*KA1
426 NR = ( N-J2+KA ) / KA1
427 J1 = J2 + ( NR-1 )*KA1
429 J2T = MAX( J2, I+2*KA-K+1 )
433 NRT = ( N-J2T+KA ) / KA1
434 DO 90 J = J2T, J1, KA1
436 * create nonzero element a(j-ka,j+1) outside the band
437 * and store it in WORK(j-m)
439 WORK( J-M ) = WORK( J-M )*AB( 1, J+1 )
440 AB( 1, J+1 ) = RWORK( J-M )*AB( 1, J+1 )
443 * generate rotations in 1st set to annihilate elements which
444 * have been created outside the band
447 $ CALL ZLARGV( NRT, AB( 1, J2T ), INCA, WORK( J2T-M ), KA1,
448 $ RWORK( J2T-M ), KA1 )
451 * apply rotations in 1st set from the right
454 CALL ZLARTV( NR, AB( KA1-L, J2 ), INCA,
455 $ AB( KA-L, J2+1 ), INCA, RWORK( J2-M ),
456 $ WORK( J2-M ), KA1 )
459 * apply rotations in 1st set from both sides to diagonal
462 CALL ZLAR2V( NR, AB( KA1, J2 ), AB( KA1, J2+1 ),
463 $ AB( KA, J2+1 ), INCA, RWORK( J2-M ),
464 $ WORK( J2-M ), KA1 )
466 CALL ZLACGV( NR, WORK( J2-M ), KA1 )
469 * start applying rotations in 1st set from the left
471 DO 110 L = KA - 1, KB - K + 1, -1
472 NRT = ( N-J2+L ) / KA1
474 $ CALL ZLARTV( NRT, AB( L, J2+KA1-L ), INCA,
475 $ AB( L+1, J2+KA1-L ), INCA, RWORK( J2-M ),
476 $ WORK( J2-M ), KA1 )
481 * post-multiply X by product of rotations in 1st set
483 DO 120 J = J2, J1, KA1
484 CALL ZROT( N-M, X( M+1, J ), 1, X( M+1, J+1 ), 1,
485 $ RWORK( J-M ), DCONJG( WORK( J-M ) ) )
491 IF( I2.LE.N .AND. KBT.GT.0 ) THEN
493 * create nonzero element a(i-kbt,i-kbt+ka+1) outside the
494 * band and store it in WORK(i-kbt)
496 WORK( I-KBT ) = -BB( KB1-KBT, I )*RA1
502 J2 = I - K - 1 + MAX( 2, K-I0+1 )*KA1
504 J2 = I - K - 1 + MAX( 1, K-I0+1 )*KA1
507 * finish applying rotations in 2nd set from the left
509 DO 140 L = KB - K, 1, -1
510 NRT = ( N-J2+KA+L ) / KA1
512 $ CALL ZLARTV( NRT, AB( L, J2-L+1 ), INCA,
513 $ AB( L+1, J2-L+1 ), INCA, RWORK( J2-KA ),
514 $ WORK( J2-KA ), KA1 )
516 NR = ( N-J2+KA ) / KA1
517 J1 = J2 + ( NR-1 )*KA1
518 DO 150 J = J1, J2, -KA1
519 WORK( J ) = WORK( J-KA )
520 RWORK( J ) = RWORK( J-KA )
522 DO 160 J = J2, J1, KA1
524 * create nonzero element a(j-ka,j+1) outside the band
525 * and store it in WORK(j)
527 WORK( J ) = WORK( J )*AB( 1, J+1 )
528 AB( 1, J+1 ) = RWORK( J )*AB( 1, J+1 )
531 IF( I-K.LT.N-KA .AND. K.LE.KBT )
532 $ WORK( I-K+KA ) = WORK( I-K )
537 J2 = I - K - 1 + MAX( 1, K-I0+1 )*KA1
538 NR = ( N-J2+KA ) / KA1
539 J1 = J2 + ( NR-1 )*KA1
542 * generate rotations in 2nd set to annihilate elements
543 * which have been created outside the band
545 CALL ZLARGV( NR, AB( 1, J2 ), INCA, WORK( J2 ), KA1,
548 * apply rotations in 2nd set from the right
551 CALL ZLARTV( NR, AB( KA1-L, J2 ), INCA,
552 $ AB( KA-L, J2+1 ), INCA, RWORK( J2 ),
556 * apply rotations in 2nd set from both sides to diagonal
559 CALL ZLAR2V( NR, AB( KA1, J2 ), AB( KA1, J2+1 ),
560 $ AB( KA, J2+1 ), INCA, RWORK( J2 ),
563 CALL ZLACGV( NR, WORK( J2 ), KA1 )
566 * start applying rotations in 2nd set from the left
568 DO 190 L = KA - 1, KB - K + 1, -1
569 NRT = ( N-J2+L ) / KA1
571 $ CALL ZLARTV( NRT, AB( L, J2+KA1-L ), INCA,
572 $ AB( L+1, J2+KA1-L ), INCA, RWORK( J2 ),
578 * post-multiply X by product of rotations in 2nd set
580 DO 200 J = J2, J1, KA1
581 CALL ZROT( N-M, X( M+1, J ), 1, X( M+1, J+1 ), 1,
582 $ RWORK( J ), DCONJG( WORK( J ) ) )
588 J2 = I - K - 1 + MAX( 1, K-I0+2 )*KA1
590 * finish applying rotations in 1st set from the left
592 DO 220 L = KB - K, 1, -1
593 NRT = ( N-J2+L ) / KA1
595 $ CALL ZLARTV( NRT, AB( L, J2+KA1-L ), INCA,
596 $ AB( L+1, J2+KA1-L ), INCA, RWORK( J2-M ),
597 $ WORK( J2-M ), KA1 )
602 DO 240 J = N - 1, J2 + KA, -1
603 RWORK( J-M ) = RWORK( J-KA-M )
604 WORK( J-M ) = WORK( J-KA-M )
610 * Transform A, working with the lower triangle
614 * Form inv(S(i))**H * A * inv(S(i))
616 BII = DBLE( BB( 1, I ) )
617 AB( 1, I ) = ( DBLE( AB( 1, I ) ) / BII ) / BII
619 AB( J-I+1, I ) = AB( J-I+1, I ) / BII
621 DO 260 J = MAX( 1, I-KA ), I - 1
622 AB( I-J+1, J ) = AB( I-J+1, J ) / BII
624 DO 290 K = I - KBT, I - 1
625 DO 270 J = I - KBT, K
626 AB( K-J+1, J ) = AB( K-J+1, J ) -
627 $ BB( I-J+1, J )*DCONJG( AB( I-K+1,
628 $ K ) ) - DCONJG( BB( I-K+1, K ) )*
629 $ AB( I-J+1, J ) + DBLE( AB( 1, I ) )*
630 $ BB( I-J+1, J )*DCONJG( BB( I-K+1,
633 DO 280 J = MAX( 1, I-KA ), I - KBT - 1
634 AB( K-J+1, J ) = AB( K-J+1, J ) -
635 $ DCONJG( BB( I-K+1, K ) )*
640 DO 300 K = MAX( J-KA, I-KBT ), I - 1
641 AB( J-K+1, K ) = AB( J-K+1, K ) -
642 $ BB( I-K+1, K )*AB( J-I+1, I )
648 * post-multiply X by inv(S(i))
650 CALL ZDSCAL( N-M, ONE / BII, X( M+1, I ), 1 )
652 $ CALL ZGERU( N-M, KBT, -CONE, X( M+1, I ), 1,
653 $ BB( KBT+1, I-KBT ), LDBB-1,
654 $ X( M+1, I-KBT ), LDX )
657 * store a(i1,i) in RA1 for use in next loop over K
659 RA1 = AB( I1-I+1, I )
662 * Generate and apply vectors of rotations to chase all the
663 * existing bulges KA positions down toward the bottom of the
669 * Determine the rotations which would annihilate the bulge
670 * which has in theory just been created
672 IF( I-K+KA.LT.N .AND. I-K.GT.1 ) THEN
674 * generate rotation to annihilate a(i-k+ka+1,i)
676 CALL ZLARTG( AB( KA1-K, I ), RA1, RWORK( I-K+KA-M ),
677 $ WORK( I-K+KA-M ), RA )
679 * create nonzero element a(i-k+ka+1,i-k) outside the
680 * band and store it in WORK(i-k)
682 T = -BB( K+1, I-K )*RA1
683 WORK( I-K ) = RWORK( I-K+KA-M )*T -
684 $ DCONJG( WORK( I-K+KA-M ) )*
686 AB( KA1, I-K ) = WORK( I-K+KA-M )*T +
687 $ RWORK( I-K+KA-M )*AB( KA1, I-K )
691 J2 = I - K - 1 + MAX( 1, K-I0+2 )*KA1
692 NR = ( N-J2+KA ) / KA1
693 J1 = J2 + ( NR-1 )*KA1
695 J2T = MAX( J2, I+2*KA-K+1 )
699 NRT = ( N-J2T+KA ) / KA1
700 DO 320 J = J2T, J1, KA1
702 * create nonzero element a(j+1,j-ka) outside the band
703 * and store it in WORK(j-m)
705 WORK( J-M ) = WORK( J-M )*AB( KA1, J-KA+1 )
706 AB( KA1, J-KA+1 ) = RWORK( J-M )*AB( KA1, J-KA+1 )
709 * generate rotations in 1st set to annihilate elements which
710 * have been created outside the band
713 $ CALL ZLARGV( NRT, AB( KA1, J2T-KA ), INCA, WORK( J2T-M ),
714 $ KA1, RWORK( J2T-M ), KA1 )
717 * apply rotations in 1st set from the left
720 CALL ZLARTV( NR, AB( L+1, J2-L ), INCA,
721 $ AB( L+2, J2-L ), INCA, RWORK( J2-M ),
722 $ WORK( J2-M ), KA1 )
725 * apply rotations in 1st set from both sides to diagonal
728 CALL ZLAR2V( NR, AB( 1, J2 ), AB( 1, J2+1 ), AB( 2, J2 ),
729 $ INCA, RWORK( J2-M ), WORK( J2-M ), KA1 )
731 CALL ZLACGV( NR, WORK( J2-M ), KA1 )
734 * start applying rotations in 1st set from the right
736 DO 340 L = KA - 1, KB - K + 1, -1
737 NRT = ( N-J2+L ) / KA1
739 $ CALL ZLARTV( NRT, AB( KA1-L+1, J2 ), INCA,
740 $ AB( KA1-L, J2+1 ), INCA, RWORK( J2-M ),
741 $ WORK( J2-M ), KA1 )
746 * post-multiply X by product of rotations in 1st set
748 DO 350 J = J2, J1, KA1
749 CALL ZROT( N-M, X( M+1, J ), 1, X( M+1, J+1 ), 1,
750 $ RWORK( J-M ), WORK( J-M ) )
756 IF( I2.LE.N .AND. KBT.GT.0 ) THEN
758 * create nonzero element a(i-kbt+ka+1,i-kbt) outside the
759 * band and store it in WORK(i-kbt)
761 WORK( I-KBT ) = -BB( KBT+1, I-KBT )*RA1
767 J2 = I - K - 1 + MAX( 2, K-I0+1 )*KA1
769 J2 = I - K - 1 + MAX( 1, K-I0+1 )*KA1
772 * finish applying rotations in 2nd set from the right
774 DO 370 L = KB - K, 1, -1
775 NRT = ( N-J2+KA+L ) / KA1
777 $ CALL ZLARTV( NRT, AB( KA1-L+1, J2-KA ), INCA,
778 $ AB( KA1-L, J2-KA+1 ), INCA,
779 $ RWORK( J2-KA ), WORK( J2-KA ), KA1 )
781 NR = ( N-J2+KA ) / KA1
782 J1 = J2 + ( NR-1 )*KA1
783 DO 380 J = J1, J2, -KA1
784 WORK( J ) = WORK( J-KA )
785 RWORK( J ) = RWORK( J-KA )
787 DO 390 J = J2, J1, KA1
789 * create nonzero element a(j+1,j-ka) outside the band
790 * and store it in WORK(j)
792 WORK( J ) = WORK( J )*AB( KA1, J-KA+1 )
793 AB( KA1, J-KA+1 ) = RWORK( J )*AB( KA1, J-KA+1 )
796 IF( I-K.LT.N-KA .AND. K.LE.KBT )
797 $ WORK( I-K+KA ) = WORK( I-K )
802 J2 = I - K - 1 + MAX( 1, K-I0+1 )*KA1
803 NR = ( N-J2+KA ) / KA1
804 J1 = J2 + ( NR-1 )*KA1
807 * generate rotations in 2nd set to annihilate elements
808 * which have been created outside the band
810 CALL ZLARGV( NR, AB( KA1, J2-KA ), INCA, WORK( J2 ), KA1,
813 * apply rotations in 2nd set from the left
816 CALL ZLARTV( NR, AB( L+1, J2-L ), INCA,
817 $ AB( L+2, J2-L ), INCA, RWORK( J2 ),
821 * apply rotations in 2nd set from both sides to diagonal
824 CALL ZLAR2V( NR, AB( 1, J2 ), AB( 1, J2+1 ), AB( 2, J2 ),
825 $ INCA, RWORK( J2 ), WORK( J2 ), KA1 )
827 CALL ZLACGV( NR, WORK( J2 ), KA1 )
830 * start applying rotations in 2nd set from the right
832 DO 420 L = KA - 1, KB - K + 1, -1
833 NRT = ( N-J2+L ) / KA1
835 $ CALL ZLARTV( NRT, AB( KA1-L+1, J2 ), INCA,
836 $ AB( KA1-L, J2+1 ), INCA, RWORK( J2 ),
842 * post-multiply X by product of rotations in 2nd set
844 DO 430 J = J2, J1, KA1
845 CALL ZROT( N-M, X( M+1, J ), 1, X( M+1, J+1 ), 1,
846 $ RWORK( J ), WORK( J ) )
852 J2 = I - K - 1 + MAX( 1, K-I0+2 )*KA1
854 * finish applying rotations in 1st set from the right
856 DO 450 L = KB - K, 1, -1
857 NRT = ( N-J2+L ) / KA1
859 $ CALL ZLARTV( NRT, AB( KA1-L+1, J2 ), INCA,
860 $ AB( KA1-L, J2+1 ), INCA, RWORK( J2-M ),
861 $ WORK( J2-M ), KA1 )
866 DO 470 J = N - 1, J2 + KA, -1
867 RWORK( J-M ) = RWORK( J-KA-M )
868 WORK( J-M ) = WORK( J-KA-M )
878 * **************************** Phase 2 *****************************
880 * The logical structure of this phase is:
884 * use S(i) to update A and create a new bulge
885 * apply rotations to push all bulges KA positions upward
888 * DO I = M - KA - 1, 2, -1
889 * apply rotations to push all bulges KA positions upward
892 * To avoid duplicating code, the two loops are merged.
917 IF( I.LT.M-KBT ) THEN
925 * Transform A, working with the upper triangle
929 * Form inv(S(i))**H * A * inv(S(i))
931 BII = DBLE( BB( KB1, I ) )
932 AB( KA1, I ) = ( DBLE( AB( KA1, I ) ) / BII ) / BII
934 AB( J-I+KA1, I ) = AB( J-I+KA1, I ) / BII
936 DO 510 J = I + 1, MIN( N, I+KA )
937 AB( I-J+KA1, J ) = AB( I-J+KA1, J ) / BII
939 DO 540 K = I + 1, I + KBT
940 DO 520 J = K, I + KBT
941 AB( K-J+KA1, J ) = AB( K-J+KA1, J ) -
943 $ DCONJG( AB( I-K+KA1, K ) ) -
944 $ DCONJG( BB( I-K+KB1, K ) )*
946 $ DBLE( AB( KA1, I ) )*
948 $ DCONJG( BB( I-K+KB1, K ) )
950 DO 530 J = I + KBT + 1, MIN( N, I+KA )
951 AB( K-J+KA1, J ) = AB( K-J+KA1, J ) -
952 $ DCONJG( BB( I-K+KB1, K ) )*
957 DO 550 K = I + 1, MIN( J+KA, I+KBT )
958 AB( J-K+KA1, K ) = AB( J-K+KA1, K ) -
959 $ BB( I-K+KB1, K )*AB( J-I+KA1, I )
965 * post-multiply X by inv(S(i))
967 CALL ZDSCAL( NX, ONE / BII, X( 1, I ), 1 )
969 $ CALL ZGERU( NX, KBT, -CONE, X( 1, I ), 1,
970 $ BB( KB, I+1 ), LDBB-1, X( 1, I+1 ), LDX )
973 * store a(i1,i) in RA1 for use in next loop over K
975 RA1 = AB( I1-I+KA1, I )
978 * Generate and apply vectors of rotations to chase all the
979 * existing bulges KA positions up toward the top of the band
984 * Determine the rotations which would annihilate the bulge
985 * which has in theory just been created
987 IF( I+K-KA1.GT.0 .AND. I+K.LT.M ) THEN
989 * generate rotation to annihilate a(i+k-ka-1,i)
991 CALL ZLARTG( AB( K+1, I ), RA1, RWORK( I+K-KA ),
992 $ WORK( I+K-KA ), RA )
994 * create nonzero element a(i+k-ka-1,i+k) outside the
995 * band and store it in WORK(m-kb+i+k)
997 T = -BB( KB1-K, I+K )*RA1
998 WORK( M-KB+I+K ) = RWORK( I+K-KA )*T -
999 $ DCONJG( WORK( I+K-KA ) )*
1001 AB( 1, I+K ) = WORK( I+K-KA )*T +
1002 $ RWORK( I+K-KA )*AB( 1, I+K )
1006 J2 = I + K + 1 - MAX( 1, K+I0-M+1 )*KA1
1007 NR = ( J2+KA-1 ) / KA1
1008 J1 = J2 - ( NR-1 )*KA1
1010 J2T = MIN( J2, I-2*KA+K-1 )
1014 NRT = ( J2T+KA-1 ) / KA1
1015 DO 570 J = J1, J2T, KA1
1017 * create nonzero element a(j-1,j+ka) outside the band
1018 * and store it in WORK(j)
1020 WORK( J ) = WORK( J )*AB( 1, J+KA-1 )
1021 AB( 1, J+KA-1 ) = RWORK( J )*AB( 1, J+KA-1 )
1024 * generate rotations in 1st set to annihilate elements which
1025 * have been created outside the band
1028 $ CALL ZLARGV( NRT, AB( 1, J1+KA ), INCA, WORK( J1 ), KA1,
1029 $ RWORK( J1 ), KA1 )
1032 * apply rotations in 1st set from the left
1034 DO 580 L = 1, KA - 1
1035 CALL ZLARTV( NR, AB( KA1-L, J1+L ), INCA,
1036 $ AB( KA-L, J1+L ), INCA, RWORK( J1 ),
1040 * apply rotations in 1st set from both sides to diagonal
1043 CALL ZLAR2V( NR, AB( KA1, J1 ), AB( KA1, J1-1 ),
1044 $ AB( KA, J1 ), INCA, RWORK( J1 ), WORK( J1 ),
1047 CALL ZLACGV( NR, WORK( J1 ), KA1 )
1050 * start applying rotations in 1st set from the right
1052 DO 590 L = KA - 1, KB - K + 1, -1
1053 NRT = ( J2+L-1 ) / KA1
1054 J1T = J2 - ( NRT-1 )*KA1
1056 $ CALL ZLARTV( NRT, AB( L, J1T ), INCA,
1057 $ AB( L+1, J1T-1 ), INCA, RWORK( J1T ),
1058 $ WORK( J1T ), KA1 )
1063 * post-multiply X by product of rotations in 1st set
1065 DO 600 J = J1, J2, KA1
1066 CALL ZROT( NX, X( 1, J ), 1, X( 1, J-1 ), 1,
1067 $ RWORK( J ), WORK( J ) )
1073 IF( I2.GT.0 .AND. KBT.GT.0 ) THEN
1075 * create nonzero element a(i+kbt-ka-1,i+kbt) outside the
1076 * band and store it in WORK(m-kb+i+kbt)
1078 WORK( M-KB+I+KBT ) = -BB( KB1-KBT, I+KBT )*RA1
1082 DO 650 K = KB, 1, -1
1084 J2 = I + K + 1 - MAX( 2, K+I0-M )*KA1
1086 J2 = I + K + 1 - MAX( 1, K+I0-M )*KA1
1089 * finish applying rotations in 2nd set from the right
1091 DO 620 L = KB - K, 1, -1
1092 NRT = ( J2+KA+L-1 ) / KA1
1093 J1T = J2 - ( NRT-1 )*KA1
1095 $ CALL ZLARTV( NRT, AB( L, J1T+KA ), INCA,
1096 $ AB( L+1, J1T+KA-1 ), INCA,
1097 $ RWORK( M-KB+J1T+KA ),
1098 $ WORK( M-KB+J1T+KA ), KA1 )
1100 NR = ( J2+KA-1 ) / KA1
1101 J1 = J2 - ( NR-1 )*KA1
1102 DO 630 J = J1, J2, KA1
1103 WORK( M-KB+J ) = WORK( M-KB+J+KA )
1104 RWORK( M-KB+J ) = RWORK( M-KB+J+KA )
1106 DO 640 J = J1, J2, KA1
1108 * create nonzero element a(j-1,j+ka) outside the band
1109 * and store it in WORK(m-kb+j)
1111 WORK( M-KB+J ) = WORK( M-KB+J )*AB( 1, J+KA-1 )
1112 AB( 1, J+KA-1 ) = RWORK( M-KB+J )*AB( 1, J+KA-1 )
1115 IF( I+K.GT.KA1 .AND. K.LE.KBT )
1116 $ WORK( M-KB+I+K-KA ) = WORK( M-KB+I+K )
1120 DO 690 K = KB, 1, -1
1121 J2 = I + K + 1 - MAX( 1, K+I0-M )*KA1
1122 NR = ( J2+KA-1 ) / KA1
1123 J1 = J2 - ( NR-1 )*KA1
1126 * generate rotations in 2nd set to annihilate elements
1127 * which have been created outside the band
1129 CALL ZLARGV( NR, AB( 1, J1+KA ), INCA, WORK( M-KB+J1 ),
1130 $ KA1, RWORK( M-KB+J1 ), KA1 )
1132 * apply rotations in 2nd set from the left
1134 DO 660 L = 1, KA - 1
1135 CALL ZLARTV( NR, AB( KA1-L, J1+L ), INCA,
1136 $ AB( KA-L, J1+L ), INCA, RWORK( M-KB+J1 ),
1137 $ WORK( M-KB+J1 ), KA1 )
1140 * apply rotations in 2nd set from both sides to diagonal
1143 CALL ZLAR2V( NR, AB( KA1, J1 ), AB( KA1, J1-1 ),
1144 $ AB( KA, J1 ), INCA, RWORK( M-KB+J1 ),
1145 $ WORK( M-KB+J1 ), KA1 )
1147 CALL ZLACGV( NR, WORK( M-KB+J1 ), KA1 )
1150 * start applying rotations in 2nd set from the right
1152 DO 670 L = KA - 1, KB - K + 1, -1
1153 NRT = ( J2+L-1 ) / KA1
1154 J1T = J2 - ( NRT-1 )*KA1
1156 $ CALL ZLARTV( NRT, AB( L, J1T ), INCA,
1157 $ AB( L+1, J1T-1 ), INCA,
1158 $ RWORK( M-KB+J1T ), WORK( M-KB+J1T ),
1164 * post-multiply X by product of rotations in 2nd set
1166 DO 680 J = J1, J2, KA1
1167 CALL ZROT( NX, X( 1, J ), 1, X( 1, J-1 ), 1,
1168 $ RWORK( M-KB+J ), WORK( M-KB+J ) )
1173 DO 710 K = 1, KB - 1
1174 J2 = I + K + 1 - MAX( 1, K+I0-M+1 )*KA1
1176 * finish applying rotations in 1st set from the right
1178 DO 700 L = KB - K, 1, -1
1179 NRT = ( J2+L-1 ) / KA1
1180 J1T = J2 - ( NRT-1 )*KA1
1182 $ CALL ZLARTV( NRT, AB( L, J1T ), INCA,
1183 $ AB( L+1, J1T-1 ), INCA, RWORK( J1T ),
1184 $ WORK( J1T ), KA1 )
1189 DO 720 J = 2, I2 - KA
1190 RWORK( J ) = RWORK( J+KA )
1191 WORK( J ) = WORK( J+KA )
1197 * Transform A, working with the lower triangle
1201 * Form inv(S(i))**H * A * inv(S(i))
1203 BII = DBLE( BB( 1, I ) )
1204 AB( 1, I ) = ( DBLE( AB( 1, I ) ) / BII ) / BII
1205 DO 730 J = I1, I - 1
1206 AB( I-J+1, J ) = AB( I-J+1, J ) / BII
1208 DO 740 J = I + 1, MIN( N, I+KA )
1209 AB( J-I+1, I ) = AB( J-I+1, I ) / BII
1211 DO 770 K = I + 1, I + KBT
1212 DO 750 J = K, I + KBT
1213 AB( J-K+1, K ) = AB( J-K+1, K ) -
1214 $ BB( J-I+1, I )*DCONJG( AB( K-I+1,
1215 $ I ) ) - DCONJG( BB( K-I+1, I ) )*
1216 $ AB( J-I+1, I ) + DBLE( AB( 1, I ) )*
1217 $ BB( J-I+1, I )*DCONJG( BB( K-I+1,
1220 DO 760 J = I + KBT + 1, MIN( N, I+KA )
1221 AB( J-K+1, K ) = AB( J-K+1, K ) -
1222 $ DCONJG( BB( K-I+1, I ) )*
1227 DO 780 K = I + 1, MIN( J+KA, I+KBT )
1228 AB( K-J+1, J ) = AB( K-J+1, J ) -
1229 $ BB( K-I+1, I )*AB( I-J+1, J )
1235 * post-multiply X by inv(S(i))
1237 CALL ZDSCAL( NX, ONE / BII, X( 1, I ), 1 )
1239 $ CALL ZGERC( NX, KBT, -CONE, X( 1, I ), 1, BB( 2, I ),
1240 $ 1, X( 1, I+1 ), LDX )
1243 * store a(i,i1) in RA1 for use in next loop over K
1245 RA1 = AB( I-I1+1, I1 )
1248 * Generate and apply vectors of rotations to chase all the
1249 * existing bulges KA positions up toward the top of the band
1251 DO 840 K = 1, KB - 1
1254 * Determine the rotations which would annihilate the bulge
1255 * which has in theory just been created
1257 IF( I+K-KA1.GT.0 .AND. I+K.LT.M ) THEN
1259 * generate rotation to annihilate a(i,i+k-ka-1)
1261 CALL ZLARTG( AB( KA1-K, I+K-KA ), RA1,
1262 $ RWORK( I+K-KA ), WORK( I+K-KA ), RA )
1264 * create nonzero element a(i+k,i+k-ka-1) outside the
1265 * band and store it in WORK(m-kb+i+k)
1267 T = -BB( K+1, I )*RA1
1268 WORK( M-KB+I+K ) = RWORK( I+K-KA )*T -
1269 $ DCONJG( WORK( I+K-KA ) )*
1271 AB( KA1, I+K-KA ) = WORK( I+K-KA )*T +
1272 $ RWORK( I+K-KA )*AB( KA1, I+K-KA )
1276 J2 = I + K + 1 - MAX( 1, K+I0-M+1 )*KA1
1277 NR = ( J2+KA-1 ) / KA1
1278 J1 = J2 - ( NR-1 )*KA1
1280 J2T = MIN( J2, I-2*KA+K-1 )
1284 NRT = ( J2T+KA-1 ) / KA1
1285 DO 800 J = J1, J2T, KA1
1287 * create nonzero element a(j+ka,j-1) outside the band
1288 * and store it in WORK(j)
1290 WORK( J ) = WORK( J )*AB( KA1, J-1 )
1291 AB( KA1, J-1 ) = RWORK( J )*AB( KA1, J-1 )
1294 * generate rotations in 1st set to annihilate elements which
1295 * have been created outside the band
1298 $ CALL ZLARGV( NRT, AB( KA1, J1 ), INCA, WORK( J1 ), KA1,
1299 $ RWORK( J1 ), KA1 )
1302 * apply rotations in 1st set from the right
1304 DO 810 L = 1, KA - 1
1305 CALL ZLARTV( NR, AB( L+1, J1 ), INCA, AB( L+2, J1-1 ),
1306 $ INCA, RWORK( J1 ), WORK( J1 ), KA1 )
1309 * apply rotations in 1st set from both sides to diagonal
1312 CALL ZLAR2V( NR, AB( 1, J1 ), AB( 1, J1-1 ),
1313 $ AB( 2, J1-1 ), INCA, RWORK( J1 ),
1316 CALL ZLACGV( NR, WORK( J1 ), KA1 )
1319 * start applying rotations in 1st set from the left
1321 DO 820 L = KA - 1, KB - K + 1, -1
1322 NRT = ( J2+L-1 ) / KA1
1323 J1T = J2 - ( NRT-1 )*KA1
1325 $ CALL ZLARTV( NRT, AB( KA1-L+1, J1T-KA1+L ), INCA,
1326 $ AB( KA1-L, J1T-KA1+L ), INCA,
1327 $ RWORK( J1T ), WORK( J1T ), KA1 )
1332 * post-multiply X by product of rotations in 1st set
1334 DO 830 J = J1, J2, KA1
1335 CALL ZROT( NX, X( 1, J ), 1, X( 1, J-1 ), 1,
1336 $ RWORK( J ), DCONJG( WORK( J ) ) )
1342 IF( I2.GT.0 .AND. KBT.GT.0 ) THEN
1344 * create nonzero element a(i+kbt,i+kbt-ka-1) outside the
1345 * band and store it in WORK(m-kb+i+kbt)
1347 WORK( M-KB+I+KBT ) = -BB( KBT+1, I )*RA1
1351 DO 880 K = KB, 1, -1
1353 J2 = I + K + 1 - MAX( 2, K+I0-M )*KA1
1355 J2 = I + K + 1 - MAX( 1, K+I0-M )*KA1
1358 * finish applying rotations in 2nd set from the left
1360 DO 850 L = KB - K, 1, -1
1361 NRT = ( J2+KA+L-1 ) / KA1
1362 J1T = J2 - ( NRT-1 )*KA1
1364 $ CALL ZLARTV( NRT, AB( KA1-L+1, J1T+L-1 ), INCA,
1365 $ AB( KA1-L, J1T+L-1 ), INCA,
1366 $ RWORK( M-KB+J1T+KA ),
1367 $ WORK( M-KB+J1T+KA ), KA1 )
1369 NR = ( J2+KA-1 ) / KA1
1370 J1 = J2 - ( NR-1 )*KA1
1371 DO 860 J = J1, J2, KA1
1372 WORK( M-KB+J ) = WORK( M-KB+J+KA )
1373 RWORK( M-KB+J ) = RWORK( M-KB+J+KA )
1375 DO 870 J = J1, J2, KA1
1377 * create nonzero element a(j+ka,j-1) outside the band
1378 * and store it in WORK(m-kb+j)
1380 WORK( M-KB+J ) = WORK( M-KB+J )*AB( KA1, J-1 )
1381 AB( KA1, J-1 ) = RWORK( M-KB+J )*AB( KA1, J-1 )
1384 IF( I+K.GT.KA1 .AND. K.LE.KBT )
1385 $ WORK( M-KB+I+K-KA ) = WORK( M-KB+I+K )
1389 DO 920 K = KB, 1, -1
1390 J2 = I + K + 1 - MAX( 1, K+I0-M )*KA1
1391 NR = ( J2+KA-1 ) / KA1
1392 J1 = J2 - ( NR-1 )*KA1
1395 * generate rotations in 2nd set to annihilate elements
1396 * which have been created outside the band
1398 CALL ZLARGV( NR, AB( KA1, J1 ), INCA, WORK( M-KB+J1 ),
1399 $ KA1, RWORK( M-KB+J1 ), KA1 )
1401 * apply rotations in 2nd set from the right
1403 DO 890 L = 1, KA - 1
1404 CALL ZLARTV( NR, AB( L+1, J1 ), INCA, AB( L+2, J1-1 ),
1405 $ INCA, RWORK( M-KB+J1 ), WORK( M-KB+J1 ),
1409 * apply rotations in 2nd set from both sides to diagonal
1412 CALL ZLAR2V( NR, AB( 1, J1 ), AB( 1, J1-1 ),
1413 $ AB( 2, J1-1 ), INCA, RWORK( M-KB+J1 ),
1414 $ WORK( M-KB+J1 ), KA1 )
1416 CALL ZLACGV( NR, WORK( M-KB+J1 ), KA1 )
1419 * start applying rotations in 2nd set from the left
1421 DO 900 L = KA - 1, KB - K + 1, -1
1422 NRT = ( J2+L-1 ) / KA1
1423 J1T = J2 - ( NRT-1 )*KA1
1425 $ CALL ZLARTV( NRT, AB( KA1-L+1, J1T-KA1+L ), INCA,
1426 $ AB( KA1-L, J1T-KA1+L ), INCA,
1427 $ RWORK( M-KB+J1T ), WORK( M-KB+J1T ),
1433 * post-multiply X by product of rotations in 2nd set
1435 DO 910 J = J1, J2, KA1
1436 CALL ZROT( NX, X( 1, J ), 1, X( 1, J-1 ), 1,
1437 $ RWORK( M-KB+J ), DCONJG( WORK( M-KB+J ) ) )
1442 DO 940 K = 1, KB - 1
1443 J2 = I + K + 1 - MAX( 1, K+I0-M+1 )*KA1
1445 * finish applying rotations in 1st set from the left
1447 DO 930 L = KB - K, 1, -1
1448 NRT = ( J2+L-1 ) / KA1
1449 J1T = J2 - ( NRT-1 )*KA1
1451 $ CALL ZLARTV( NRT, AB( KA1-L+1, J1T-KA1+L ), INCA,
1452 $ AB( KA1-L, J1T-KA1+L ), INCA,
1453 $ RWORK( J1T ), WORK( J1T ), KA1 )
1458 DO 950 J = 2, I2 - KA
1459 RWORK( J ) = RWORK( J+KA )
1460 WORK( J ) = WORK( J+KA )