! Last change: DOS 31 Jul 2000 8:36 pm ! *** copyright 2000 *** ! *** filename ranlp.f95 *** John F. Monahan ** ! ********************** ! ! SOME COMPILERS REQUIRE MODULE TO PREVIOUSLY EXIST OR BE ! AT THE BEGINNING MODULE GFSRLP INTEGER TABPTJ INTEGER, DIMENSION(98) :: TABLE END MODULE GFSRLP PROGRAM PRANLP ! ! BASIC CHI-SQUARE TEST OF UNIFORM PSEUDORANDOM GENERATOR USE GFSRLP IMPLICIT NONE REAL CHISQ,U,EXP,FKCELL,RANLP INTEGER, DIMENSION(64) :: CELL ! DO 2**10 = 1024 UNIFORMS IN 64 CELLS INTEGER, PARAMETER :: N = 1024 INTEGER, PARAMETER :: KCELLS = 64 INTEGER I,J ! 20 FORMAT(6I12) 21 FORMAT(' RESULT OF CHI-SQUARE TEST ON RANLP UNIFORM GENERATOR'/ & & ' WITH',I8,' OBS IN',I4,' CELLS GIVES CHISQ =',F12.4) ! OPEN( UNIT=6, FILE='ranlp.out' ) OPEN( UNIT=5, FILE='gfsrlp.tb0' ) ! original table OPEN( UNIT=7, FILE='gfsrlp.tb1' ) ! store table at end ! ! INITIALIZE CELL COUNTERS TO ZERO CELL = 0 ! INITIALIZE GENERATOR WITH TABLE READ(5,20) TABPTJ,TABLE ! EXPECTED NUMBER IN EACH CELL FKCELL = REAL(KCELLS) EXP = REAL(N)/FKCELL ! FILL UP THE CELLS DO I = 1,N U = RANLP(I) ! J POINTS TO CELL J = 1 + INT( U*FKCELL ) ! INCREMENT COUNT IN CELL CELL(J) = CELL(J) + 1 END DO ! LOOP ON I ! SAVE TABLE WRITE(7,20) TABPTJ,TABLE ! TEST FOR UNIFORMITY CHISQ = 0. DO J = 1,KCELLS CHISQ = CHISQ + (CELL(J) - EXP)*(CELL(J) - EXP)/EXP END DO ! LOOP ON J ! WRITE OUT RESULTS WRITE(6,21) N,KCELLS,CHISQ STOP END PROGRAM PRANLP REAL FUNCTION RANLP(IDUM) ! LEWIS-PAYNE GFSR UNIFORM RANDOM NUMBER GENERATOR ! ! T. G. LEWIS & W. H. PAYNE (1973) GENERALIZED FEEDBACK SHIFT REGISTER ! PSEUDORANDOM NUMBERS, JOURNAL OF THE ACM, VOLUME 20, PP. 456-468 ! ! USES PRIMITIVE TRINOMIAL WITH P=98 AND Q=27 ! ! ARGUMENT IS A DUMMY AND NEVER USED ! ! INPUT POINTER AND TABLE PASSED IN MODULE GFSRLP ! ORIGINAL TABLE IN THE FILE 'gfsrlp.tb0' IN 6I12 FORMAT ! CAN WRITE POINTER AND TABLE IN FILE AS SEED FOR NEXT EXPERIMENT ! USE GFSRLP ! MODULE HOLDS TABLE AND POINTER IMPLICIT NONE INTEGER, INTENT(IN) :: IDUM ! PARAMETERS OF TAUSWORTHE SEQUENCE INTEGER, PARAMETER :: P = 98 INTEGER, PARAMETER :: Q = 27 INTEGER K REAL, PARAMETER :: FN = 2147483648. ! 2**31 ! ! UPDATE POINTER TABPTJ = TABPTJ + 1 IF ( TABPTJ .GT. P ) TABPTJ = 1 ! UPDATE DELAY POINTER K = TABPTJ + Q IF ( K .GT. P ) K = K - P ! COMPUTE EXCLUSIVE OR OF TWO TABLE ENTRIES ! AND REPLACE WITH NEW ONE TABLE(TABPTJ) = IEOR( TABLE(K), TABLE(TABPTJ) ) ! CONVERT BIG INTEGER TO FLOATING POINT NUMBER RANLP = REAL( TABLE(TABPTJ) ) / FN RETURN END FUNCTION RANLP ! *** end of filename ranlp.f95 *********************