93 module mersennetwister_mod
95 use platform_mod,
only: r8_kind, i8_kind
103 integer,
parameter :: blocksize = 624, &
106 umask = -2147483648_i8_kind, &
109 integer,
parameter ::
tmaskb= -1658038656, & !< (0x9d2c5680UL)
117 integer :: currentElement
118 integer,
dimension(0:blockSize -1) :: state
123 module procedure initialize_scalar, initialize_vector
136 function mixbits(u, v)
137 integer,
intent( in) :: u, v
144 integer,
intent( in) :: u, v
148 integer,
parameter,
dimension(0:1) :: t_matrix = (/ 0,
matrix_a /)
150 twist = ieor(ishft(mixbits(u, v), -1), t_matrix(iand(v, 1)))
151 twist = ieor(ishft(mixbits(u, v), -1), t_matrix(iand(v, 1)))
154 subroutine nextstate(twister)
155 type(randomNumberSequence),
intent(inout) :: twister
160 do k = 0, blocksize - m - 1
161 twister%state(k) = ieor(twister%state(k + m), &
162 twist(twister%state(k), twister%state(k + 1)))
164 do k = blocksize - m, blocksize - 2
165 twister%state(k) = ieor(twister%state(k + m - blocksize), &
166 twist(twister%state(k), twister%state(k + 1)))
168 twister%state(blocksize - 1) = ieor(twister%state(m - 1), &
169 twist(twister%state(blocksize - 1), twister%state(0)))
170 twister%currentElement = 0
172 end subroutine nextstate
174 elemental function temper(y)
175 integer,
intent(in) :: y
181 x = ieor(y, ishft(y, -11))
182 x = ieor(x, iand(ishft(x, 7),
tmaskb))
183 x = ieor(x, iand(ishft(x, 15),
tmaskc))
184 temper = ieor(x, ishft(x, -18))
189 function initialize_scalar(seed)
result(twister)
190 integer,
intent(in ) :: seed
191 type(randomNumberSequence) :: twister
198 twister%state(0) = iand(seed, -1)
199 do i = 1, blocksize - 1
200 twister%state(i) = 1812433253 * ieor(twister%state(i-1), &
201 ishft(twister%state(i-1), -30)) + i
202 twister%state(i) = iand(twister%state(i), -1)
204 twister%currentElement = blocksize
205 end function initialize_scalar
207 function initialize_vector(seed)
result(twister)
208 integer,
dimension(0:),
intent(in) :: seed
209 type(randomNumberSequence) :: twister
211 integer :: i, j, k, nFirstLoop, nWraps
214 twister = initialize_scalar(19650218)
216 nfirstloop = max(blocksize,
size(seed))
218 i = mod(k + nwraps, blocksize)
219 j = mod(k - 1,
size(seed))
221 twister%state(i) = twister%state(blocksize - 1)
222 twister%state(1) = ieor(twister%state(1), &
223 ieor(twister%state(1-1), &
224 ishft(twister%state(1-1), -30)) * 1664525) + &
226 twister%state(i) = iand(twister%state(i), -1)
229 twister%state(i) = ieor(twister%state(i), &
230 ieor(twister%state(i-1), &
231 ishft(twister%state(i-1), -30)) * 1664525) + &
233 twister%state(i) = iand(twister%state(i), -1)
240 do i = mod(nfirstloop, blocksize) + nwraps + 1, blocksize - 1
241 twister%state(i) = ieor(twister%state(i), &
242 ieor(twister%state(i-1), &
243 ishft(twister%state(i-1), -30)) * 1566083941) - i
244 twister%state(i) = iand(twister%state(i), -1)
247 twister%state(0) = twister%state(blocksize - 1)
249 do i = 1, mod(nfirstloop, blocksize) + nwraps
250 twister%state(i) = ieor(twister%state(i), &
251 ieor(twister%state(i-1), &
252 ishft(twister%state(i-1), -30)) * 1566083941) - i
253 twister%state(i) = iand(twister%state(i), -1)
256 twister%state(0) =
umask
257 twister%currentElement = blocksize
259 end function initialize_vector
274 if(twister%currentElement >= blocksize)
call nextstate(twister)
276 getrandomint = temper(twister%state(twister%currentElement))
277 twister%currentElement = twister%currentElement + 1
306 if(localint < 0)
then
307 getrandomreal = dble(localint + 2.0d0**32)/(2.0d0**32 - 1.0d0)
313 subroutine finalize_randomnumbersequence(twister)
316 twister%currentElement = blocksize
318 end subroutine finalize_randomnumbersequence
320 end module mersennetwister_mod
integer, parameter matrix_a
constant vector a (0x9908b0dfUL)
integer function, public getrandompositiveint(twister)
Generate a random integer on the interval [0,0x7fffffff] or [0,2**31]. Equivalent to genrand_int31 in...
integer, parameter lmask
least significant r bits (0x7fffffffUL)
integer, parameter umask
most significant w-r bits (0x80000000UL)
integer, parameter tmaskc
(0xefc60000UL)
integer, parameter tmaskb
(0x9d2c5680UL)
real(r8_kind) function, public getrandomreal(twister)
Generate a random number on [0,1] Equivalent to genrand_real1 in the C code. The result is stored as ...
integer function, public getrandomint(twister)
Generate a random integer on the interval [0,0xffffffff].
The type containing the state variable.