📄 matrix.f90
字号:
IF( ITMP1.GE.NVAL( JI ) ) THEN AB( JI, 2 ) = TMP1 NAB( JI, 2 ) = ITMP1 END IF END IF 100 CONTINUE KL = KLNEW END IF 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 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 DO 120 JI = KF, KL C( JI ) = HALF*( AB( JI, 1 )+AB( JI, 2 ) ) 120 CONTINUE IF( KF.GT.KL )& GO TO 140 130 CONTINUE 140 CONTINUE INFO = MAX( KL+1-KF, 0 ) MOUT = KL RETURN END!======================================================================= REAL FUNCTION SLAMCH( CMACH ) CHARACTER CMACH REAL ONE, ZERO PARAMETER ( ONE = 1.0E+0, ZERO = 0.0E+0 ) LOGICAL FIRST, LRND INTEGER BETA, IMAX, IMIN, IT REAL BASE, EMAX, EMIN, EPS, PREC, RMACH, RMAX, RMIN,& RND, SFMIN, SMALL, T LOGICAL LSAME EXTERNAL LSAME EXTERNAL SLAMC2 SAVE FIRST, EPS, SFMIN, BASE, T, RND, EMIN, RMIN,& EMAX, RMAX, PREC DATA FIRST / .TRUE. / IF( FIRST ) THEN FIRST = .FALSE. CALL SLAMC2( BETA, IT, LRND, EPS, IMIN, RMIN, IMAX, RMAX ) BASE = BETA T = IT IF( LRND ) THEN RND = ONE EPS = ( BASE**( 1-IT ) ) / 2 ELSE RND = ZERO EPS = BASE**( 1-IT ) END IF PREC = EPS*BASE EMIN = IMIN EMAX = IMAX SFMIN = RMIN SMALL = ONE / RMAX IF( SMALL.GE.SFMIN ) THEN SFMIN = SMALL*( ONE+EPS ) END IF END IF IF( LSAME( CMACH, 'E' ) ) THEN RMACH = EPS ELSE IF( LSAME( CMACH, 'S' ) ) THEN RMACH = SFMIN ELSE IF( LSAME( CMACH, 'B' ) ) THEN RMACH = BASE ELSE IF( LSAME( CMACH, 'P' ) ) THEN RMACH = PREC ELSE IF( LSAME( CMACH, 'N' ) ) THEN RMACH = T ELSE IF( LSAME( CMACH, 'R' ) ) THEN RMACH = RND ELSE IF( LSAME( CMACH, 'M' ) ) THEN RMACH = EMIN ELSE IF( LSAME( CMACH, 'U' ) ) THEN RMACH = RMIN ELSE IF( LSAME( CMACH, 'L' ) ) THEN RMACH = EMAX ELSE IF( LSAME( CMACH, 'O' ) ) THEN RMACH = RMAX END IF SLAMCH = RMACH RETURN END SUBROUTINE SLAMC1( BETA, T, RND, IEEE1 ) LOGICAL IEEE1, RND INTEGER BETA, T LOGICAL FIRST, LIEEE1, LRND INTEGER LBETA, LT REAL A, B, C, F, ONE, QTR, SAVEC, T1, T2 REAL SLAMC3 EXTERNAL SLAMC3 SAVE FIRST, LIEEE1, LBETA, LRND, LT DATA FIRST / .TRUE. / IF( FIRST ) THEN FIRST = .FALSE. ONE = 1 A = 1 C = 1 10 CONTINUE IF( C.EQ.ONE ) THEN A = 2*A C = SLAMC3( A, ONE ) C = SLAMC3( C, -A ) GO TO 10 END IF B = 1 C = SLAMC3( A, B ) 20 CONTINUE IF( C.EQ.A ) THEN B = 2*B C = SLAMC3( A, B ) GO TO 20 END IF QTR = ONE / 4 SAVEC = C C = SLAMC3( C, -A ) LBETA = C + QTR B = LBETA F = SLAMC3( B / 2, -B / 100 ) C = SLAMC3( F, A ) IF( C.EQ.A ) THEN LRND = .TRUE. ELSE LRND = .FALSE. END IF F = SLAMC3( B / 2, B / 100 ) C = SLAMC3( F, A ) IF( ( LRND ) .AND. ( C.EQ.A ) )& LRND = .FALSE. T1 = SLAMC3( B / 2, A ) T2 = SLAMC3( B / 2, SAVEC ) LIEEE1 = ( T1.EQ.A ) .AND. ( T2.GT.SAVEC ) .AND. LRND LT = 0 A = 1 C = 1 30 CONTINUE IF( C.EQ.ONE ) THEN LT = LT + 1 A = A*LBETA C = SLAMC3( A, ONE ) C = SLAMC3( C, -A ) GO TO 30 END IF END IF BETA = LBETA T = LT RND = LRND IEEE1 = LIEEE1 RETURN END SUBROUTINE SLAMC2( BETA, T, RND, EPS, EMIN, RMIN, EMAX, RMAX ) LOGICAL RND INTEGER BETA, EMAX, EMIN, T REAL EPS, RMAX, RMIN LOGICAL FIRST, IEEE, IWARN, LIEEE1, LRND INTEGER GNMIN, GPMIN, I, LBETA, LEMAX, LEMIN, LT,& NGNMIN, NGPMIN REAL A, B, C, HALF, LEPS, LRMAX, LRMIN, ONE, RBASE,& SIXTH, SMALL, THIRD, TWO, ZERO REAL SLAMC3 EXTERNAL SLAMC3 EXTERNAL SLAMC1, SLAMC4, SLAMC5 INTRINSIC ABS, MAX, MIN SAVE FIRST, IWARN, LBETA, LEMAX, LEMIN, LEPS, LRMAX,& LRMIN, LT DATA FIRST / .TRUE. / , IWARN / .FALSE. / IF( FIRST ) THEN FIRST = .FALSE. ZERO = 0 ONE = 1 TWO = 2 CALL SLAMC1( LBETA, LT, LRND, LIEEE1 ) B = LBETA A = B**( -LT ) LEPS = A B = TWO / 3 HALF = ONE / 2 SIXTH = SLAMC3( B, -HALF ) THIRD = SLAMC3( SIXTH, SIXTH ) B = SLAMC3( THIRD, -HALF ) B = SLAMC3( B, SIXTH ) B = ABS( B ) IF( B.LT.LEPS )& B = LEPS LEPS = 1 10 CONTINUE IF( ( LEPS.GT.B ) .AND. ( B.GT.ZERO ) ) THEN LEPS = B C = SLAMC3( HALF*LEPS, ( TWO**5 )*( LEPS**2 ) ) C = SLAMC3( HALF, -C ) B = SLAMC3( HALF, C ) C = SLAMC3( HALF, -B ) B = SLAMC3( HALF, C ) GO TO 10 END IF IF( A.LT.LEPS )& LEPS = A RBASE = ONE / LBETA SMALL = ONE DO 20 I = 1, 3 SMALL = SLAMC3( SMALL*RBASE, ZERO ) 20 CONTINUE A = SLAMC3( ONE, SMALL ) CALL SLAMC4( NGPMIN, ONE, LBETA ) CALL SLAMC4( NGNMIN, -ONE, LBETA ) CALL SLAMC4( GPMIN, A, LBETA ) CALL SLAMC4( GNMIN, -A, LBETA ) IEEE = .FALSE. IF( ( NGPMIN.EQ.NGNMIN ) .AND. ( GPMIN.EQ.GNMIN ) ) THEN IF( NGPMIN.EQ.GPMIN ) THEN LEMIN = NGPMIN ELSE IF( ( GPMIN-NGPMIN ).EQ.3 ) THEN LEMIN = NGPMIN - 1 + LT IEEE = .TRUE. ELSE LEMIN = MIN( NGPMIN, GPMIN ) IWARN = .TRUE. END IF ELSE IF( ( NGPMIN.EQ.GPMIN ) .AND. ( NGNMIN.EQ.GNMIN ) ) THEN IF( ABS( NGPMIN-NGNMIN ).EQ.1 ) THEN LEMIN = MAX( NGPMIN, NGNMIN ) ELSE LEMIN = MIN( NGPMIN, NGNMIN ) IWARN = .TRUE. END IF ELSE IF( ( ABS( NGPMIN-NGNMIN ).EQ.1 ) .AND.& ( GPMIN.EQ.GNMIN ) ) THEN IF( ( GPMIN-MIN( NGPMIN, NGNMIN ) ).EQ.3 ) THEN LEMIN = MAX( NGPMIN, NGNMIN ) - 1 + LT ELSE LEMIN = MIN( NGPMIN, NGNMIN ) IWARN = .TRUE. END IF ELSE LEMIN = MIN( NGPMIN, NGNMIN, GPMIN, GNMIN ) IWARN = .TRUE. END IF IF( IWARN ) THEN FIRST = .TRUE. WRITE( 6, FMT = 9999 )LEMIN END IF IEEE = IEEE .OR. LIEEE1 LRMIN = 1 DO 30 I = 1, 1 - LEMIN LRMIN = SLAMC3( LRMIN*RBASE, ZERO ) 30 CONTINUE CALL SLAMC5( LBETA, LT, LEMIN, IEEE, LEMAX, LRMAX ) END IF BETA = LBETA T = LT RND = LRND EPS = LEPS EMIN = LEMIN RMIN = LRMIN EMAX = LEMAX RMAX = LRMAX RETURN 9999 FORMAT( / / ' WARNING. The value EMIN may be incorrect:-',& ' EMIN = ', I8, /& ' If, after inspection, the value EMIN looks',& ' acceptable please comment out ',& / ' the IF block as marked within the code of routine',& ' SLAMC2,', / ' otherwise supply EMIN explicitly.', / ) END REAL FUNCTION SLAMC3( A, B ) REAL A, B SLAMC3 = A + B RETURN END SUBROUTINE SLAMC4( EMIN, START, BASE ) INTEGER BASE, EMIN REAL START INTEGER I REAL A, B1, B2, C1, C2, D1, D2, ONE, RBASE, ZERO REAL SLAMC3 EXTERNAL SLAMC3 A = START ONE = 1 RBASE = ONE / BASE ZERO = 0 EMIN = 1 B1 = SLAMC3( A*RBASE, ZERO ) C1 = A C2 = A D1 = A D2 = A 10 CONTINUE IF( ( C1.EQ.A ) .AND. ( C2.EQ.A ) .AND. ( D1.EQ.A ) .AND.& ( D2.EQ.A ) ) THEN EMIN = EMIN - 1 A = B1 B1 = SLAMC3( A / BASE, ZERO ) C1 = SLAMC3( B1*BASE, ZERO ) D1 = ZERO DO 20 I = 1, BASE D1 = D1 + B1 20 CONTINUE B2 = SLAMC3( A*RBASE, ZERO ) C2 = SLAMC3( B2 / RBASE, ZERO ) D2 = ZERO DO 30 I = 1, BASE D2 = D2 + B2 30 CONTINUE GO TO 10 END IF RETURN END SUBROUTINE SLAMC5( BETA, P, EMIN, IEEE, EMAX, RMAX ) LOGICAL IEEE INTEGER BETA, EMAX, EMIN, P REAL RMAX REAL ZERO, ONE PARAMETER ( ZERO = 0.0E0, ONE = 1.0E0 ) INTEGER EXBITS, EXPSUM, I, LEXP, NBITS, TRY, UEXP REAL OLDY, RECBAS, Y, Z REAL SLAMC3 EXTERNAL SLAMC3 INTRINSIC MOD LEXP = 1 EXBITS = 1 10 CONTINUE TRY = LEXP*2 IF( TRY.LE.( -EMIN ) ) THEN LEXP = TRY EXBITS = EXBITS + 1 GO TO 10 END IF IF( LEXP.EQ.-EMIN ) THEN UEXP = LEXP ELSE UEXP = TRY EXBITS = EXBITS + 1 END IF IF( ( UEXP+EMIN ).GT.( -LEXP-EMIN ) ) THEN EXPSUM = 2*LEXP ELSE EXPSUM = 2*UEXP END IF EMAX = EXPSUM + EMIN - 1 NBITS = 1 + EXBITS + P IF( ( MOD( NBITS, 2 ).EQ.1 ) .AND. ( BETA.EQ.2 ) ) THEN EMAX = EMAX - 1 END IF IF( IEEE ) THEN EMAX = EMAX - 1 END IF RECBAS = ONE / BETA Z = BETA - ONE Y = ZERO
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -