NCEPLIBS-w3emc 2.12.0
Loading...
Searching...
No Matches
mersenne_twister Module Reference

This module calculates random numbers using the Mersenne twister. More...

Data Types

interface  random_gauss
 
interface  random_index
 
interface  random_number
 
interface  random_setseed
 
type  random_stat
 

Functions/Subroutines

real function, public random_gauss_f ()
 Generates Gaussian random numbers in functional mode.
 
integer function, public random_index_f (imax)
 Generates random indices in functional mode.
 
real function, public random_number_f ()
 Generates random numbers in functional mode.
 
subroutine, public random_seed (size, put, get, stat)
 Sets and gets state; overloads Fortran 90 standard.
 

Variables

type(random_stat), save sstat
 

Detailed Description

This module calculates random numbers using the Mersenne twister.

(It has been adapted to a Fortran 90 module from open source software. The comments from the original software are given below in the remarks.)

The Mersenne twister (aka MT19937) is a state-of-the-art random number generator based on Mersenne primes and originally developed in 1997 by Matsumoto and Nishimura. It has a period before repeating of 2^19937-1, which certainly should be good enough for geophysical purposes.

Considering the algorithm's robustness, it runs fairly speedily. (Some timing statistics are given below in the remarks.)

This adaptation uses the standard Fortran 90 random number interface, which can generate an arbitrary number of random numbers at one time. The random numbers generated are uniformly distributed between 0 and 1.

The module also can generate random numbers from a Gaussian distribution with mean 0 and standard deviation 1, using a Numerical Recipes algorithm.

The module also can generate uniformly random integer indices. There are also thread-safe versions of the generators in this adaptation, necessitating the passing of generator states which must be kept private.

Usage:

  • The module can be compiled with 4-byte reals or with 8-byte reals, but 4-byte integers are required. The module should be endian-independent.
  • The Fortran 90 interfaces random_seed and random_number are overloaded and can be used as in the standard by adding the appropriate use statement
  • In the below use cases, harvest is a real array of arbitrary size, and iharvest is an integer array of arbitrary size.
  • To generate uniformly distributed random numbers between 0 and 1,
    • call random_number(harvest)
  • To generate Gaussian distributed random numbers with 0 mean and 1 sigma,
    • call random_gauss(harvest)
  • To generate uniformly distributed random integer indices between 0 and n,
    • call random_index(n,iharvest)
  • In standard "saved" mode, the random number generator can be used without setting a seed. But to set a seed, only 1 non-zero integer is required, e.g.
    • call random_setseed(4357) ! set default seed
  • The full generator state can be set via the standard interface random_seed, but it is recommended to use this method only to restore saved states, e.g.
    • call random_seed(size=lsave) ! get size of generator state seed array
    • allocate isave(lsave) ! allocate seed array
    • call random_seed(get=isave) ! fill seed array (then maybe save to disk)
    • call random_seed(put=isave) ! restore state (after read from disk maybe)
  • Locally kept generator states can also be saved in a seed array, e.g.
    • type(random_stat):: stat
    • call random_seed(get=isave,stat=stat) ! fill seed array
    • call random_seed(put=isave,stat=stat) ! restore state
  • To generate random numbers in a threaded region, the "thread-safe" mode must be used where generator states of type random_state are passed, e.g.

Public Defined Types:

Note
Here are the comments in the original open source code: A C-program for MT19937: Real number version genrand() generates one pseudorandom real number (double) which is uniformly distributed on [0,1]-interval, for each call. sgenrand(seed) set initial values to the working area of 624 words. Before genrand(), sgenrand(seed) must be called once. (seed is any 32-bit integer except for 0). Integer generator is obtained by modifying two lines. Coded by Takuji Nishimura, considering the suggestions by Topher Cooper and Marc Rieffel in July-Aug. 1997. This library is free software; you can redistribute it and/or modify it under the terms of the GNU Library General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public License for more details. You should have received a copy of the GNU Library General Public License along with this library; if not, write to the Free Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA Copyright (C) 1997 Makoto Matsumoto and Takuji Nishimura. When you use this, send an email to: matum.nosp@m.oto@.nosp@m.math..nosp@m.keio.nosp@m..ac.j.nosp@m.p with an appropriate reference to your work. Fortran translation by Hiroshi Takano. Jan. 13, 1999.
On a single IBM Power4 processor on the NCEP operational cluster (2005) each Mersenne twister random number takes less than 30 ns, about 3 times slower than the default random number generator, and each random number from a Gaussian distribution takes less than 150 ns.
Author
Mark Iredell
Date
2005-06-14

Function/Subroutine Documentation

◆ random_gauss_f()

real function, public mersenne_twister::random_gauss_f

Generates Gaussian random numbers in functional mode.

Returns
harvest Real number output.
Author
Mark Iredell
Date
2005-06-14

Definition at line 334 of file mersenne_twister.f.

◆ random_index_f()

integer function, public mersenne_twister::random_index_f ( integer, intent(in)  imax)

Generates random indices in functional mode.

Parameters
[in]imaxInteger maximum index input
Returns
iharvest Integer number output
Author
Mark Iredell
Date
2005-06-14

Definition at line 440 of file mersenne_twister.f.

◆ random_number_f()

real function, public mersenne_twister::random_number_f

Generates random numbers in functional mode.

Returns
harvest Real number output.
Author
Mark Iredell
Date
2005-06-14

Definition at line 250 of file mersenne_twister.f.

◆ random_seed()

subroutine, public mersenne_twister::random_seed ( integer, intent(out), optional  size,
integer, dimension(nrest), intent(in), optional  put,
integer, dimension(nrest), intent(out), optional  get,
type(random_stat), intent(inout), optional  stat 
)

Sets and gets state; overloads Fortran 90 standard.

Parameters
[out]sizeOptional integer output size of seed array.
[in]putOptional integer(:) input seed array.
[out]getOptional integer(:) output seed array.
[in,out]statOptional type(random_stat) (thread-safe mode).
Author
Mark Iredell
Date
2005-06-14

Definition at line 158 of file mersenne_twister.f.

Variable Documentation

◆ sstat

type(random_stat), save mersenne_twister::sstat

Definition at line 127 of file mersenne_twister.f.