⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 pdsteqr.f

📁 大型并行量子化学软件;支持密度泛函(DFT)。可以进行各种量子化学计算。支持CHARMM并行计算。非常具有应用价值。
💻 F
📖 第 1 页 / 共 5 页
字号:
      LOGICAL            IEEE1, RND      INTEGER            BETA, T*     ..**  Purpose*  =======**  DLAMC1 determines the machine parameters given by BETA, T, RND, and*  IEEE1.**  Arguments*  =========**  BETA    (output) INTEGER*          The base of the machine.**  T       (output) INTEGER*          The number of ( BETA ) digits in the mantissa.**  RND     (output) LOGICAL*          Specifies whether proper rounding  ( RND = .TRUE. )  or*          chopping  ( RND = .FALSE. )  occurs in addition. This may not*          be a reliable guide to the way in which the machine performs*          its arithmetic.**  IEEE1   (output) LOGICAL*          Specifies whether rounding appears to be done in the IEEE*          'round to nearest' style.**  Further Details*  ===============**  The routine is based on the routine  ENVRON  by Malcolm and*  incorporates suggestions by Gentleman and Marovich. See**     Malcolm M. A. (1972) Algorithms to reveal properties of*        floating-point arithmetic. Comms. of the ACM, 15, 949-951.**     Gentleman W. M. and Marovich S. B. (1974) More on algorithms*        that reveal properties of floating point arithmetic units.*        Comms. of the ACM, 17, 276-277.** =====================================================================**     .. Local Scalars ..      LOGICAL            FIRST, LIEEE1, LRND      INTEGER            LBETA, LT      DOUBLE PRECISION   A, B, C, F, ONE, QTR, SAVEC, T1, T2*     ..*     .. External Functions ..      DOUBLE PRECISION   PDLAMC3      EXTERNAL           PDLAMC3*     ..*     .. Save statement ..      SAVE               FIRST, LIEEE1, LBETA, LRND, LT*     ..*     .. Data statements ..      DATA               FIRST / .TRUE. /*     ..*     .. Executable Statements ..*      IF( FIRST ) THEN         FIRST = .FALSE.         ONE = 1**        LBETA,  LIEEE1,  LT and  LRND  are the  local values  of  BETA,*        IEEE1, T and RND.**        Throughout this routine  we use the function  DLAMC3  to ensure*        that relevant values are  stored and not held in registers,  or*        are not affected by optimizers.**        Compute  a = 2.0**m  with the  smallest positive integer m such*        that**           fl( a + 1.0 ) = a.*         A = 1         C = 1**+       WHILE( C.EQ.ONE )LOOP   10    CONTINUE         IF( C.EQ.ONE ) THEN            A = 2*A            C = PDLAMC3( A, ONE )            C = PDLAMC3( C, -A )            GO TO 10         END IF*+       END WHILE**        Now compute  b = 2.0**m  with the smallest positive integer m*        such that**           fl( a + b ) .gt. a.*         B = 1         C = PDLAMC3( A, B )**+       WHILE( C.EQ.A )LOOP   20    CONTINUE         IF( C.EQ.A ) THEN            B = 2*B            C = PDLAMC3( A, B )            GO TO 20         END IF*+       END WHILE**        Now compute the base.  a and c  are neighbouring floating point*        numbers  in the  interval  ( beta**t, beta**( t + 1 ) )  and so*        their difference is beta. Adding 0.25 to c is to ensure that it*        is truncated to beta and not ( beta - 1 ).*         QTR = ONE / 4         SAVEC = C         C = PDLAMC3( C, -A )         LBETA = C + QTR**        Now determine whether rounding or chopping occurs,  by adding a*        bit  less  than  beta/2  and a  bit  more  than  beta/2  to  a.*         B = LBETA         F = PDLAMC3( B / 2, -B / 100 )         C = PDLAMC3( F, A )         IF( C.EQ.A ) THEN            LRND = .TRUE.         ELSE            LRND = .FALSE.         END IF         F = PDLAMC3( B / 2, B / 100 )         C = PDLAMC3( F, A )         IF( ( LRND ) .AND. ( C.EQ.A ) )     $      LRND = .FALSE.**        Try and decide whether rounding is done in the  IEEE  'round to*        nearest' style. B/2 is half a unit in the last place of the two*        numbers A and SAVEC. Furthermore, A is even, i.e. has last  bit*        zero, and SAVEC is odd. Thus adding B/2 to A should not  change*        A, but adding B/2 to SAVEC should change SAVEC.*         T1 = PDLAMC3( B / 2, A )         T2 = PDLAMC3( B / 2, SAVEC )         LIEEE1 = ( T1.EQ.A ) .AND. ( T2.GT.SAVEC ) .AND. LRND**        Now find  the  mantissa, t.  It should  be the  integer part of*        log to the base beta of a,  however it is safer to determine  t*        by powering.  So we find t as the smallest positive integer for*        which**           fl( beta**t + 1.0 ) = 1.0.*         LT = 0         A = 1         C = 1**+       WHILE( C.EQ.ONE )LOOP   30    CONTINUE         IF( C.EQ.ONE ) THEN            LT = LT + 1            A = A*LBETA            C = PDLAMC3( A, ONE )            C = PDLAMC3( C, -A )            GO TO 30         END IF*+       END WHILE*      END IF*      BETA = LBETA      T = LT      RND = LRND      IEEE1 = LIEEE1      RETURN**     End of DLAMC1*      END**************************************************************************      SUBROUTINE PDLAMC2( BETA, T, RND, EPS, EMIN, RMIN, EMAX, RMAX )**  -- LAPACK auxiliary routine (version 3.0) --*     Univ. of Tennessee, Univ. of California Berkeley, NAG Ltd.,*     Courant Institute, Argonne National Lab, and Rice University*     October 31, 1992**     .. Scalar Arguments ..      LOGICAL            RND      INTEGER            BETA, EMAX, EMIN, T      DOUBLE PRECISION   EPS, RMAX, RMIN*     ..**  Purpose*  =======**  DLAMC2 determines the machine parameters specified in its argument*  list.**  Arguments*  =========**  BETA    (output) INTEGER*          The base of the machine.**  T       (output) INTEGER*          The number of ( BETA ) digits in the mantissa.**  RND     (output) LOGICAL*          Specifies whether proper rounding  ( RND = .TRUE. )  or*          chopping  ( RND = .FALSE. )  occurs in addition. This may not*          be a reliable guide to the way in which the machine performs*          its arithmetic.**  EPS     (output) DOUBLE PRECISION*          The smallest positive number such that**             fl( 1.0 - EPS ) .LT. 1.0,**          where fl denotes the computed value.**  EMIN    (output) INTEGER*          The minimum exponent before (gradual) underflow occurs.**  RMIN    (output) DOUBLE PRECISION*          The smallest normalized number for the machine, given by*          BASE**( EMIN - 1 ), where  BASE  is the floating point value*          of BETA.**  EMAX    (output) INTEGER*          The maximum exponent before overflow occurs.**  RMAX    (output) DOUBLE PRECISION*          The largest positive number for the machine, given by*          BASE**EMAX * ( 1 - EPS ), where  BASE  is the floating point*          value of BETA.**  Further Details*  ===============**  The computation of  EPS  is based on a routine PARANOIA by*  W. Kahan of the University of California at Berkeley.** =====================================================================**     .. Local Scalars ..      LOGICAL            FIRST, IEEE, IWARN, LIEEE1, LRND      INTEGER            GNMIN, GPMIN, I, LBETA, LEMAX, LEMIN, LT,     $                   NGNMIN, NGPMIN      DOUBLE PRECISION   A, B, C, HALF, LEPS, LRMAX, LRMIN, ONE, RBASE,     $                   SIXTH, SMALL, THIRD, TWO, ZERO*     ..*     .. External Functions ..      DOUBLE PRECISION   PDLAMC3      EXTERNAL           PDLAMC3*     ..*     .. External Subroutines ..      EXTERNAL           PDLAMC1, PDLAMC4, PDLAMC5*     ..*     .. Intrinsic Functions ..      INTRINSIC          ABS, MAX, MIN*     ..*     .. Save statement ..      SAVE               FIRST, IWARN, LBETA, LEMAX, LEMIN, LEPS, LRMAX,     $                   LRMIN, LT*     ..*     .. Data statements ..      DATA               FIRST / .TRUE. / , IWARN / .FALSE. /*     ..*     .. Executable Statements ..*      IF( FIRST ) THEN         FIRST = .FALSE.         ZERO = 0         ONE = 1         TWO = 2**        LBETA, LT, LRND, LEPS, LEMIN and LRMIN  are the local values of*        BETA, T, RND, EPS, EMIN and RMIN.**        Throughout this routine  we use the function  DLAMC3  to ensure*        that relevant values are stored  and not held in registers,  or*        are not affected by optimizers.**        DLAMC1 returns the parameters  LBETA, LT, LRND and LIEEE1.*         CALL PDLAMC1( LBETA, LT, LRND, LIEEE1 )**        Start to find EPS.*         B = LBETA         A = B**( -LT )         LEPS = A**        Try some tricks to see whether or not this is the correct  EPS.*         B = TWO / 3         HALF = ONE / 2         SIXTH = PDLAMC3( B, -HALF )         THIRD = PDLAMC3( SIXTH, SIXTH )         B = PDLAMC3( THIRD, -HALF )         B = PDLAMC3( B, SIXTH )         B = ABS( B )         IF( B.LT.LEPS )     $      B = LEPS*         LEPS = 1**+       WHILE( ( LEPS.GT.B ).AND.( B.GT.ZERO ) )LOOP   10    CONTINUE         IF( ( LEPS.GT.B ) .AND. ( B.GT.ZERO ) ) THEN            LEPS = B            C = PDLAMC3( HALF*LEPS, ( TWO**5 )*( LEPS**2 ) )            C = PDLAMC3( HALF, -C )            B = PDLAMC3( HALF, C )            C = PDLAMC3( HALF, -B )            B = PDLAMC3( HALF, C )            GO TO 10         END IF*+       END WHILE*         IF( A.LT.LEPS )     $      LEPS = A**        Computation of EPS complete.**        Now find  EMIN.  Let A = + or - 1, and + or - (1 + BASE**(-3)).*        Keep dividing  A by BETA until (gradual) underflow occurs. This*        is detected when we cannot recover the previous A.*         RBASE = ONE / LBETA         SMALL = ONE         DO 20 I = 1, 3            SMALL = PDLAMC3( SMALL*RBASE, ZERO )   20    CONTINUE         A = PDLAMC3( ONE, SMALL )         CALL PDLAMC4( NGPMIN, ONE, LBETA )         CALL PDLAMC4( NGNMIN, -ONE, LBETA )         CALL PDLAMC4( GPMIN, A, LBETA )         CALL PDLAMC4( GNMIN, -A, LBETA )         IEEE = .FALSE.*         IF( ( NGPMIN.EQ.NGNMIN ) .AND. ( GPMIN.EQ.GNMIN ) ) THEN            IF( NGPMIN.EQ.GPMIN ) THEN               LEMIN = NGPMIN*            ( Non twos-complement machines, no gradual underflow;*              e.g.,  VAX )            ELSE IF( ( GPMIN-NGPMIN ).EQ.3 ) THEN               LEMIN = NGPMIN - 1 + LT               IEEE = .TRUE.*            ( Non twos-complement machines, with gradual underflow;*              e.g., IEEE standard followers )            ELSE               LEMIN = MIN( NGPMIN, GPMIN )*            ( A guess; no known machine )               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 )*            ( Twos-complement machines, no gradual underflow;*              e.g., CYBER 205 )            ELSE               LEMIN = MIN( NGPMIN, NGNMIN )*            ( A guess; no known machine )               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*            ( Twos-complement machines with gradual underflow;*              no known machine )            ELSE               LEMIN = MIN( NGPMIN, NGNMIN )*            ( A guess; no known machine )               IWARN = .TRUE.            END IF*         ELSE            LEMIN = MIN( NGPMIN, NGNMIN, GPMIN, GNMIN )*         ( A guess; no known machine )            IWARN = .TRUE.         END IF**** Comment out this if block if EMIN is ok         IF( IWARN ) THEN            FIRST = .TRUE.            WRITE( 6, FMT = 9999 )LEMIN         END IF*****        Assume IEEE arithmetic if we found denormalised  numbers above,*        or if arithmetic seems to round in the  IEEE style,  determined*        in routine DLAMC1. A true IEEE machine should have both  things*        true; however, faulty machines may have one or the other.*         IEEE = IEEE .OR. LIEEE1**        Compute  RMIN by successive division by  BETA. We could compute*        RMIN as BASE**( EMIN - 1 ),  but some machines underflow during*        this computation.*         LRMIN = 1         DO 30 I = 1, 1 - LEMIN            LRMIN = PDLAMC3( LRMIN*RBASE, ZERO )   30    CONTINUE**        Finally, call DLAMC5 to compute EMAX and RMAX.*         CALL PDLAMC5( 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',     $      ' DLAMC2,', / ' otherwise supply EMIN explicitly.', / )**     End of DLAMC2*      END**************************************************************************      DOUBLE PRECISION FUNCTION PDLAMC3( A, B )**  -- LAPACK auxiliary routine (version 3.0) --*     Univ. of Tennessee, Univ. of California Berkeley, NAG Ltd.,*     Courant Institute, Argonne National Lab, and Rice University*     October 31, 1992**     .. Scalar Arguments ..      DOUBLE PRECISION   A, B*     ..**  Purpose*  =======**  DLAMC3  is intended to force  A  and  B  to be stored prior to doing*  the addition of  A  and  B ,  for use in situations where optimizers*  might hold one of these in a register.**  Arguments*  =========**  A, B    (input) DOUBLE PRECISION*          The values A and B.** =====================================================================*

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -