3 * =========== DOCUMENTATION ===========
5 * Online html documentation available at
6 * http://www.netlib.org/lapack/explore-html/
9 *> Download SSBGST + dependencies
10 *> <a href="http://www.netlib.org/cgi-bin/netlibfiles.tgz?format=tgz&filename=/lapack/lapack_routine/ssbgst.f">
12 *> <a href="http://www.netlib.org/cgi-bin/netlibfiles.zip?format=zip&filename=/lapack/lapack_routine/ssbgst.f">
14 *> <a href="http://www.netlib.org/cgi-bin/netlibfiles.txt?format=txt&filename=/lapack/lapack_routine/ssbgst.f">
21 * SUBROUTINE SSBGST( VECT, UPLO, N, KA, KB, AB, LDAB, BB, LDBB, X,
24 * .. Scalar Arguments ..
25 * CHARACTER UPLO, VECT
26 * INTEGER INFO, KA, KB, LDAB, LDBB, LDX, N
28 * .. Array Arguments ..
29 * REAL AB( LDAB, * ), BB( LDBB, * ), WORK( * ),
39 *> SSBGST reduces a real symmetric-definite banded generalized
40 *> eigenproblem A*x = lambda*B*x to standard form C*y = lambda*y,
41 *> such that C has the same bandwidth as A.
43 *> B must have been previously factorized as S**T*S by SPBSTF, using a
44 *> split Cholesky factorization. A is overwritten by C = X**T*A*X, where
45 *> X = S**(-1)*Q and Q is an orthogonal matrix chosen to preserve the
54 *> VECT is CHARACTER*1
55 *> = 'N': do not form the transformation matrix X;
61 *> UPLO is CHARACTER*1
62 *> = 'U': Upper triangle of A is stored;
63 *> = 'L': Lower triangle of A is stored.
69 *> The order of the matrices A and B. N >= 0.
75 *> The number of superdiagonals of the matrix A if UPLO = 'U',
76 *> or the number of subdiagonals if UPLO = 'L'. KA >= 0.
82 *> The number of superdiagonals of the matrix B if UPLO = 'U',
83 *> or the number of subdiagonals if UPLO = 'L'. KA >= KB >= 0.
88 *> AB is REAL array, dimension (LDAB,N)
89 *> On entry, the upper or lower triangle of the symmetric band
90 *> matrix A, stored in the first ka+1 rows of the array. The
91 *> j-th column of A is stored in the j-th column of the array AB
93 *> if UPLO = 'U', AB(ka+1+i-j,j) = A(i,j) for max(1,j-ka)<=i<=j;
94 *> if UPLO = 'L', AB(1+i-j,j) = A(i,j) for j<=i<=min(n,j+ka).
96 *> On exit, the transformed matrix X**T*A*X, stored in the same
103 *> The leading dimension of the array AB. LDAB >= KA+1.
108 *> BB is REAL array, dimension (LDBB,N)
109 *> The banded factor S from the split Cholesky factorization of
110 *> B, as returned by SPBSTF, stored in the first KB+1 rows of
117 *> The leading dimension of the array BB. LDBB >= KB+1.
122 *> X is REAL array, dimension (LDX,N)
123 *> If VECT = 'V', the n-by-n matrix X.
124 *> If VECT = 'N', the array X is not referenced.
130 *> The leading dimension of the array X.
131 *> LDX >= max(1,N) if VECT = 'V'; LDX >= 1 otherwise.
136 *> WORK is REAL array, dimension (2*N)
142 *> = 0: successful exit
143 *> < 0: if INFO = -i, the i-th argument had an illegal value.
149 *> \author Univ. of Tennessee
150 *> \author Univ. of California Berkeley
151 *> \author Univ. of Colorado Denver
154 *> \date November 2011
156 *> \ingroup realOTHERcomputational
158 * =====================================================================
159 SUBROUTINE SSBGST( VECT, UPLO, N, KA, KB, AB, LDAB, BB, LDBB, X,
162 * -- LAPACK computational routine (version 3.4.0) --
163 * -- LAPACK is a software package provided by Univ. of Tennessee, --
164 * -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..--
167 * .. Scalar Arguments ..
169 INTEGER INFO, KA, KB, LDAB, LDBB, LDX, N
171 * .. Array Arguments ..
172 REAL AB( LDAB, * ), BB( LDBB, * ), WORK( * ),
176 * =====================================================================
180 PARAMETER ( ZERO = 0.0E+0, ONE = 1.0E+0 )
182 * .. Local Scalars ..
183 LOGICAL UPDATE, UPPER, WANTX
184 INTEGER I, I0, I1, I2, INCA, J, J1, J1T, J2, J2T, K,
185 $ KA1, KB1, KBT, L, M, NR, NRT, NX
188 * .. External Functions ..
192 * .. External Subroutines ..
193 EXTERNAL SGER, SLAR2V, SLARGV, SLARTG, SLARTV, SLASET,
194 $ SROT, SSCAL, XERBLA
196 * .. Intrinsic Functions ..
199 * .. Executable Statements ..
201 * Test the input parameters
203 WANTX = LSAME( VECT, 'V' )
204 UPPER = LSAME( UPLO, 'U' )
208 IF( .NOT.WANTX .AND. .NOT.LSAME( VECT, 'N' ) ) THEN
210 ELSE IF( .NOT.UPPER .AND. .NOT.LSAME( UPLO, 'L' ) ) THEN
212 ELSE IF( N.LT.0 ) THEN
214 ELSE IF( KA.LT.0 ) THEN
216 ELSE IF( KB.LT.0 .OR. KB.GT.KA ) THEN
218 ELSE IF( LDAB.LT.KA+1 ) THEN
220 ELSE IF( LDBB.LT.KB+1 ) THEN
222 ELSE IF( LDX.LT.1 .OR. WANTX .AND. LDX.LT.MAX( 1, N ) ) THEN
226 CALL XERBLA( 'SSBGST', -INFO )
230 * Quick return if possible
237 * Initialize X to the unit matrix, if needed
240 $ CALL SLASET( 'Full', N, N, ZERO, ONE, X, LDX )
242 * Set M to the splitting point m. It must be the same value as is
243 * used in SPBSTF. The chosen value allows the arrays WORK and RWORK
244 * to be of dimension (N).
248 * The routine works in two phases, corresponding to the two halves
249 * of the split Cholesky factorization of B as S**T*S where
254 * with U upper triangular of order m, and L lower triangular of
255 * order n-m. S has the same bandwidth as B.
257 * S is treated as a product of elementary matrices:
259 * S = S(m)*S(m-1)*...*S(2)*S(1)*S(m+1)*S(m+2)*...*S(n-1)*S(n)
261 * where S(i) is determined by the i-th row of S.
263 * In phase 1, the index i takes the values n, n-1, ... , m+1;
264 * in phase 2, it takes the values 1, 2, ... , m.
266 * For each value of i, the current matrix A is updated by forming
267 * inv(S(i))**T*A*inv(S(i)). This creates a triangular bulge outside
268 * the band of A. The bulge is then pushed down toward the bottom of
269 * A in phase 1, and up toward the top of A in phase 2, by applying
272 * There are kb*(kb+1)/2 elements in the bulge, but at most 2*kb-1
273 * of them are linearly independent, so annihilating a bulge requires
274 * only 2*kb-1 plane rotations. The rotations are divided into a 1st
275 * set of kb-1 rotations, and a 2nd set of kb rotations.
277 * Wherever possible, rotations are generated and applied in vector
278 * operations of length NR between the indices J1 and J2 (sometimes
279 * replaced by modified values NRT, J1T or J2T).
281 * The cosines and sines of the rotations are stored in the array
282 * WORK. The cosines of the 1st set of rotations are stored in
283 * elements n+2:n+m-kb-1 and the sines of the 1st set in elements
284 * 2:m-kb-1; the cosines of the 2nd set are stored in elements
285 * n+m-kb+1:2*n and the sines of the second set in elements m-kb+1:n.
287 * The bulges are not formed explicitly; nonzero elements outside the
288 * band are created only when they are required for generating new
289 * rotations; they are stored in the array WORK, in positions where
290 * they are later overwritten by the sines of the rotations which
293 * **************************** Phase 1 *****************************
295 * The logical structure of this phase is:
298 * DO I = N, M + 1, -1
299 * use S(i) to update A and create a new bulge
300 * apply rotations to push all bulges KA positions downward
303 * DO I = M + KA + 1, N - 1
304 * apply rotations to push all bulges KA positions downward
307 * To avoid duplicating code, the two loops are merged.
334 * Transform A, working with the upper triangle
338 * Form inv(S(i))**T * A * inv(S(i))
342 AB( I-J+KA1, J ) = AB( I-J+KA1, J ) / BII
344 DO 30 J = MAX( 1, I-KA ), I
345 AB( J-I+KA1, I ) = AB( J-I+KA1, I ) / BII
347 DO 60 K = I - KBT, I - 1
349 AB( J-K+KA1, K ) = AB( J-K+KA1, K ) -
350 $ BB( J-I+KB1, I )*AB( K-I+KA1, I ) -
351 $ BB( K-I+KB1, I )*AB( J-I+KA1, I ) +
352 $ AB( KA1, I )*BB( J-I+KB1, I )*
355 DO 50 J = MAX( 1, I-KA ), I - KBT - 1
356 AB( J-K+KA1, K ) = AB( J-K+KA1, K ) -
357 $ BB( K-I+KB1, I )*AB( J-I+KA1, I )
361 DO 70 K = MAX( J-KA, I-KBT ), I - 1
362 AB( K-J+KA1, J ) = AB( K-J+KA1, J ) -
363 $ BB( K-I+KB1, I )*AB( I-J+KA1, J )
369 * post-multiply X by inv(S(i))
371 CALL SSCAL( N-M, ONE / BII, X( M+1, I ), 1 )
373 $ CALL SGER( N-M, KBT, -ONE, X( M+1, I ), 1,
374 $ BB( KB1-KBT, I ), 1, X( M+1, I-KBT ), LDX )
377 * store a(i,i1) in RA1 for use in next loop over K
379 RA1 = AB( I-I1+KA1, I1 )
382 * Generate and apply vectors of rotations to chase all the
383 * existing bulges KA positions down toward the bottom of the
389 * Determine the rotations which would annihilate the bulge
390 * which has in theory just been created
392 IF( I-K+KA.LT.N .AND. I-K.GT.1 ) THEN
394 * generate rotation to annihilate a(i,i-k+ka+1)
396 CALL SLARTG( AB( K+1, I-K+KA ), RA1,
397 $ WORK( N+I-K+KA-M ), WORK( I-K+KA-M ),
400 * create nonzero element a(i-k,i-k+ka+1) outside the
401 * band and store it in WORK(i-k)
403 T = -BB( KB1-K, I )*RA1
404 WORK( I-K ) = WORK( N+I-K+KA-M )*T -
405 $ WORK( I-K+KA-M )*AB( 1, I-K+KA )
406 AB( 1, I-K+KA ) = WORK( I-K+KA-M )*T +
407 $ WORK( N+I-K+KA-M )*AB( 1, I-K+KA )
411 J2 = I - K - 1 + MAX( 1, K-I0+2 )*KA1
412 NR = ( N-J2+KA ) / KA1
413 J1 = J2 + ( NR-1 )*KA1
415 J2T = MAX( J2, I+2*KA-K+1 )
419 NRT = ( N-J2T+KA ) / KA1
420 DO 90 J = J2T, J1, KA1
422 * create nonzero element a(j-ka,j+1) outside the band
423 * and store it in WORK(j-m)
425 WORK( J-M ) = WORK( J-M )*AB( 1, J+1 )
426 AB( 1, J+1 ) = WORK( N+J-M )*AB( 1, J+1 )
429 * generate rotations in 1st set to annihilate elements which
430 * have been created outside the band
433 $ CALL SLARGV( NRT, AB( 1, J2T ), INCA, WORK( J2T-M ), KA1,
434 $ WORK( N+J2T-M ), KA1 )
437 * apply rotations in 1st set from the right
440 CALL SLARTV( NR, AB( KA1-L, J2 ), INCA,
441 $ AB( KA-L, J2+1 ), INCA, WORK( N+J2-M ),
442 $ WORK( J2-M ), KA1 )
445 * apply rotations in 1st set from both sides to diagonal
448 CALL SLAR2V( NR, AB( KA1, J2 ), AB( KA1, J2+1 ),
449 $ AB( KA, J2+1 ), INCA, WORK( N+J2-M ),
450 $ WORK( J2-M ), KA1 )
454 * start applying rotations in 1st set from the left
456 DO 110 L = KA - 1, KB - K + 1, -1
457 NRT = ( N-J2+L ) / KA1
459 $ CALL SLARTV( NRT, AB( L, J2+KA1-L ), INCA,
460 $ AB( L+1, J2+KA1-L ), INCA,
461 $ WORK( N+J2-M ), WORK( J2-M ), KA1 )
466 * post-multiply X by product of rotations in 1st set
468 DO 120 J = J2, J1, KA1
469 CALL SROT( N-M, X( M+1, J ), 1, X( M+1, J+1 ), 1,
470 $ WORK( N+J-M ), WORK( J-M ) )
476 IF( I2.LE.N .AND. KBT.GT.0 ) THEN
478 * create nonzero element a(i-kbt,i-kbt+ka+1) outside the
479 * band and store it in WORK(i-kbt)
481 WORK( I-KBT ) = -BB( KB1-KBT, I )*RA1
487 J2 = I - K - 1 + MAX( 2, K-I0+1 )*KA1
489 J2 = I - K - 1 + MAX( 1, K-I0+1 )*KA1
492 * finish applying rotations in 2nd set from the left
494 DO 140 L = KB - K, 1, -1
495 NRT = ( N-J2+KA+L ) / KA1
497 $ CALL SLARTV( NRT, AB( L, J2-L+1 ), INCA,
498 $ AB( L+1, J2-L+1 ), INCA, WORK( N+J2-KA ),
499 $ WORK( J2-KA ), KA1 )
501 NR = ( N-J2+KA ) / KA1
502 J1 = J2 + ( NR-1 )*KA1
503 DO 150 J = J1, J2, -KA1
504 WORK( J ) = WORK( J-KA )
505 WORK( N+J ) = WORK( N+J-KA )
507 DO 160 J = J2, J1, KA1
509 * create nonzero element a(j-ka,j+1) outside the band
510 * and store it in WORK(j)
512 WORK( J ) = WORK( J )*AB( 1, J+1 )
513 AB( 1, J+1 ) = WORK( N+J )*AB( 1, J+1 )
516 IF( I-K.LT.N-KA .AND. K.LE.KBT )
517 $ WORK( I-K+KA ) = WORK( I-K )
522 J2 = I - K - 1 + MAX( 1, K-I0+1 )*KA1
523 NR = ( N-J2+KA ) / KA1
524 J1 = J2 + ( NR-1 )*KA1
527 * generate rotations in 2nd set to annihilate elements
528 * which have been created outside the band
530 CALL SLARGV( NR, AB( 1, J2 ), INCA, WORK( J2 ), KA1,
531 $ WORK( N+J2 ), KA1 )
533 * apply rotations in 2nd set from the right
536 CALL SLARTV( NR, AB( KA1-L, J2 ), INCA,
537 $ AB( KA-L, J2+1 ), INCA, WORK( N+J2 ),
541 * apply rotations in 2nd set from both sides to diagonal
544 CALL SLAR2V( NR, AB( KA1, J2 ), AB( KA1, J2+1 ),
545 $ AB( KA, J2+1 ), INCA, WORK( N+J2 ),
550 * start applying rotations in 2nd set from the left
552 DO 190 L = KA - 1, KB - K + 1, -1
553 NRT = ( N-J2+L ) / KA1
555 $ CALL SLARTV( NRT, AB( L, J2+KA1-L ), INCA,
556 $ AB( L+1, J2+KA1-L ), INCA, WORK( N+J2 ),
562 * post-multiply X by product of rotations in 2nd set
564 DO 200 J = J2, J1, KA1
565 CALL SROT( N-M, X( M+1, J ), 1, X( M+1, J+1 ), 1,
566 $ WORK( N+J ), WORK( J ) )
572 J2 = I - K - 1 + MAX( 1, K-I0+2 )*KA1
574 * finish applying rotations in 1st set from the left
576 DO 220 L = KB - K, 1, -1
577 NRT = ( N-J2+L ) / KA1
579 $ CALL SLARTV( NRT, AB( L, J2+KA1-L ), INCA,
580 $ AB( L+1, J2+KA1-L ), INCA,
581 $ WORK( N+J2-M ), WORK( J2-M ), KA1 )
586 DO 240 J = N - 1, I - KB + 2*KA + 1, -1
587 WORK( N+J-M ) = WORK( N+J-KA-M )
588 WORK( J-M ) = WORK( J-KA-M )
594 * Transform A, working with the lower triangle
598 * Form inv(S(i))**T * A * inv(S(i))
602 AB( J-I+1, I ) = AB( J-I+1, I ) / BII
604 DO 260 J = MAX( 1, I-KA ), I
605 AB( I-J+1, J ) = AB( I-J+1, J ) / BII
607 DO 290 K = I - KBT, I - 1
608 DO 270 J = I - KBT, K
609 AB( K-J+1, J ) = AB( K-J+1, J ) -
610 $ BB( I-J+1, J )*AB( I-K+1, K ) -
611 $ BB( I-K+1, K )*AB( I-J+1, J ) +
612 $ AB( 1, I )*BB( I-J+1, J )*
615 DO 280 J = MAX( 1, I-KA ), I - KBT - 1
616 AB( K-J+1, J ) = AB( K-J+1, J ) -
617 $ BB( I-K+1, K )*AB( I-J+1, J )
621 DO 300 K = MAX( J-KA, I-KBT ), I - 1
622 AB( J-K+1, K ) = AB( J-K+1, K ) -
623 $ BB( I-K+1, K )*AB( J-I+1, I )
629 * post-multiply X by inv(S(i))
631 CALL SSCAL( N-M, ONE / BII, X( M+1, I ), 1 )
633 $ CALL SGER( N-M, KBT, -ONE, X( M+1, I ), 1,
634 $ BB( KBT+1, I-KBT ), LDBB-1,
635 $ X( M+1, I-KBT ), LDX )
638 * store a(i1,i) in RA1 for use in next loop over K
640 RA1 = AB( I1-I+1, I )
643 * Generate and apply vectors of rotations to chase all the
644 * existing bulges KA positions down toward the bottom of the
650 * Determine the rotations which would annihilate the bulge
651 * which has in theory just been created
653 IF( I-K+KA.LT.N .AND. I-K.GT.1 ) THEN
655 * generate rotation to annihilate a(i-k+ka+1,i)
657 CALL SLARTG( AB( KA1-K, I ), RA1, WORK( N+I-K+KA-M ),
658 $ WORK( I-K+KA-M ), RA )
660 * create nonzero element a(i-k+ka+1,i-k) outside the
661 * band and store it in WORK(i-k)
663 T = -BB( K+1, I-K )*RA1
664 WORK( I-K ) = WORK( N+I-K+KA-M )*T -
665 $ WORK( I-K+KA-M )*AB( KA1, I-K )
666 AB( KA1, I-K ) = WORK( I-K+KA-M )*T +
667 $ WORK( N+I-K+KA-M )*AB( KA1, I-K )
671 J2 = I - K - 1 + MAX( 1, K-I0+2 )*KA1
672 NR = ( N-J2+KA ) / KA1
673 J1 = J2 + ( NR-1 )*KA1
675 J2T = MAX( J2, I+2*KA-K+1 )
679 NRT = ( N-J2T+KA ) / KA1
680 DO 320 J = J2T, J1, KA1
682 * create nonzero element a(j+1,j-ka) outside the band
683 * and store it in WORK(j-m)
685 WORK( J-M ) = WORK( J-M )*AB( KA1, J-KA+1 )
686 AB( KA1, J-KA+1 ) = WORK( N+J-M )*AB( KA1, J-KA+1 )
689 * generate rotations in 1st set to annihilate elements which
690 * have been created outside the band
693 $ CALL SLARGV( NRT, AB( KA1, J2T-KA ), INCA, WORK( J2T-M ),
694 $ KA1, WORK( N+J2T-M ), KA1 )
697 * apply rotations in 1st set from the left
700 CALL SLARTV( NR, AB( L+1, J2-L ), INCA,
701 $ AB( L+2, J2-L ), INCA, WORK( N+J2-M ),
702 $ WORK( J2-M ), KA1 )
705 * apply rotations in 1st set from both sides to diagonal
708 CALL SLAR2V( NR, AB( 1, J2 ), AB( 1, J2+1 ), AB( 2, J2 ),
709 $ INCA, WORK( N+J2-M ), WORK( J2-M ), KA1 )
713 * start applying rotations in 1st set from the right
715 DO 340 L = KA - 1, KB - K + 1, -1
716 NRT = ( N-J2+L ) / KA1
718 $ CALL SLARTV( NRT, AB( KA1-L+1, J2 ), INCA,
719 $ AB( KA1-L, J2+1 ), INCA, WORK( N+J2-M ),
720 $ WORK( J2-M ), KA1 )
725 * post-multiply X by product of rotations in 1st set
727 DO 350 J = J2, J1, KA1
728 CALL SROT( N-M, X( M+1, J ), 1, X( M+1, J+1 ), 1,
729 $ WORK( N+J-M ), WORK( J-M ) )
735 IF( I2.LE.N .AND. KBT.GT.0 ) THEN
737 * create nonzero element a(i-kbt+ka+1,i-kbt) outside the
738 * band and store it in WORK(i-kbt)
740 WORK( I-KBT ) = -BB( KBT+1, I-KBT )*RA1
746 J2 = I - K - 1 + MAX( 2, K-I0+1 )*KA1
748 J2 = I - K - 1 + MAX( 1, K-I0+1 )*KA1
751 * finish applying rotations in 2nd set from the right
753 DO 370 L = KB - K, 1, -1
754 NRT = ( N-J2+KA+L ) / KA1
756 $ CALL SLARTV( NRT, AB( KA1-L+1, J2-KA ), INCA,
757 $ AB( KA1-L, J2-KA+1 ), INCA,
758 $ WORK( N+J2-KA ), WORK( J2-KA ), KA1 )
760 NR = ( N-J2+KA ) / KA1
761 J1 = J2 + ( NR-1 )*KA1
762 DO 380 J = J1, J2, -KA1
763 WORK( J ) = WORK( J-KA )
764 WORK( N+J ) = WORK( N+J-KA )
766 DO 390 J = J2, J1, KA1
768 * create nonzero element a(j+1,j-ka) outside the band
769 * and store it in WORK(j)
771 WORK( J ) = WORK( J )*AB( KA1, J-KA+1 )
772 AB( KA1, J-KA+1 ) = WORK( N+J )*AB( KA1, J-KA+1 )
775 IF( I-K.LT.N-KA .AND. K.LE.KBT )
776 $ WORK( I-K+KA ) = WORK( I-K )
781 J2 = I - K - 1 + MAX( 1, K-I0+1 )*KA1
782 NR = ( N-J2+KA ) / KA1
783 J1 = J2 + ( NR-1 )*KA1
786 * generate rotations in 2nd set to annihilate elements
787 * which have been created outside the band
789 CALL SLARGV( NR, AB( KA1, J2-KA ), INCA, WORK( J2 ), KA1,
790 $ WORK( N+J2 ), KA1 )
792 * apply rotations in 2nd set from the left
795 CALL SLARTV( NR, AB( L+1, J2-L ), INCA,
796 $ AB( L+2, J2-L ), INCA, WORK( N+J2 ),
800 * apply rotations in 2nd set from both sides to diagonal
803 CALL SLAR2V( NR, AB( 1, J2 ), AB( 1, J2+1 ), AB( 2, J2 ),
804 $ INCA, WORK( N+J2 ), WORK( J2 ), KA1 )
808 * start applying rotations in 2nd set from the right
810 DO 420 L = KA - 1, KB - K + 1, -1
811 NRT = ( N-J2+L ) / KA1
813 $ CALL SLARTV( NRT, AB( KA1-L+1, J2 ), INCA,
814 $ AB( KA1-L, J2+1 ), INCA, WORK( N+J2 ),
820 * post-multiply X by product of rotations in 2nd set
822 DO 430 J = J2, J1, KA1
823 CALL SROT( N-M, X( M+1, J ), 1, X( M+1, J+1 ), 1,
824 $ WORK( N+J ), WORK( J ) )
830 J2 = I - K - 1 + MAX( 1, K-I0+2 )*KA1
832 * finish applying rotations in 1st set from the right
834 DO 450 L = KB - K, 1, -1
835 NRT = ( N-J2+L ) / KA1
837 $ CALL SLARTV( NRT, AB( KA1-L+1, J2 ), INCA,
838 $ AB( KA1-L, J2+1 ), INCA, WORK( N+J2-M ),
839 $ WORK( J2-M ), KA1 )
844 DO 470 J = N - 1, I - KB + 2*KA + 1, -1
845 WORK( N+J-M ) = WORK( N+J-KA-M )
846 WORK( J-M ) = WORK( J-KA-M )
856 * **************************** Phase 2 *****************************
858 * The logical structure of this phase is:
862 * use S(i) to update A and create a new bulge
863 * apply rotations to push all bulges KA positions upward
866 * DO I = M - KA - 1, 2, -1
867 * apply rotations to push all bulges KA positions upward
870 * To avoid duplicating code, the two loops are merged.
895 IF( I.LT.M-KBT ) THEN
903 * Transform A, working with the upper triangle
907 * Form inv(S(i))**T * A * inv(S(i))
911 AB( J-I+KA1, I ) = AB( J-I+KA1, I ) / BII
913 DO 510 J = I, MIN( N, I+KA )
914 AB( I-J+KA1, J ) = AB( I-J+KA1, J ) / BII
916 DO 540 K = I + 1, I + KBT
917 DO 520 J = K, I + KBT
918 AB( K-J+KA1, J ) = AB( K-J+KA1, J ) -
919 $ BB( I-J+KB1, J )*AB( I-K+KA1, K ) -
920 $ BB( I-K+KB1, K )*AB( I-J+KA1, J ) +
921 $ AB( KA1, I )*BB( I-J+KB1, J )*
924 DO 530 J = I + KBT + 1, MIN( N, I+KA )
925 AB( K-J+KA1, J ) = AB( K-J+KA1, J ) -
926 $ BB( I-K+KB1, K )*AB( I-J+KA1, J )
930 DO 550 K = I + 1, MIN( J+KA, I+KBT )
931 AB( J-K+KA1, K ) = AB( J-K+KA1, K ) -
932 $ BB( I-K+KB1, K )*AB( J-I+KA1, I )
938 * post-multiply X by inv(S(i))
940 CALL SSCAL( NX, ONE / BII, X( 1, I ), 1 )
942 $ CALL SGER( NX, KBT, -ONE, X( 1, I ), 1, BB( KB, I+1 ),
943 $ LDBB-1, X( 1, I+1 ), LDX )
946 * store a(i1,i) in RA1 for use in next loop over K
948 RA1 = AB( I1-I+KA1, I )
951 * Generate and apply vectors of rotations to chase all the
952 * existing bulges KA positions up toward the top of the band
957 * Determine the rotations which would annihilate the bulge
958 * which has in theory just been created
960 IF( I+K-KA1.GT.0 .AND. I+K.LT.M ) THEN
962 * generate rotation to annihilate a(i+k-ka-1,i)
964 CALL SLARTG( AB( K+1, I ), RA1, WORK( N+I+K-KA ),
965 $ WORK( I+K-KA ), RA )
967 * create nonzero element a(i+k-ka-1,i+k) outside the
968 * band and store it in WORK(m-kb+i+k)
970 T = -BB( KB1-K, I+K )*RA1
971 WORK( M-KB+I+K ) = WORK( N+I+K-KA )*T -
972 $ WORK( I+K-KA )*AB( 1, I+K )
973 AB( 1, I+K ) = WORK( I+K-KA )*T +
974 $ WORK( N+I+K-KA )*AB( 1, I+K )
978 J2 = I + K + 1 - MAX( 1, K+I0-M+1 )*KA1
979 NR = ( J2+KA-1 ) / KA1
980 J1 = J2 - ( NR-1 )*KA1
982 J2T = MIN( J2, I-2*KA+K-1 )
986 NRT = ( J2T+KA-1 ) / KA1
987 DO 570 J = J1, J2T, KA1
989 * create nonzero element a(j-1,j+ka) outside the band
990 * and store it in WORK(j)
992 WORK( J ) = WORK( J )*AB( 1, J+KA-1 )
993 AB( 1, J+KA-1 ) = WORK( N+J )*AB( 1, J+KA-1 )
996 * generate rotations in 1st set to annihilate elements which
997 * have been created outside the band
1000 $ CALL SLARGV( NRT, AB( 1, J1+KA ), INCA, WORK( J1 ), KA1,
1001 $ WORK( N+J1 ), KA1 )
1004 * apply rotations in 1st set from the left
1006 DO 580 L = 1, KA - 1
1007 CALL SLARTV( NR, AB( KA1-L, J1+L ), INCA,
1008 $ AB( KA-L, J1+L ), INCA, WORK( N+J1 ),
1012 * apply rotations in 1st set from both sides to diagonal
1015 CALL SLAR2V( NR, AB( KA1, J1 ), AB( KA1, J1-1 ),
1016 $ AB( KA, J1 ), INCA, WORK( N+J1 ),
1021 * start applying rotations in 1st set from the right
1023 DO 590 L = KA - 1, KB - K + 1, -1
1024 NRT = ( J2+L-1 ) / KA1
1025 J1T = J2 - ( NRT-1 )*KA1
1027 $ CALL SLARTV( NRT, AB( L, J1T ), INCA,
1028 $ AB( L+1, J1T-1 ), INCA, WORK( N+J1T ),
1029 $ WORK( J1T ), KA1 )
1034 * post-multiply X by product of rotations in 1st set
1036 DO 600 J = J1, J2, KA1
1037 CALL SROT( NX, X( 1, J ), 1, X( 1, J-1 ), 1,
1038 $ WORK( N+J ), WORK( J ) )
1044 IF( I2.GT.0 .AND. KBT.GT.0 ) THEN
1046 * create nonzero element a(i+kbt-ka-1,i+kbt) outside the
1047 * band and store it in WORK(m-kb+i+kbt)
1049 WORK( M-KB+I+KBT ) = -BB( KB1-KBT, I+KBT )*RA1
1053 DO 650 K = KB, 1, -1
1055 J2 = I + K + 1 - MAX( 2, K+I0-M )*KA1
1057 J2 = I + K + 1 - MAX( 1, K+I0-M )*KA1
1060 * finish applying rotations in 2nd set from the right
1062 DO 620 L = KB - K, 1, -1
1063 NRT = ( J2+KA+L-1 ) / KA1
1064 J1T = J2 - ( NRT-1 )*KA1
1066 $ CALL SLARTV( NRT, AB( L, J1T+KA ), INCA,
1067 $ AB( L+1, J1T+KA-1 ), INCA,
1068 $ WORK( N+M-KB+J1T+KA ),
1069 $ WORK( M-KB+J1T+KA ), KA1 )
1071 NR = ( J2+KA-1 ) / KA1
1072 J1 = J2 - ( NR-1 )*KA1
1073 DO 630 J = J1, J2, KA1
1074 WORK( M-KB+J ) = WORK( M-KB+J+KA )
1075 WORK( N+M-KB+J ) = WORK( N+M-KB+J+KA )
1077 DO 640 J = J1, J2, KA1
1079 * create nonzero element a(j-1,j+ka) outside the band
1080 * and store it in WORK(m-kb+j)
1082 WORK( M-KB+J ) = WORK( M-KB+J )*AB( 1, J+KA-1 )
1083 AB( 1, J+KA-1 ) = WORK( N+M-KB+J )*AB( 1, J+KA-1 )
1086 IF( I+K.GT.KA1 .AND. K.LE.KBT )
1087 $ WORK( M-KB+I+K-KA ) = WORK( M-KB+I+K )
1091 DO 690 K = KB, 1, -1
1092 J2 = I + K + 1 - MAX( 1, K+I0-M )*KA1
1093 NR = ( J2+KA-1 ) / KA1
1094 J1 = J2 - ( NR-1 )*KA1
1097 * generate rotations in 2nd set to annihilate elements
1098 * which have been created outside the band
1100 CALL SLARGV( NR, AB( 1, J1+KA ), INCA, WORK( M-KB+J1 ),
1101 $ KA1, WORK( N+M-KB+J1 ), KA1 )
1103 * apply rotations in 2nd set from the left
1105 DO 660 L = 1, KA - 1
1106 CALL SLARTV( NR, AB( KA1-L, J1+L ), INCA,
1107 $ AB( KA-L, J1+L ), INCA,
1108 $ WORK( N+M-KB+J1 ), WORK( M-KB+J1 ), KA1 )
1111 * apply rotations in 2nd set from both sides to diagonal
1114 CALL SLAR2V( NR, AB( KA1, J1 ), AB( KA1, J1-1 ),
1115 $ AB( KA, J1 ), INCA, WORK( N+M-KB+J1 ),
1116 $ WORK( M-KB+J1 ), KA1 )
1120 * start applying rotations in 2nd set from the right
1122 DO 670 L = KA - 1, KB - K + 1, -1
1123 NRT = ( J2+L-1 ) / KA1
1124 J1T = J2 - ( NRT-1 )*KA1
1126 $ CALL SLARTV( NRT, AB( L, J1T ), INCA,
1127 $ AB( L+1, J1T-1 ), INCA,
1128 $ WORK( N+M-KB+J1T ), WORK( M-KB+J1T ),
1134 * post-multiply X by product of rotations in 2nd set
1136 DO 680 J = J1, J2, KA1
1137 CALL SROT( NX, X( 1, J ), 1, X( 1, J-1 ), 1,
1138 $ WORK( N+M-KB+J ), WORK( M-KB+J ) )
1143 DO 710 K = 1, KB - 1
1144 J2 = I + K + 1 - MAX( 1, K+I0-M+1 )*KA1
1146 * finish applying rotations in 1st set from the right
1148 DO 700 L = KB - K, 1, -1
1149 NRT = ( J2+L-1 ) / KA1
1150 J1T = J2 - ( NRT-1 )*KA1
1152 $ CALL SLARTV( NRT, AB( L, J1T ), INCA,
1153 $ AB( L+1, J1T-1 ), INCA, WORK( N+J1T ),
1154 $ WORK( J1T ), KA1 )
1159 DO 720 J = 2, MIN( I+KB, M ) - 2*KA - 1
1160 WORK( N+J ) = WORK( N+J+KA )
1161 WORK( J ) = WORK( J+KA )
1167 * Transform A, working with the lower triangle
1171 * Form inv(S(i))**T * A * inv(S(i))
1175 AB( I-J+1, J ) = AB( I-J+1, J ) / BII
1177 DO 740 J = I, MIN( N, I+KA )
1178 AB( J-I+1, I ) = AB( J-I+1, I ) / BII
1180 DO 770 K = I + 1, I + KBT
1181 DO 750 J = K, I + KBT
1182 AB( J-K+1, K ) = AB( J-K+1, K ) -
1183 $ BB( J-I+1, I )*AB( K-I+1, I ) -
1184 $ BB( K-I+1, I )*AB( J-I+1, I ) +
1185 $ AB( 1, I )*BB( J-I+1, I )*
1188 DO 760 J = I + KBT + 1, MIN( N, I+KA )
1189 AB( J-K+1, K ) = AB( J-K+1, K ) -
1190 $ BB( K-I+1, I )*AB( J-I+1, I )
1194 DO 780 K = I + 1, MIN( J+KA, I+KBT )
1195 AB( K-J+1, J ) = AB( K-J+1, J ) -
1196 $ BB( K-I+1, I )*AB( I-J+1, J )
1202 * post-multiply X by inv(S(i))
1204 CALL SSCAL( NX, ONE / BII, X( 1, I ), 1 )
1206 $ CALL SGER( NX, KBT, -ONE, X( 1, I ), 1, BB( 2, I ), 1,
1207 $ X( 1, I+1 ), LDX )
1210 * store a(i,i1) in RA1 for use in next loop over K
1212 RA1 = AB( I-I1+1, I1 )
1215 * Generate and apply vectors of rotations to chase all the
1216 * existing bulges KA positions up toward the top of the band
1218 DO 840 K = 1, KB - 1
1221 * Determine the rotations which would annihilate the bulge
1222 * which has in theory just been created
1224 IF( I+K-KA1.GT.0 .AND. I+K.LT.M ) THEN
1226 * generate rotation to annihilate a(i,i+k-ka-1)
1228 CALL SLARTG( AB( KA1-K, I+K-KA ), RA1,
1229 $ WORK( N+I+K-KA ), WORK( I+K-KA ), RA )
1231 * create nonzero element a(i+k,i+k-ka-1) outside the
1232 * band and store it in WORK(m-kb+i+k)
1234 T = -BB( K+1, I )*RA1
1235 WORK( M-KB+I+K ) = WORK( N+I+K-KA )*T -
1236 $ WORK( I+K-KA )*AB( KA1, I+K-KA )
1237 AB( KA1, I+K-KA ) = WORK( I+K-KA )*T +
1238 $ WORK( N+I+K-KA )*AB( KA1, I+K-KA )
1242 J2 = I + K + 1 - MAX( 1, K+I0-M+1 )*KA1
1243 NR = ( J2+KA-1 ) / KA1
1244 J1 = J2 - ( NR-1 )*KA1
1246 J2T = MIN( J2, I-2*KA+K-1 )
1250 NRT = ( J2T+KA-1 ) / KA1
1251 DO 800 J = J1, J2T, KA1
1253 * create nonzero element a(j+ka,j-1) outside the band
1254 * and store it in WORK(j)
1256 WORK( J ) = WORK( J )*AB( KA1, J-1 )
1257 AB( KA1, J-1 ) = WORK( N+J )*AB( KA1, J-1 )
1260 * generate rotations in 1st set to annihilate elements which
1261 * have been created outside the band
1264 $ CALL SLARGV( NRT, AB( KA1, J1 ), INCA, WORK( J1 ), KA1,
1265 $ WORK( N+J1 ), KA1 )
1268 * apply rotations in 1st set from the right
1270 DO 810 L = 1, KA - 1
1271 CALL SLARTV( NR, AB( L+1, J1 ), INCA, AB( L+2, J1-1 ),
1272 $ INCA, WORK( N+J1 ), WORK( J1 ), KA1 )
1275 * apply rotations in 1st set from both sides to diagonal
1278 CALL SLAR2V( NR, AB( 1, J1 ), AB( 1, J1-1 ),
1279 $ AB( 2, J1-1 ), INCA, WORK( N+J1 ),
1284 * start applying rotations in 1st set from the left
1286 DO 820 L = KA - 1, KB - K + 1, -1
1287 NRT = ( J2+L-1 ) / KA1
1288 J1T = J2 - ( NRT-1 )*KA1
1290 $ CALL SLARTV( NRT, AB( KA1-L+1, J1T-KA1+L ), INCA,
1291 $ AB( KA1-L, J1T-KA1+L ), INCA,
1292 $ WORK( N+J1T ), WORK( J1T ), KA1 )
1297 * post-multiply X by product of rotations in 1st set
1299 DO 830 J = J1, J2, KA1
1300 CALL SROT( NX, X( 1, J ), 1, X( 1, J-1 ), 1,
1301 $ WORK( N+J ), WORK( J ) )
1307 IF( I2.GT.0 .AND. KBT.GT.0 ) THEN
1309 * create nonzero element a(i+kbt,i+kbt-ka-1) outside the
1310 * band and store it in WORK(m-kb+i+kbt)
1312 WORK( M-KB+I+KBT ) = -BB( KBT+1, I )*RA1
1316 DO 880 K = KB, 1, -1
1318 J2 = I + K + 1 - MAX( 2, K+I0-M )*KA1
1320 J2 = I + K + 1 - MAX( 1, K+I0-M )*KA1
1323 * finish applying rotations in 2nd set from the left
1325 DO 850 L = KB - K, 1, -1
1326 NRT = ( J2+KA+L-1 ) / KA1
1327 J1T = J2 - ( NRT-1 )*KA1
1329 $ CALL SLARTV( NRT, AB( KA1-L+1, J1T+L-1 ), INCA,
1330 $ AB( KA1-L, J1T+L-1 ), INCA,
1331 $ WORK( N+M-KB+J1T+KA ),
1332 $ WORK( M-KB+J1T+KA ), KA1 )
1334 NR = ( J2+KA-1 ) / KA1
1335 J1 = J2 - ( NR-1 )*KA1
1336 DO 860 J = J1, J2, KA1
1337 WORK( M-KB+J ) = WORK( M-KB+J+KA )
1338 WORK( N+M-KB+J ) = WORK( N+M-KB+J+KA )
1340 DO 870 J = J1, J2, KA1
1342 * create nonzero element a(j+ka,j-1) outside the band
1343 * and store it in WORK(m-kb+j)
1345 WORK( M-KB+J ) = WORK( M-KB+J )*AB( KA1, J-1 )
1346 AB( KA1, J-1 ) = WORK( N+M-KB+J )*AB( KA1, J-1 )
1349 IF( I+K.GT.KA1 .AND. K.LE.KBT )
1350 $ WORK( M-KB+I+K-KA ) = WORK( M-KB+I+K )
1354 DO 920 K = KB, 1, -1
1355 J2 = I + K + 1 - MAX( 1, K+I0-M )*KA1
1356 NR = ( J2+KA-1 ) / KA1
1357 J1 = J2 - ( NR-1 )*KA1
1360 * generate rotations in 2nd set to annihilate elements
1361 * which have been created outside the band
1363 CALL SLARGV( NR, AB( KA1, J1 ), INCA, WORK( M-KB+J1 ),
1364 $ KA1, WORK( N+M-KB+J1 ), KA1 )
1366 * apply rotations in 2nd set from the right
1368 DO 890 L = 1, KA - 1
1369 CALL SLARTV( NR, AB( L+1, J1 ), INCA, AB( L+2, J1-1 ),
1370 $ INCA, WORK( N+M-KB+J1 ), WORK( M-KB+J1 ),
1374 * apply rotations in 2nd set from both sides to diagonal
1377 CALL SLAR2V( NR, AB( 1, J1 ), AB( 1, J1-1 ),
1378 $ AB( 2, J1-1 ), INCA, WORK( N+M-KB+J1 ),
1379 $ WORK( M-KB+J1 ), KA1 )
1383 * start applying rotations in 2nd set from the left
1385 DO 900 L = KA - 1, KB - K + 1, -1
1386 NRT = ( J2+L-1 ) / KA1
1387 J1T = J2 - ( NRT-1 )*KA1
1389 $ CALL SLARTV( NRT, AB( KA1-L+1, J1T-KA1+L ), INCA,
1390 $ AB( KA1-L, J1T-KA1+L ), INCA,
1391 $ WORK( N+M-KB+J1T ), WORK( M-KB+J1T ),
1397 * post-multiply X by product of rotations in 2nd set
1399 DO 910 J = J1, J2, KA1
1400 CALL SROT( NX, X( 1, J ), 1, X( 1, J-1 ), 1,
1401 $ WORK( N+M-KB+J ), WORK( M-KB+J ) )
1406 DO 940 K = 1, KB - 1
1407 J2 = I + K + 1 - MAX( 1, K+I0-M+1 )*KA1
1409 * finish applying rotations in 1st set from the left
1411 DO 930 L = KB - K, 1, -1
1412 NRT = ( J2+L-1 ) / KA1
1413 J1T = J2 - ( NRT-1 )*KA1
1415 $ CALL SLARTV( NRT, AB( KA1-L+1, J1T-KA1+L ), INCA,
1416 $ AB( KA1-L, J1T-KA1+L ), INCA,
1417 $ WORK( N+J1T ), WORK( J1T ), KA1 )
1422 DO 950 J = 2, MIN( I+KB, M ) - 2*KA - 1
1423 WORK( N+J ) = WORK( N+J+KA )
1424 WORK( J ) = WORK( J+KA )