📄 slasd4.f
字号:
WORK( J ) = WORK( J ) + ETA 50 CONTINUE* SIGMA = SIGMA + ETA** Evaluate PSI and the derivative DPSI* DPSI = ZERO PSI = ZERO ERRETM = ZERO OPS = OPS + REAL( 7*II ) DO 60 J = 1, II TEMP = Z( J ) / ( WORK( J )*DELTA( J ) ) PSI = PSI + Z( J )*TEMP DPSI = DPSI + TEMP*TEMP ERRETM = ERRETM + PSI 60 CONTINUE ERRETM = ABS( ERRETM )** Evaluate PHI and the derivative DPHI* OPS = OPS + REAL( 14 ) TEMP = Z( N ) / ( WORK( N )*DELTA( N ) ) PHI = Z( N )*TEMP DPHI = TEMP*TEMP ERRETM = EIGHT*( -PHI-PSI ) + ERRETM - PHI + RHOINV + $ ABS( TAU )*( DPSI+DPHI )* W = RHOINV + PHI + PSI** Main loop to update the values of the array DELTA* ITER = NITER + 1* DO 90 NITER = ITER, MAXIT** Test for convergence* OPS = OPS + REAL( 1 ) IF( ABS( W ).LE.EPS*ERRETM ) THEN GO TO 240 END IF** Calculate the new step* OPS = OPS + REAL( 22 ) DTNSQ1 = WORK( N-1 )*DELTA( N-1 ) DTNSQ = WORK( N )*DELTA( N ) C = W - DTNSQ1*DPSI - DTNSQ*DPHI A = ( DTNSQ+DTNSQ1 )*W - DTNSQ1*DTNSQ*( DPSI+DPHI ) B = DTNSQ1*DTNSQ*W IF( A.GE.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** Note, eta should be positive if w is negative, and* eta should be negative otherwise. However,* if for some reason caused by roundoff, eta*w > 0,* we simply use one Newton step instead. This way* will guarantee eta*w < 0.* OPS = OPS + REAL( 2 ) IF( W*ETA.GT.ZERO ) THEN OPS = OPS + REAL( 2 ) ETA = -W / ( DPSI+DPHI ) END IF TEMP = ETA - DTNSQ IF( TEMP.LE.ZERO ) THEN OPS = OPS + REAL( 1 ) ETA = ETA / TWO END IF* OPS = OPS + REAL( 6 + 2*N + 1 ) TAU = TAU + ETA ETA = ETA / ( SIGMA+SQRT( ETA+SIGMA*SIGMA ) ) DO 70 J = 1, N DELTA( J ) = DELTA( J ) - ETA WORK( J ) = WORK( J ) + ETA 70 CONTINUE* SIGMA = SIGMA + ETA** Evaluate PSI and the derivative DPSI* DPSI = ZERO PSI = ZERO ERRETM = ZERO OPS = OPS + REAL( 7*II ) DO 80 J = 1, II TEMP = Z( J ) / ( WORK( J )*DELTA( J ) ) PSI = PSI + Z( J )*TEMP DPSI = DPSI + TEMP*TEMP ERRETM = ERRETM + PSI 80 CONTINUE ERRETM = ABS( ERRETM )** Evaluate PHI and the derivative DPHI* OPS = OPS + REAL( 14 ) TEMP = Z( N ) / ( WORK( N )*DELTA( N ) ) PHI = Z( N )*TEMP DPHI = TEMP*TEMP ERRETM = EIGHT*( -PHI-PSI ) + ERRETM - PHI + RHOINV + $ ABS( TAU )*( DPSI+DPHI )* W = RHOINV + PHI + PSI 90 CONTINUE** Return with INFO = 1, NITER = MAXIT and not converged* INFO = 1 GO TO 240** End for the case I = N* ELSE** The case for I < N* NITER = 1 IP1 = I + 1** Calculate initial guess* OPS = OPS + REAL( 9 + 4*N ) DELSQ = ( D( IP1 )-D( I ) )*( D( IP1 )+D( I ) ) DELSQ2 = DELSQ / TWO TEMP = DELSQ2 / ( D( I )+SQRT( D( I )*D( I )+DELSQ2 ) ) DO 100 J = 1, N WORK( J ) = D( J ) + D( I ) + TEMP DELTA( J ) = ( D( J )-D( I ) ) - TEMP 100 CONTINUE* PSI = ZERO OPS = OPS + REAL( 4*( I-1 ) ) DO 110 J = 1, I - 1 PSI = PSI + Z( J )*Z( J ) / ( WORK( J )*DELTA( J ) ) 110 CONTINUE* PHI = ZERO OPS = OPS + REAL( 4*( N-I-1 ) + 10 ) DO 120 J = N, I + 2, -1 PHI = PHI + Z( J )*Z( J ) / ( WORK( J )*DELTA( J ) ) 120 CONTINUE C = RHOINV + PSI + PHI W = C + Z( I )*Z( I ) / ( WORK( I )*DELTA( I ) ) + $ Z( IP1 )*Z( IP1 ) / ( WORK( IP1 )*DELTA( IP1 ) )* IF( W.GT.ZERO ) THEN** d(i)^2 < the ith sigma^2 < (d(i)^2+d(i+1)^2)/2** We choose d(i) as origin.* OPS = OPS + REAL( 20 ) 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** TAU now is an estimation of SIGMA^2 - D( I )^2. The* following, however, is the corresponding estimation of* SIGMA - D( I ).* ETA = TAU / ( D( I )+SQRT( D( I )*D( I )+TAU ) ) ELSE** (d(i)^2+d(i+1)^2)/2 <= the ith sigma^2 < d(i+1)^2/2** We choose d(i+1) as origin.* OPS = OPS + REAL( 20 ) 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** TAU now is an estimation of SIGMA^2 - D( IP1 )^2. The* following, however, is the corresponding estimation of* SIGMA - D( IP1 ).* ETA = TAU / ( D( IP1 )+SQRT( ABS( D( IP1 )*D( IP1 )+ $ TAU ) ) ) END IF* OPS = OPS + REAL( 1 + 4*N ) 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** Evaluate PSI and the derivative DPSI* DPSI = ZERO PSI = ZERO ERRETM = ZERO OPS = OPS + REAL( 7*IIM1 ) 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 )** Evaluate PHI and the derivative DPHI* DPHI = ZERO PHI = ZERO OPS = OPS + REAL( 7*( N-IIP1+1 ) + 2 ) 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* W = RHOINV + PHI + PSI** W is the value of the secular function with* its ii-th element removed.* 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.* OPS = OPS + REAL( 17 ) 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** Test for convergence* IF( ABS( W ).LE.EPS*ERRETM ) THEN GO TO 240 END IF* IF( W.LE.ZERO ) THEN SG2LB = MAX( SG2LB, TAU ) ELSE SG2UB = MIN( SG2UB, TAU ) END IF** Calculate the new step* NITER = NITER + 1 IF( .NOT.SWTCH3 ) THEN OPS = OPS + REAL( 15 ) 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 OPS = OPS + REAL( 5 ) 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 OPS = OPS + REAL( 1 ) ETA = B / A ELSE IF( A.LE.ZERO ) THEN OPS = OPS + REAL( 8 ) ETA = ( A-SQRT( ABS( A*A-FOUR*B*C ) ) ) / ( TWO*C ) ELSE OPS = OPS + REAL( 8 ) ETA = TWO*B / ( A+SQRT( ABS( A*A-FOUR*B*C ) ) ) END IF ELSE** Interpolation using THREE most relevant poles* OPS = OPS + REAL( 15 ) 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 OPS = OPS + REAL( 2 ) ZZ( 3 ) = DTIIP*DTIIP*DPHI ELSE OPS = OPS + REAL( 4 ) ZZ( 3 ) = DTIIP*DTIIP*( ( DPSI-TEMP1 )+DPHI )
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -