      PROGRAM RANGEN
C
C     PSEUDORANDOM NUMBER GENERATOR
C     -----------------------------------------------
C     AUTHOR: ROBERT EHRLICH (GEORGE MASON U    1973)
C     Revised: Peter Signell (Mich. St. U.      3/86)
C     Revised: Gary Herzenstiel (Mich. St. U.   3/86)
C     Revised: E.J.D.Kales (Mich. St. U.       11/87)
C
C     generate pseudorandom numbers using the power residue
C     method, each number is obtained from the preceeding by
C     X = C*X (MOD N)
C
C     SUBROUTINES: GETINF  - get values for NUM,N,X, & C 
C                  GENRAT  - generate the random numbers
C                  DISPLA  - display the numbers
C                  QUERY   - ask if user wants to repeat
C                  
C                         R A N G E N R
C                               :
C              ---------------------------------------
C              :              :             :        :
C           GETINF         GENRAT        DISPLA    QUERY
C         (NUM,N,X,C)   (NUM,N,X,C,R)    (NUM,R)  (AGAIN)
C
C     ***** DECLARATIONS *****
      REAL NUM,N,N1,R(1001)
      INTEGER IX,M,IC
      CHARACTER AGAIN
      OPEN(UNIT=3,FILE='m354p1f.out')
C                    
C     ***** M A I N   B O D Y *****
C
 10   CALL GETINF (     NUM,N,X,C)
      CALL GENRAT (NUM,N,X,C,   R)
      CALL DISPLA (NUM,N,X,C,R   )
      CALL QUERY  (         AGAIN)
      IF(AGAIN.EQ.'Y') THEN
          WRITE(3,'(A1)') 12
          GOTO 10
      ENDIF
      IF(AGAIN.EQ.'y') THEN
          WRITE(3,'(A1)') 12
          GOTO 10
      ENDIF
      CLOSE(UNIT=3)
      STOP
      END
C
C     ***** G E T I N F *****
C
      SUBROUTINE GETINF(   NUM,N,X,C)
C      
C     prompt user for NUM,N, X, & C
C         (all floating point values)
C
C     ***** DECLARATIONS *****
      REAL NUM,N,X,C
C
C     NUM = number of pseudorandom numbers desired
C     N   = modulus (largest integer)
C     X   = first number in the series
C     C   = constant for power residue formula
C
      PRINT *,'Please supply NUM, N, X, & C values:'
      WRITE(*,20) 'NUM='
      READ *,NUM
      WRITE(*,20) '  N='
      READ *,N
      WRITE(*,20) '  X='
      READ *,X
      WRITE(*,20) '  C='
      READ *,C
  20  FORMAT(/A4)
      WRITE(*,24) NUM,N,X,C
      WRITE(3,24) NUM,N,X,C
  24  FORMAT('m354p1f.for: Pseudorandom Number Generator'/
     +'   Numbers=',F10.2/
     +'   Modulus=',F10.2/
     +' First No.=',F10.2/
     +'  Constant=',F10.2/)
      RETURN
      END
C                              
C     ***** G E N R A T *****
C
      SUBROUTINE GENRAT(NUM,N,X,C,   R)
C      
C     ***** DECLARATIONS *****
      INTEGER M,IX,IC,J,K,NUM1
      REAL NUM,N,X,C,R(1001),N1,RAN
C
      N1=N-1.0
      M=N
      IX=X
      IC=C
      NUM1=NUM
C
      DO 30,J=1,NUM1
C
C        <>IC*IX (MOD N)
C        <>when N is the largest number permitted:
           IX=IABS(IC*IX)
C        <>when numbers larger than N are permitted:
           IF(IX.GT.N1) IX=IX-M*(IX/M)
           RAN=IX
C        <>divide by N-1, so RAN is between 0 and 1:
           R(J)=RAN/N1
C
 30   CONTINUE
      RETURN
      END
C
C     ***** D I S P L A *****
C
      SUBROUTINE DISPLA(NUM,N,X,C,R    )
C
C     ***** DECLARATIONS *****
      REAL NUM,N,X,C,R(1001)
      INTEGER INUM,J1,J,TJ,LEFTOVR
C
      INUM=NUM
      TJ=(NUM/6)*6
      LEFTOVR=INUM-TJ
      WRITE(3,44) ((R(J1),J1=J,J+5),J=1,TJ,6)
      WRITE(3,44) (R(J1),J1=TJ+1,INUM)
 44   FORMAT(6F12.5)
      RETURN
      END
C
C     ***** Q U E R Y *****
C
      SUBROUTINE QUERY(    AGAIN)
C 
C     ***** DECLARATIONS *****
      CHARACTER AGAIN
C
      PRINT *
      WRITE(*,62)
 62   FORMAT(
     +'Would you like to do this again using new values?'/
     +'(Y/N)? ')
      READ( *,'(A1)')AGAIN
      RETURN
      END
C     ***** P R O G R A M    E N D *****