76 module mersennetwister_mod
78 use platform_mod,
only: r8_kind, i8_kind
86 integer,
parameter :: blocksize = 624, &
89 umask = -2147483648_i8_kind, &
92 integer,
parameter ::
tmaskb= -1658038656, & !< (0x9d2c5680UL)
100 integer :: currentElement
101 integer,
dimension(0:blockSize -1) :: state
106 module procedure initialize_scalar, initialize_vector
119 function mixbits(u, v)
120 integer,
intent( in) :: u, v
127 integer,
intent( in) :: u, v
131 integer,
parameter,
dimension(0:1) :: t_matrix = (/ 0,
matrix_a /)
133 twist = ieor(ishft(mixbits(u, v), -1), t_matrix(iand(v, 1)))
134 twist = ieor(ishft(mixbits(u, v), -1), t_matrix(iand(v, 1)))
137 subroutine nextstate(twister)
138 type(randomNumberSequence),
intent(inout) :: twister
143 do k = 0, blocksize - m - 1
144 twister%state(k) = ieor(twister%state(k + m), &
145 twist(twister%state(k), twister%state(k + 1)))
147 do k = blocksize - m, blocksize - 2
148 twister%state(k) = ieor(twister%state(k + m - blocksize), &
149 twist(twister%state(k), twister%state(k + 1)))
151 twister%state(blocksize - 1) = ieor(twister%state(m - 1), &
152 twist(twister%state(blocksize - 1), twister%state(0)))
153 twister%currentElement = 0
155 end subroutine nextstate
157 elemental function temper(y)
158 integer,
intent(in) :: y
164 x = ieor(y, ishft(y, -11))
165 x = ieor(x, iand(ishft(x, 7),
tmaskb))
166 x = ieor(x, iand(ishft(x, 15),
tmaskc))
167 temper = ieor(x, ishft(x, -18))
172 function initialize_scalar(seed)
result(twister)
173 integer,
intent(in ) :: seed
174 type(randomNumberSequence) :: twister
181 twister%state(0) = iand(seed, -1)
182 do i = 1, blocksize - 1
183 twister%state(i) = 1812433253 * ieor(twister%state(i-1), &
184 ishft(twister%state(i-1), -30)) + i
185 twister%state(i) = iand(twister%state(i), -1)
187 twister%currentElement = blocksize
188 end function initialize_scalar
190 function initialize_vector(seed)
result(twister)
191 integer,
dimension(0:),
intent(in) :: seed
192 type(randomNumberSequence) :: twister
194 integer :: i, j, k, nFirstLoop, nWraps
197 twister = initialize_scalar(19650218)
199 nfirstloop = max(blocksize,
size(seed))
201 i = mod(k + nwraps, blocksize)
202 j = mod(k - 1,
size(seed))
204 twister%state(i) = twister%state(blocksize - 1)
205 twister%state(1) = ieor(twister%state(1), &
206 ieor(twister%state(1-1), &
207 ishft(twister%state(1-1), -30)) * 1664525) + &
209 twister%state(i) = iand(twister%state(i), -1)
212 twister%state(i) = ieor(twister%state(i), &
213 ieor(twister%state(i-1), &
214 ishft(twister%state(i-1), -30)) * 1664525) + &
216 twister%state(i) = iand(twister%state(i), -1)
223 do i = mod(nfirstloop, blocksize) + nwraps + 1, blocksize - 1
224 twister%state(i) = ieor(twister%state(i), &
225 ieor(twister%state(i-1), &
226 ishft(twister%state(i-1), -30)) * 1566083941) - i
227 twister%state(i) = iand(twister%state(i), -1)
230 twister%state(0) = twister%state(blocksize - 1)
232 do i = 1, mod(nfirstloop, blocksize) + nwraps
233 twister%state(i) = ieor(twister%state(i), &
234 ieor(twister%state(i-1), &
235 ishft(twister%state(i-1), -30)) * 1566083941) - i
236 twister%state(i) = iand(twister%state(i), -1)
239 twister%state(0) =
umask
240 twister%currentElement = blocksize
242 end function initialize_vector
257 if(twister%currentElement >= blocksize)
call nextstate(twister)
259 getrandomint = temper(twister%state(twister%currentElement))
260 twister%currentElement = twister%currentElement + 1
289 if(localint < 0)
then
290 getrandomreal = dble(localint + 2.0d0**32)/(2.0d0**32 - 1.0d0)
296 subroutine finalize_randomnumbersequence(twister)
299 twister%currentElement = blocksize
301 end subroutine finalize_randomnumbersequence
303 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.