Type | Intent | Optional | Attributes | Name | ||
---|---|---|---|---|---|---|
integer | :: | iy |
NAME
SYNOPSIS
DESCRIPTION
OPTIONS
EXAMPLE |
doubleprecision function mat_urand(iy) !> !!##NAME !! mat_urand(3f) - [] uniform random number generator !! LICENSE(MIT) !! !!##SYNOPSIS !! !! doubleprecision function mat_urand(iy) !! !! integer,intent(inout) :: iy !! !!##DESCRIPTION !! mat_urand(3f) is a uniform random number generator based on theory and !! suggestions given in D.E. Knuth (1969), Vol 2. The integer IY should !! be initialized to an arbitrary integer prior to the first call to !! mat_urand(3f). The calling program should not alter the value of IY !! between subsequent calls to mat_urand(3f). Values of mat_urand(3f) will !! be returned in the interval (0,1). !! !!##OPTIONS !! IY seed for generating a sequence. !! !!##EXAMPLE !! integer :: iy integer,save :: ia integer,save :: ic integer,save :: itwo=2 integer,save :: m2=0 integer :: m integer,save :: mic doubleprecision :: halfm doubleprecision,save :: s doubleprecision :: datan doubleprecision :: dsqrt !----------------------------------------------------------------------- if (m2 .eq. 0) then ! if first entry, compute machine integer word length m = 1 infinite : do m2 = m m = itwo*m2 if (m .le. m2) exit infinite enddo infinite halfm = m2 ia = 8*int(halfm*datan(1.d0)/8.d0) + 5 ! compute multiplier and increment for linear congruential method ic = 2*int(halfm*(0.5d0-dsqrt(3.d0)/6.d0)) + 1 mic = (m2 - ic) + m2 s = 0.5d0/halfm ! s is the scale factor for converting to floating point endif ! compute next random number iy = iy*ia if (iy .gt. mic) iy = (iy - m2) - m2 ! this statement is for computers which do not allow integer overflow on addition iy = iy + ic if (iy/2 .gt. m2) iy = (iy - m2) - m2 ! this statement is for computers where the word length for addition is greater than ! for multiplication if (iy .lt. 0) iy = (iy + m2) + m2 ! this statement is for computers where integer overflow affects the sign bit mat_urand = dble(iy)*s end function mat_urand