zlahqr.f.html
来自「famous linear algebra library (LAPACK) p」· HTML 代码 · 共 495 行 · 第 1/3 页
HTML
495 行
</span><span class="comment">*</span><span class="comment"> .. External Subroutines ..
</span> EXTERNAL <a name="DLABAD.148"></a><a href="dlabad.f.html#DLABAD.1">DLABAD</a>, ZCOPY, <a name="ZLARFG.148"></a><a href="zlarfg.f.html#ZLARFG.1">ZLARFG</a>, ZSCAL
<span class="comment">*</span><span class="comment"> ..
</span><span class="comment">*</span><span class="comment"> .. Statement Functions ..
</span> DOUBLE PRECISION CABS1
<span class="comment">*</span><span class="comment"> ..
</span><span class="comment">*</span><span class="comment"> .. Intrinsic Functions ..
</span> INTRINSIC ABS, DBLE, DCONJG, DIMAG, MAX, MIN, SQRT
<span class="comment">*</span><span class="comment"> ..
</span><span class="comment">*</span><span class="comment"> .. Statement Function definitions ..
</span> CABS1( CDUM ) = ABS( DBLE( CDUM ) ) + ABS( DIMAG( CDUM ) )
<span class="comment">*</span><span class="comment"> ..
</span><span class="comment">*</span><span class="comment"> .. Executable Statements ..
</span><span class="comment">*</span><span class="comment">
</span> INFO = 0
<span class="comment">*</span><span class="comment">
</span><span class="comment">*</span><span class="comment"> Quick return if possible
</span><span class="comment">*</span><span class="comment">
</span> IF( N.EQ.0 )
$ RETURN
IF( ILO.EQ.IHI ) THEN
W( ILO ) = H( ILO, ILO )
RETURN
END IF
<span class="comment">*</span><span class="comment">
</span><span class="comment">*</span><span class="comment"> ==== clear out the trash ====
</span> DO 10 J = ILO, IHI - 3
H( J+2, J ) = ZERO
H( J+3, J ) = ZERO
10 CONTINUE
IF( ILO.LE.IHI-2 )
$ H( IHI, IHI-2 ) = ZERO
<span class="comment">*</span><span class="comment"> ==== ensure that subdiagonal entries are real ====
</span> DO 20 I = ILO + 1, IHI
IF( DIMAG( H( I, I-1 ) ).NE.RZERO ) THEN
<span class="comment">*</span><span class="comment"> ==== The following redundant normalization
</span><span class="comment">*</span><span class="comment"> . avoids problems with both gradual and
</span><span class="comment">*</span><span class="comment"> . sudden underflow in ABS(H(I,I-1)) ====
</span> SC = H( I, I-1 ) / CABS1( H( I, I-1 ) )
SC = DCONJG( SC ) / ABS( SC )
H( I, I-1 ) = ABS( H( I, I-1 ) )
IF( WANTT ) THEN
JLO = 1
JHI = N
ELSE
JLO = ILO
JHI = IHI
END IF
CALL ZSCAL( JHI-I+1, SC, H( I, I ), LDH )
CALL ZSCAL( MIN( JHI, I+1 )-JLO+1, DCONJG( SC ),
$ H( JLO, I ), 1 )
IF( WANTZ )
$ CALL ZSCAL( IHIZ-ILOZ+1, DCONJG( SC ), Z( ILOZ, I ), 1 )
END IF
20 CONTINUE
<span class="comment">*</span><span class="comment">
</span> NH = IHI - ILO + 1
NZ = IHIZ - ILOZ + 1
<span class="comment">*</span><span class="comment">
</span><span class="comment">*</span><span class="comment"> Set machine-dependent constants for the stopping criterion.
</span><span class="comment">*</span><span class="comment">
</span> SAFMIN = <a name="DLAMCH.208"></a><a href="dlamch.f.html#DLAMCH.1">DLAMCH</a>( <span class="string">'SAFE MINIMUM'</span> )
SAFMAX = RONE / SAFMIN
CALL <a name="DLABAD.210"></a><a href="dlabad.f.html#DLABAD.1">DLABAD</a>( SAFMIN, SAFMAX )
ULP = <a name="DLAMCH.211"></a><a href="dlamch.f.html#DLAMCH.1">DLAMCH</a>( <span class="string">'PRECISION'</span> )
SMLNUM = SAFMIN*( DBLE( NH ) / ULP )
<span class="comment">*</span><span class="comment">
</span><span class="comment">*</span><span class="comment"> I1 and I2 are the indices of the first row and last column of H
</span><span class="comment">*</span><span class="comment"> to which transformations must be applied. If eigenvalues only are
</span><span class="comment">*</span><span class="comment"> being computed, I1 and I2 are set inside the main loop.
</span><span class="comment">*</span><span class="comment">
</span> IF( WANTT ) THEN
I1 = 1
I2 = N
END IF
<span class="comment">*</span><span class="comment">
</span><span class="comment">*</span><span class="comment"> The main loop begins here. I is the loop index and decreases from
</span><span class="comment">*</span><span class="comment"> IHI to ILO in steps of 1. Each iteration of the loop works
</span><span class="comment">*</span><span class="comment"> with the active submatrix in rows and columns L to I.
</span><span class="comment">*</span><span class="comment"> Eigenvalues I+1 to IHI have already converged. Either L = ILO, or
</span><span class="comment">*</span><span class="comment"> H(L,L-1) is negligible so that the matrix splits.
</span><span class="comment">*</span><span class="comment">
</span> I = IHI
30 CONTINUE
IF( I.LT.ILO )
$ GO TO 150
<span class="comment">*</span><span class="comment">
</span><span class="comment">*</span><span class="comment"> Perform QR iterations on rows and columns ILO to I until a
</span><span class="comment">*</span><span class="comment"> submatrix of order 1 splits off at the bottom because a
</span><span class="comment">*</span><span class="comment"> subdiagonal element has become negligible.
</span><span class="comment">*</span><span class="comment">
</span> L = ILO
DO 130 ITS = 0, ITMAX
<span class="comment">*</span><span class="comment">
</span><span class="comment">*</span><span class="comment"> Look for a single small subdiagonal element.
</span><span class="comment">*</span><span class="comment">
</span> DO 40 K = I, L + 1, -1
IF( CABS1( H( K, K-1 ) ).LE.SMLNUM )
$ GO TO 50
TST = CABS1( H( K-1, K-1 ) ) + CABS1( H( K, K ) )
IF( TST.EQ.ZERO ) THEN
IF( K-2.GE.ILO )
$ TST = TST + ABS( DBLE( H( K-1, K-2 ) ) )
IF( K+1.LE.IHI )
$ TST = TST + ABS( DBLE( H( K+1, K ) ) )
END IF
<span class="comment">*</span><span class="comment"> ==== The following is a conservative small subdiagonal
</span><span class="comment">*</span><span class="comment"> . deflation criterion due to Ahues & Tisseur (LAWN 122,
</span><span class="comment">*</span><span class="comment"> . 1997). It has better mathematical foundation and
</span><span class="comment">*</span><span class="comment"> . improves accuracy in some examples. ====
</span> IF( ABS( DBLE( H( K, K-1 ) ) ).LE.ULP*TST ) THEN
AB = MAX( CABS1( H( K, K-1 ) ), CABS1( H( K-1, K ) ) )
BA = MIN( CABS1( H( K, K-1 ) ), CABS1( H( K-1, K ) ) )
AA = MAX( CABS1( H( K, K ) ),
$ CABS1( H( K-1, K-1 )-H( K, K ) ) )
BB = MIN( CABS1( H( K, K ) ),
$ CABS1( H( K-1, K-1 )-H( K, K ) ) )
S = AA + AB
IF( BA*( AB / S ).LE.MAX( SMLNUM,
$ ULP*( BB*( AA / S ) ) ) )GO TO 50
END IF
40 CONTINUE
50 CONTINUE
L = K
IF( L.GT.ILO ) THEN
<span class="comment">*</span><span class="comment">
</span><span class="comment">*</span><span class="comment"> H(L,L-1) is negligible
</span><span class="comment">*</span><span class="comment">
</span> H( L, L-1 ) = ZERO
END IF
<span class="comment">*</span><span class="comment">
</span><span class="comment">*</span><span class="comment"> Exit from loop if a submatrix of order 1 has split off.
</span><span class="comment">*</span><span class="comment">
</span> IF( L.GE.I )
$ GO TO 140
<span class="comment">*</span><span class="comment">
</span><span class="comment">*</span><span class="comment"> Now the active submatrix is in rows and columns L to I. If
</span><span class="comment">*</span><span class="comment"> eigenvalues only are being computed, only the active submatrix
</span><span class="comment">*</span><span class="comment"> need be transformed.
</span><span class="comment">*</span><span class="comment">
</span> IF( .NOT.WANTT ) THEN
I1 = L
I2 = I
END IF
<span class="comment">*</span><span class="comment">
</span> IF( ITS.EQ.10 .OR. ITS.EQ.20 ) THEN
<span class="comment">*</span><span class="comment">
</span><span class="comment">*</span><span class="comment"> Exceptional shift.
</span><span class="comment">*</span><span class="comment">
</span> S = DAT1*ABS( DBLE( H( I, I-1 ) ) )
T = S + H( I, I )
ELSE
<span class="comment">*</span><span class="comment">
</span><span class="comment">*</span><span class="comment"> Wilkinson's shift.
</span><span class="comment">*</span><span class="comment">
</span> T = H( I, I )
U = SQRT( H( I-1, I ) )*SQRT( H( I, I-1 ) )
S = CABS1( U )
IF( S.NE.RZERO ) THEN
X = HALF*( H( I-1, I-1 )-T )
SX = CABS1( X )
S = MAX( S, CABS1( X ) )
Y = S*SQRT( ( X / S )**2+( U / S )**2 )
IF( SX.GT.RZERO ) THEN
IF( DBLE( X / SX )*DBLE( Y )+DIMAG( X / SX )*
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?