slasd4.f.html
来自「famous linear algebra library (LAPACK) p」· HTML 代码 · 共 915 行 · 第 1/4 页
HTML
915 行
</span> ORGATI = .TRUE.
SG2LB = ZERO
SG2UB = DELSQ2
A = C*DELSQ + Z( I )*Z( I ) + Z( IP1 )*Z( IP1 )
B = Z( I )*Z( I )*DELSQ
IF( A.GT.ZERO ) THEN
TAU = TWO*B / ( A+SQRT( ABS( A*A-FOUR*B*C ) ) )
ELSE
TAU = ( A-SQRT( ABS( A*A-FOUR*B*C ) ) ) / ( TWO*C )
END IF
<span class="comment">*</span><span class="comment">
</span><span class="comment">*</span><span class="comment"> TAU now is an estimation of SIGMA^2 - D( I )^2. The
</span><span class="comment">*</span><span class="comment"> following, however, is the corresponding estimation of
</span><span class="comment">*</span><span class="comment"> SIGMA - D( I ).
</span><span class="comment">*</span><span class="comment">
</span> ETA = TAU / ( D( I )+SQRT( D( I )*D( I )+TAU ) )
ELSE
<span class="comment">*</span><span class="comment">
</span><span class="comment">*</span><span class="comment"> (d(i)^2+d(i+1)^2)/2 <= the ith sigma^2 < d(i+1)^2/2
</span><span class="comment">*</span><span class="comment">
</span><span class="comment">*</span><span class="comment"> We choose d(i+1) as origin.
</span><span class="comment">*</span><span class="comment">
</span> ORGATI = .FALSE.
SG2LB = -DELSQ2
SG2UB = ZERO
A = C*DELSQ - Z( I )*Z( I ) - Z( IP1 )*Z( IP1 )
B = Z( IP1 )*Z( IP1 )*DELSQ
IF( A.LT.ZERO ) THEN
TAU = TWO*B / ( A-SQRT( ABS( A*A+FOUR*B*C ) ) )
ELSE
TAU = -( A+SQRT( ABS( A*A+FOUR*B*C ) ) ) / ( TWO*C )
END IF
<span class="comment">*</span><span class="comment">
</span><span class="comment">*</span><span class="comment"> TAU now is an estimation of SIGMA^2 - D( IP1 )^2. The
</span><span class="comment">*</span><span class="comment"> following, however, is the corresponding estimation of
</span><span class="comment">*</span><span class="comment"> SIGMA - D( IP1 ).
</span><span class="comment">*</span><span class="comment">
</span> ETA = TAU / ( D( IP1 )+SQRT( ABS( D( IP1 )*D( IP1 )+
$ TAU ) ) )
END IF
<span class="comment">*</span><span class="comment">
</span> IF( ORGATI ) THEN
II = I
SIGMA = D( I ) + ETA
DO 130 J = 1, N
WORK( J ) = D( J ) + D( I ) + ETA
DELTA( J ) = ( D( J )-D( I ) ) - ETA
130 CONTINUE
ELSE
II = I + 1
SIGMA = D( IP1 ) + ETA
DO 140 J = 1, N
WORK( J ) = D( J ) + D( IP1 ) + ETA
DELTA( J ) = ( D( J )-D( IP1 ) ) - ETA
140 CONTINUE
END IF
IIM1 = II - 1
IIP1 = II + 1
<span class="comment">*</span><span class="comment">
</span><span class="comment">*</span><span class="comment"> Evaluate PSI and the derivative DPSI
</span><span class="comment">*</span><span class="comment">
</span> DPSI = ZERO
PSI = ZERO
ERRETM = ZERO
DO 150 J = 1, IIM1
TEMP = Z( J ) / ( WORK( J )*DELTA( J ) )
PSI = PSI + Z( J )*TEMP
DPSI = DPSI + TEMP*TEMP
ERRETM = ERRETM + PSI
150 CONTINUE
ERRETM = ABS( ERRETM )
<span class="comment">*</span><span class="comment">
</span><span class="comment">*</span><span class="comment"> Evaluate PHI and the derivative DPHI
</span><span class="comment">*</span><span class="comment">
</span> DPHI = ZERO
PHI = ZERO
DO 160 J = N, IIP1, -1
TEMP = Z( J ) / ( WORK( J )*DELTA( J ) )
PHI = PHI + Z( J )*TEMP
DPHI = DPHI + TEMP*TEMP
ERRETM = ERRETM + PHI
160 CONTINUE
<span class="comment">*</span><span class="comment">
</span> W = RHOINV + PHI + PSI
<span class="comment">*</span><span class="comment">
</span><span class="comment">*</span><span class="comment"> W is the value of the secular function with
</span><span class="comment">*</span><span class="comment"> its ii-th element removed.
</span><span class="comment">*</span><span class="comment">
</span> SWTCH3 = .FALSE.
IF( ORGATI ) THEN
IF( W.LT.ZERO )
$ SWTCH3 = .TRUE.
ELSE
IF( W.GT.ZERO )
$ SWTCH3 = .TRUE.
END IF
IF( II.EQ.1 .OR. II.EQ.N )
$ SWTCH3 = .FALSE.
<span class="comment">*</span><span class="comment">
</span> TEMP = Z( II ) / ( WORK( II )*DELTA( II ) )
DW = DPSI + DPHI + TEMP*TEMP
TEMP = Z( II )*TEMP
W = W + TEMP
ERRETM = EIGHT*( PHI-PSI ) + ERRETM + TWO*RHOINV +
$ THREE*ABS( TEMP ) + ABS( TAU )*DW
<span class="comment">*</span><span class="comment">
</span><span class="comment">*</span><span class="comment"> Test for convergence
</span><span class="comment">*</span><span class="comment">
</span> IF( ABS( W ).LE.EPS*ERRETM ) THEN
GO TO 240
END IF
<span class="comment">*</span><span class="comment">
</span> IF( W.LE.ZERO ) THEN
SG2LB = MAX( SG2LB, TAU )
ELSE
SG2UB = MIN( SG2UB, TAU )
END IF
<span class="comment">*</span><span class="comment">
</span><span class="comment">*</span><span class="comment"> Calculate the new step
</span><span class="comment">*</span><span class="comment">
</span> NITER = NITER + 1
IF( .NOT.SWTCH3 ) THEN
DTIPSQ = WORK( IP1 )*DELTA( IP1 )
DTISQ = WORK( I )*DELTA( I )
IF( ORGATI ) THEN
C = W - DTIPSQ*DW + DELSQ*( Z( I ) / DTISQ )**2
ELSE
C = W - DTISQ*DW - DELSQ*( Z( IP1 ) / DTIPSQ )**2
END IF
A = ( DTIPSQ+DTISQ )*W - DTIPSQ*DTISQ*DW
B = DTIPSQ*DTISQ*W
IF( C.EQ.ZERO ) THEN
IF( A.EQ.ZERO ) THEN
IF( ORGATI ) THEN
A = Z( I )*Z( I ) + DTIPSQ*DTIPSQ*( DPSI+DPHI )
ELSE
A = Z( IP1 )*Z( IP1 ) + DTISQ*DTISQ*( DPSI+DPHI )
END IF
END IF
ETA = B / A
ELSE IF( A.LE.ZERO ) THEN
ETA = ( A-SQRT( ABS( A*A-FOUR*B*C ) ) ) / ( TWO*C )
ELSE
ETA = TWO*B / ( A+SQRT( ABS( A*A-FOUR*B*C ) ) )
END IF
ELSE
<span class="comment">*</span><span class="comment">
</span><span class="comment">*</span><span class="comment"> Interpolation using THREE most relevant poles
</span><span class="comment">*</span><span class="comment">
</span> DTIIM = WORK( IIM1 )*DELTA( IIM1 )
DTIIP = WORK( IIP1 )*DELTA( IIP1 )
TEMP = RHOINV + PSI + PHI
IF( ORGATI ) THEN
TEMP1 = Z( IIM1 ) / DTIIM
TEMP1 = TEMP1*TEMP1
C = ( TEMP - DTIIP*( DPSI+DPHI ) ) -
$ ( D( IIM1 )-D( IIP1 ) )*( D( IIM1 )+D( IIP1 ) )*TEMP1
ZZ( 1 ) = Z( IIM1 )*Z( IIM1 )
IF( DPSI.LT.TEMP1 ) THEN
ZZ( 3 ) = DTIIP*DTIIP*DPHI
ELSE
ZZ( 3 ) = DTIIP*DTIIP*( ( DPSI-TEMP1 )+DPHI )
END IF
ELSE
TEMP1 = Z( IIP1 ) / DTIIP
TEMP1 = TEMP1*TEMP1
C = ( TEMP - DTIIM*( DPSI+DPHI ) ) -
$ ( D( IIP1 )-D( IIM1 ) )*( D( IIM1 )+D( IIP1 ) )*TEMP1
IF( DPHI.LT.TEMP1 ) THEN
ZZ( 1 ) = DTIIM*DTIIM*DPSI
ELSE
ZZ( 1 ) = DTIIM*DTIIM*( DPSI+( DPHI-TEMP1 ) )
END IF
ZZ( 3 ) = Z( IIP1 )*Z( IIP1 )
END IF
ZZ( 2 ) = Z( II )*Z( II )
DD( 1 ) = DTIIM
DD( 2 ) = DELTA( II )*WORK( II )
DD( 3 ) = DTIIP
CALL <a name="SLAED6.619"></a><a href="slaed6.f.html#SLAED6.1">SLAED6</a>( NITER, ORGATI, C, DD, ZZ, W, ETA, INFO )
IF( INFO.NE.0 )
$ GO TO 240
END IF
<span class="comment">*</span><span class="comment">
</span><span class="comment">*</span><span class="comment"> Note, eta should be positive if w is negative, and
</span><span class="comment">*</span><span class="comment"> eta should be negative otherwise. However,
</span><span class="comment">*</span><span class="comment"> if for some reason caused by roundoff, eta*w > 0,
</span><span class="comment">*</span><span class="comment"> we simply use one Newton step instead. This way
</span><span class="comment">*</span><span class="comment"> will guarantee eta*w < 0.
</span><span class="comment">*</span><span class="comment">
</span> IF( W*ETA.GE.ZERO )
$ ETA = -W / DW
IF( ORGATI ) THEN
TEMP1 = WORK( I )*DELTA( I )
TEMP = ETA - TEMP1
ELSE
TEMP1 = WORK( IP1 )*DELTA( IP1 )
TEMP = ETA - TEMP1
END IF
IF( TEMP.GT.SG2UB .OR. TEMP.LT.SG2LB ) THEN
IF( W.LT.ZERO ) THEN
ETA = ( SG2UB-TAU ) / TWO
ELSE
ETA = ( SG2LB-TAU ) / TWO
END IF
END IF
<span class="comment">*</span><span class="comment">
</span> TAU = TAU + ETA
ETA = ETA / ( SIGMA+SQRT( SIGMA*SIGMA+ETA ) )
<span class="comment">*</span><span class="comment">
</span> PREW = W
<span class="comment">*</span><span class="comment">
</span> SIGMA = SIGMA + ETA
DO 170 J = 1, N
WORK( J ) = WORK( J ) + ETA
DELTA( J ) = DELTA( J ) - ETA
170 CONTINUE
<span class="comment">*</span><span class="comment">
</span><span class="comment">*</span><span class="comment"> Evaluate PSI and the derivative DPSI
</span><span class="comment">*</span><span class="comment">
</span> DPSI = ZERO
PSI = ZERO
ERRETM = ZERO
DO 180 J = 1, IIM1
TEMP = Z( J ) / ( WORK( J )*DELTA( J ) )
PSI = PSI + Z( J )*TEMP
DPSI = DPSI + TEMP*TEMP
ERRETM = ERRETM + PSI
180 CONTINUE
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?