zhbgst.f.html
来自「famous linear algebra library (LAPACK) p」· HTML 代码 · 共 1,016 行 · 第 1/5 页
HTML
1,016 行
</span><span class="comment">*</span><span class="comment"> A in phase 1, and up toward the top of A in phase 2, by applying
</span><span class="comment">*</span><span class="comment"> plane rotations.
</span><span class="comment">*</span><span class="comment">
</span><span class="comment">*</span><span class="comment"> There are kb*(kb+1)/2 elements in the bulge, but at most 2*kb-1
</span><span class="comment">*</span><span class="comment"> of them are linearly independent, so annihilating a bulge requires
</span><span class="comment">*</span><span class="comment"> only 2*kb-1 plane rotations. The rotations are divided into a 1st
</span><span class="comment">*</span><span class="comment"> set of kb-1 rotations, and a 2nd set of kb rotations.
</span><span class="comment">*</span><span class="comment">
</span><span class="comment">*</span><span class="comment"> Wherever possible, rotations are generated and applied in vector
</span><span class="comment">*</span><span class="comment"> operations of length NR between the indices J1 and J2 (sometimes
</span><span class="comment">*</span><span class="comment"> replaced by modified values NRT, J1T or J2T).
</span><span class="comment">*</span><span class="comment">
</span><span class="comment">*</span><span class="comment"> The real cosines and complex sines of the rotations are stored in
</span><span class="comment">*</span><span class="comment"> the arrays RWORK and WORK, those of the 1st set in elements
</span><span class="comment">*</span><span class="comment"> 2:m-kb-1, and those of the 2nd set in elements m-kb+1:n.
</span><span class="comment">*</span><span class="comment">
</span><span class="comment">*</span><span class="comment"> The bulges are not formed explicitly; nonzero elements outside the
</span><span class="comment">*</span><span class="comment"> band are created only when they are required for generating new
</span><span class="comment">*</span><span class="comment"> rotations; they are stored in the array WORK, in positions where
</span><span class="comment">*</span><span class="comment"> they are later overwritten by the sines of the rotations which
</span><span class="comment">*</span><span class="comment"> annihilate them.
</span><span class="comment">*</span><span class="comment">
</span><span class="comment">*</span><span class="comment"> **************************** Phase 1 *****************************
</span><span class="comment">*</span><span class="comment">
</span><span class="comment">*</span><span class="comment"> The logical structure of this phase is:
</span><span class="comment">*</span><span class="comment">
</span><span class="comment">*</span><span class="comment"> UPDATE = .TRUE.
</span><span class="comment">*</span><span class="comment"> DO I = N, M + 1, -1
</span><span class="comment">*</span><span class="comment"> use S(i) to update A and create a new bulge
</span><span class="comment">*</span><span class="comment"> apply rotations to push all bulges KA positions downward
</span><span class="comment">*</span><span class="comment"> END DO
</span><span class="comment">*</span><span class="comment"> UPDATE = .FALSE.
</span><span class="comment">*</span><span class="comment"> DO I = M + KA + 1, N - 1
</span><span class="comment">*</span><span class="comment"> apply rotations to push all bulges KA positions downward
</span><span class="comment">*</span><span class="comment"> END DO
</span><span class="comment">*</span><span class="comment">
</span><span class="comment">*</span><span class="comment"> To avoid duplicating code, the two loops are merged.
</span><span class="comment">*</span><span class="comment">
</span> UPDATE = .TRUE.
I = N + 1
10 CONTINUE
IF( UPDATE ) THEN
I = I - 1
KBT = MIN( KB, I-1 )
I0 = I - 1
I1 = MIN( N, I+KA )
I2 = I - KBT + KA1
IF( I.LT.M+1 ) THEN
UPDATE = .FALSE.
I = I + 1
I0 = M
IF( KA.EQ.0 )
$ GO TO 480
GO TO 10
END IF
ELSE
I = I + KA
IF( I.GT.N-1 )
$ GO TO 480
END IF
<span class="comment">*</span><span class="comment">
</span> IF( UPPER ) THEN
<span class="comment">*</span><span class="comment">
</span><span class="comment">*</span><span class="comment"> Transform A, working with the upper triangle
</span><span class="comment">*</span><span class="comment">
</span> IF( UPDATE ) THEN
<span class="comment">*</span><span class="comment">
</span><span class="comment">*</span><span class="comment"> Form inv(S(i))**H * A * inv(S(i))
</span><span class="comment">*</span><span class="comment">
</span> BII = DBLE( BB( KB1, I ) )
AB( KA1, I ) = ( DBLE( AB( KA1, I ) ) / BII ) / BII
DO 20 J = I + 1, I1
AB( I-J+KA1, J ) = AB( I-J+KA1, J ) / BII
20 CONTINUE
DO 30 J = MAX( 1, I-KA ), I - 1
AB( J-I+KA1, I ) = AB( J-I+KA1, I ) / BII
30 CONTINUE
DO 60 K = I - KBT, I - 1
DO 40 J = I - KBT, K
AB( J-K+KA1, K ) = AB( J-K+KA1, K ) -
$ BB( J-I+KB1, I )*
$ DCONJG( AB( K-I+KA1, I ) ) -
$ DCONJG( BB( K-I+KB1, I ) )*
$ AB( J-I+KA1, I ) +
$ DBLE( AB( KA1, I ) )*
$ BB( J-I+KB1, I )*
$ DCONJG( BB( K-I+KB1, I ) )
40 CONTINUE
DO 50 J = MAX( 1, I-KA ), I - KBT - 1
AB( J-K+KA1, K ) = AB( J-K+KA1, K ) -
$ DCONJG( BB( K-I+KB1, I ) )*
$ AB( J-I+KA1, I )
50 CONTINUE
60 CONTINUE
DO 80 J = I, I1
DO 70 K = MAX( J-KA, I-KBT ), I - 1
AB( K-J+KA1, J ) = AB( K-J+KA1, J ) -
$ BB( K-I+KB1, I )*AB( I-J+KA1, J )
70 CONTINUE
80 CONTINUE
<span class="comment">*</span><span class="comment">
</span> IF( WANTX ) THEN
<span class="comment">*</span><span class="comment">
</span><span class="comment">*</span><span class="comment"> post-multiply X by inv(S(i))
</span><span class="comment">*</span><span class="comment">
</span> CALL ZDSCAL( N-M, ONE / BII, X( M+1, I ), 1 )
IF( KBT.GT.0 )
$ CALL ZGERC( N-M, KBT, -CONE, X( M+1, I ), 1,
$ BB( KB1-KBT, I ), 1, X( M+1, I-KBT ),
$ LDX )
END IF
<span class="comment">*</span><span class="comment">
</span><span class="comment">*</span><span class="comment"> store a(i,i1) in RA1 for use in next loop over K
</span><span class="comment">*</span><span class="comment">
</span> RA1 = AB( I-I1+KA1, I1 )
END IF
<span class="comment">*</span><span class="comment">
</span><span class="comment">*</span><span class="comment"> Generate and apply vectors of rotations to chase all the
</span><span class="comment">*</span><span class="comment"> existing bulges KA positions down toward the bottom of the
</span><span class="comment">*</span><span class="comment"> band
</span><span class="comment">*</span><span class="comment">
</span> DO 130 K = 1, KB - 1
IF( UPDATE ) THEN
<span class="comment">*</span><span class="comment">
</span><span class="comment">*</span><span class="comment"> Determine the rotations which would annihilate the bulge
</span><span class="comment">*</span><span class="comment"> which has in theory just been created
</span><span class="comment">*</span><span class="comment">
</span> IF( I-K+KA.LT.N .AND. I-K.GT.1 ) THEN
<span class="comment">*</span><span class="comment">
</span><span class="comment">*</span><span class="comment"> generate rotation to annihilate a(i,i-k+ka+1)
</span><span class="comment">*</span><span class="comment">
</span> CALL <a name="ZLARTG.317"></a><a href="zlartg.f.html#ZLARTG.1">ZLARTG</a>( AB( K+1, I-K+KA ), RA1,
$ RWORK( I-K+KA-M ), WORK( I-K+KA-M ), RA )
<span class="comment">*</span><span class="comment">
</span><span class="comment">*</span><span class="comment"> create nonzero element a(i-k,i-k+ka+1) outside the
</span><span class="comment">*</span><span class="comment"> band and store it in WORK(i-k)
</span><span class="comment">*</span><span class="comment">
</span> T = -BB( KB1-K, I )*RA1
WORK( I-K ) = RWORK( I-K+KA-M )*T -
$ DCONJG( WORK( I-K+KA-M ) )*
$ AB( 1, I-K+KA )
AB( 1, I-K+KA ) = WORK( I-K+KA-M )*T +
$ RWORK( I-K+KA-M )*AB( 1, I-K+KA )
RA1 = RA
END IF
END IF
J2 = I - K - 1 + MAX( 1, K-I0+2 )*KA1
NR = ( N-J2+KA ) / KA1
J1 = J2 + ( NR-1 )*KA1
IF( UPDATE ) THEN
J2T = MAX( J2, I+2*KA-K+1 )
ELSE
J2T = J2
END IF
NRT = ( N-J2T+KA ) / KA1
DO 90 J = J2T, J1, KA1
<span class="comment">*</span><span class="comment">
</span><span class="comment">*</span><span class="comment"> create nonzero element a(j-ka,j+1) outside the band
</span><span class="comment">*</span><span class="comment"> and store it in WORK(j-m)
</span><span class="comment">*</span><span class="comment">
</span> WORK( J-M ) = WORK( J-M )*AB( 1, J+1 )
AB( 1, J+1 ) = RWORK( J-M )*AB( 1, J+1 )
90 CONTINUE
<span class="comment">*</span><span class="comment">
</span><span class="comment">*</span><span class="comment"> generate rotations in 1st set to annihilate elements which
</span><span class="comment">*</span><span class="comment"> have been created outside the band
</span><span class="comment">*</span><span class="comment">
</span> IF( NRT.GT.0 )
$ CALL <a name="ZLARGV.354"></a><a href="zlargv.f.html#ZLARGV.1">ZLARGV</a>( NRT, AB( 1, J2T ), INCA, WORK( J2T-M ), KA1,
$ RWORK( J2T-M ), KA1 )
IF( NR.GT.0 ) THEN
<span class="comment">*</span><span class="comment">
</span><span class="comment">*</span><span class="comment"> apply rotations in 1st set from the right
</span><span class="comment">*</span><span class="comment">
</span> DO 100 L = 1, KA - 1
CALL <a name="ZLARTV.361"></a><a href="zlartv.f.html#ZLARTV.1">ZLARTV</a>( NR, AB( KA1-L, J2 ), INCA,
$ AB( KA-L, J2+1 ), INCA, RWORK( J2-M ),
$ WORK( J2-M ), KA1 )
100 CONTINUE
<span class="comment">*</span><span class="comment">
</span><span class="comment">*</span><span class="comment"> apply rotations in 1st set from both sides to diagonal
</span><span class="comment">*</span><span class="comment"> blocks
</span><span class="comment">*</span><span class="comment">
</span> CALL <a name="ZLAR2V.369"></a><a href="zlar2v.f.html#ZLAR2V.1">ZLAR2V</a>( NR, AB( KA1, J2 ), AB( KA1, J2+1 ),
$ AB( KA, J2+1 ), INCA, RWORK( J2-M ),
$ WORK( J2-M ), KA1 )
<span class="comment">*</span><span class="comment">
</span> CALL <a name="ZLACGV.373"></a><a href="zlacgv.f.html#ZLACGV.1">ZLACGV</a>( NR, WORK( J2-M ), KA1 )
END IF
<span class="comment">*</span><span class="comment">
</span><span class="comment">*</span><span class="comment"> start applying rotations in 1st set from the left
</span><span class="comment">*</span><span class="comment">
</span> DO 110 L = KA - 1, KB - K + 1, -1
NRT = ( N-J2+L ) / KA1
IF( NRT.GT.0 )
$ CALL <a name="ZLARTV.381"></a><a href="zlartv.f.html#ZLARTV.1">ZLARTV</a>( NRT, AB( L, J2+KA1-L ), INCA,
$ AB( L+1, J2+KA1-L ), INCA, RWORK( J2-M ),
$ WORK( J2-M ), KA1 )
110 CONTINUE
<span class="comment">*</span><span class="comment">
</span> IF( WANTX ) THEN
<span class="comment">*</span><span class="comment">
</span><span class="comment">*</span><span class="comment"> post-multiply X by product of rotations in 1st set
</span><span class="comment">*</span><span class="comment">
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?