📄 slaebz.f
字号:
KL = MINP** If IJOB=2, initialize C.* If IJOB=3, use the user-supplied starting point.* IF( IJOB.EQ.2 ) THEN DO 40 JI = 1, MINP C( JI ) = HALF*( AB( JI, 1 )+AB( JI, 2 ) ) 40 CONTINUE** Increment opcount for initializing C.* OPS = OPS + MINP*2 END IF** Iteration loop* DO 130 JIT = 1, NITMAX** Loop over intervals* IF( KL-KF+1.GE.NBMIN .AND. NBMIN.GT.0 ) THEN** Begin of Parallel Version of the loop* DO 60 JI = KF, KL** Compute N(c), the number of eigenvalues less than c* WORK( JI ) = D( 1 ) - C( JI ) IWORK( JI ) = 0 IF( WORK( JI ).LE.PIVMIN ) THEN IWORK( JI ) = 1 WORK( JI ) = MIN( WORK( JI ), -PIVMIN ) END IF* DO 50 J = 2, N WORK( JI ) = D( J ) - E2( J-1 ) / WORK( JI ) - C( JI ) IF( WORK( JI ).LE.PIVMIN ) THEN IWORK( JI ) = IWORK( JI ) + 1 WORK( JI ) = MIN( WORK( JI ), -PIVMIN ) END IF 50 CONTINUE 60 CONTINUE** Increment iteration counter.* ITCNT = ITCNT + KL - KF + 1** Increment opcount for evaluating Sturm sequences on* each interval.* OPS = OPS + ( KL-KF+1 )*( N-1 )*3* IF( IJOB.LE.2 ) THEN** IJOB=2: Choose all intervals containing eigenvalues.* KLNEW = KL DO 70 JI = KF, KL** Insure that N(w) is monotone* IWORK( JI ) = MIN( NAB( JI, 2 ), $ MAX( NAB( JI, 1 ), IWORK( JI ) ) )** Update the Queue -- add intervals if both halves* contain eigenvalues.* IF( IWORK( JI ).EQ.NAB( JI, 2 ) ) THEN** No eigenvalue in the upper interval:* just use the lower interval.* AB( JI, 2 ) = C( JI )* ELSE IF( IWORK( JI ).EQ.NAB( JI, 1 ) ) THEN** No eigenvalue in the lower interval:* just use the upper interval.* AB( JI, 1 ) = C( JI ) ELSE KLNEW = KLNEW + 1 IF( KLNEW.LE.MMAX ) THEN** Eigenvalue in both intervals -- add upper to* queue.* AB( KLNEW, 2 ) = AB( JI, 2 ) NAB( KLNEW, 2 ) = NAB( JI, 2 ) AB( KLNEW, 1 ) = C( JI ) NAB( KLNEW, 1 ) = IWORK( JI ) AB( JI, 2 ) = C( JI ) NAB( JI, 2 ) = IWORK( JI ) ELSE INFO = MMAX + 1 END IF END IF 70 CONTINUE IF( INFO.NE.0 ) $ RETURN KL = KLNEW ELSE** IJOB=3: Binary search. Keep only the interval containing* w s.t. N(w) = NVAL* DO 80 JI = KF, KL IF( IWORK( JI ).LE.NVAL( JI ) ) THEN AB( JI, 1 ) = C( JI ) NAB( JI, 1 ) = IWORK( JI ) END IF IF( IWORK( JI ).GE.NVAL( JI ) ) THEN AB( JI, 2 ) = C( JI ) NAB( JI, 2 ) = IWORK( JI ) END IF 80 CONTINUE END IF* ELSE** End of Parallel Version of the loop** Begin of Serial Version of the loop* KLNEW = KL DO 100 JI = KF, KL** Compute N(w), the number of eigenvalues less than w* TMP1 = C( JI ) TMP2 = D( 1 ) - TMP1 ITMP1 = 0 IF( TMP2.LE.PIVMIN ) THEN ITMP1 = 1 TMP2 = MIN( TMP2, -PIVMIN ) END IF** A series of compiler directives to defeat vectorization* for the next loop**$PL$ CMCHAR=' 'CDIR$ NEXTSCALARC$DIR SCALARCDIR$ NEXT SCALARCVD$L NOVECTORCDEC$ NOVECTORCVD$ NOVECTOR*VDIR NOVECTOR*VOCL LOOP,SCALARCIBM PREFER SCALAR*$PL$ CMCHAR='*'* DO 90 J = 2, N TMP2 = D( J ) - E2( J-1 ) / TMP2 - TMP1 IF( TMP2.LE.PIVMIN ) THEN ITMP1 = ITMP1 + 1 TMP2 = MIN( TMP2, -PIVMIN ) END IF 90 CONTINUE* IF( IJOB.LE.2 ) THEN** IJOB=2: Choose all intervals containing eigenvalues.** Insure that N(w) is monotone* ITMP1 = MIN( NAB( JI, 2 ), $ MAX( NAB( JI, 1 ), ITMP1 ) )** Update the Queue -- add intervals if both halves* contain eigenvalues.* IF( ITMP1.EQ.NAB( JI, 2 ) ) THEN** No eigenvalue in the upper interval:* just use the lower interval.* AB( JI, 2 ) = TMP1* ELSE IF( ITMP1.EQ.NAB( JI, 1 ) ) THEN** No eigenvalue in the lower interval:* just use the upper interval.* AB( JI, 1 ) = TMP1 ELSE IF( KLNEW.LT.MMAX ) THEN** Eigenvalue in both intervals -- add upper to queue.* KLNEW = KLNEW + 1 AB( KLNEW, 2 ) = AB( JI, 2 ) NAB( KLNEW, 2 ) = NAB( JI, 2 ) AB( KLNEW, 1 ) = TMP1 NAB( KLNEW, 1 ) = ITMP1 AB( JI, 2 ) = TMP1 NAB( JI, 2 ) = ITMP1 ELSE INFO = MMAX + 1 RETURN END IF ELSE** IJOB=3: Binary search. Keep only the interval* containing w s.t. N(w) = NVAL* IF( ITMP1.LE.NVAL( JI ) ) THEN AB( JI, 1 ) = TMP1 NAB( JI, 1 ) = ITMP1 END IF IF( ITMP1.GE.NVAL( JI ) ) THEN AB( JI, 2 ) = TMP1 NAB( JI, 2 ) = ITMP1 END IF END IF 100 CONTINUE** Increment iteration counter.* ITCNT = ITCNT + KL - KF + 1** Increment opcount for evaluating Sturm sequences on* each interval.* OPS = OPS + ( KL-KF+1 )*( N-1 )*3 KL = KLNEW** End of Serial Version of the loop* END IF** Check for convergence* KFNEW = KF DO 110 JI = KF, KL TMP1 = ABS( AB( JI, 2 )-AB( JI, 1 ) ) TMP2 = MAX( ABS( AB( JI, 2 ) ), ABS( AB( JI, 1 ) ) ) IF( TMP1.LT.MAX( ABSTOL, PIVMIN, RELTOL*TMP2 ) .OR. $ NAB( JI, 1 ).GE.NAB( JI, 2 ) ) THEN** Converged -- Swap with position KFNEW,* then increment KFNEW* IF( JI.GT.KFNEW ) THEN TMP1 = AB( JI, 1 ) TMP2 = AB( JI, 2 ) ITMP1 = NAB( JI, 1 ) ITMP2 = NAB( JI, 2 ) AB( JI, 1 ) = AB( KFNEW, 1 ) AB( JI, 2 ) = AB( KFNEW, 2 ) NAB( JI, 1 ) = NAB( KFNEW, 1 ) NAB( JI, 2 ) = NAB( KFNEW, 2 ) AB( KFNEW, 1 ) = TMP1 AB( KFNEW, 2 ) = TMP2 NAB( KFNEW, 1 ) = ITMP1 NAB( KFNEW, 2 ) = ITMP2 IF( IJOB.EQ.3 ) THEN ITMP1 = NVAL( JI ) NVAL( JI ) = NVAL( KFNEW ) NVAL( KFNEW ) = ITMP1 END IF END IF KFNEW = KFNEW + 1 END IF 110 CONTINUE KF = KFNEW** Choose Midpoints* DO 120 JI = KF, KL C( JI ) = HALF*( AB( JI, 1 )+AB( JI, 2 ) ) 120 CONTINUE** Increment opcount for convergence check and choosing midpoints.* OPS = OPS + ( KL-KF+1 )*4** If no more intervals to refine, quit.* IF( KF.GT.KL ) $ GO TO 140 130 CONTINUE** Converged* 140 CONTINUE INFO = MAX( KL+1-KF, 0 ) MOUT = KL* RETURN** End of SLAEBZ* END
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -