!********o*********o*********o*********o*********o*********o*********o**
! In spite of previous claims, this program doesn't work as intended
! with the ifc random-number generator.
!---------------------
! This program demonstrates a way to set the seed of fortran's pseudo-
! random number generator (PRNG).  You can set the seed to something
! specific so that you get the same sequence each time, or you can have
! it choose a seed from the system clock.
!
! Inputs
!   A choice of the random seed.
!
! Outputs
!   A series of 'random' numbers.
!---------------------
! Author:   Bob Harris
! Class:    CMPSC 201F
! Section:  1234
! Date Due: 19 Nov 2003
!********o*********o*********o*********o*********o*********o*********o**

program morerandom

implicit none

integer   :: sequenceChoice
real      :: r
character :: answer

! ask our user for a value to slect which pseudo-random sequence we'll
! get

print *, "please tell me what value to use for a random seed"
print *, "(use zero if you don't really care)"
read  *, sequenceChoice

! use that value to 'seed' the pseudo-random number generator

call SetSpecificRandomSeed (sequenceChoice)

do

    ! get the next number in the pseudo-random sequence;  see Nyhoff &
    ! Leestma page A47;  the subroutine RANDOM_NUMBER will place the
    ! number in r;  That number will be in the range 0 <= r < 1

    call RANDOM_NUMBER(r)
    print *, "random number is: ", r

    ! ask the user if we should keep going

    print *, "had enough yet?"
    read  *, answer
    if ((answer == 'Y') .or. (answer == 'y')) exit

    end do

contains

!-----------------------------------------------------------------------
! SetSpecificRandomSeed--
!   Seed the random number generator with your choice of seed.
!---------------------
! This routine fails to have the desired effect under ifc.  It causes
! ifc's generator to go into a mode where it just adds a constant to
! the previous random number, modulo 1.
!---------------------
! Arguments
!   sequenceChoice:  The initial seed for the random number generator.
!                    If this is zero, we use the system clock instead.
!-----------------------------------------------------------------------

subroutine SetSpecificRandomSeed (sequenceChoice)
    integer, intent(in)                :: sequenceChoice
    integer                            :: seedSize
    integer, allocatable, dimension(:) :: seedArray
    integer                            :: count, countrate, countmax
    integer                            :: magic
    integer                            :: index

    ! find out how big the random number generator's seed is;  the
    ! fortran standard allows the seed to be different sizes on
    ! different operating systems or compilers

    call random_seed (size=seedSize)

    ! allocate an array big enough to hold the entire seed

    allocate (seedArray(seedSize))

    if (sequenceChoice /= 0) then
        magic = sequenceChoice
    else
        call system_clock (count, countrate, countmax)
        magic = count
    end if

    ! fill the array with a deterministic sequence, based on the
    ! sequence-choice number;  note that is it necessary to write
    ! a value to each element of the seed array, and that value
    ! must depend on the sequence-choice number

    do index=1,seedSize
        seedArray(index) = magic
        magic            = (5*magic)+1
    end do

    ! initialize the random number generator with our seed array

    call random_seed (put=seedArray)

end subroutine SetSpecificRandomSeed

end program morerandom

