- NAME
- SYNOPSIS
- DESCRIPTION
- CONSTRUCTOR
- SEEDING
- STATE HANDLING
- FLOATING POINT PRECISION
- UNIFORMLY DISTRIBUTED RANDOM NUMBERS
- NON-UNIFORMLY DISTRIBUTED RANDOM NUMBERS
- EXPORTS
- NOTES
- SEE ALSO
- AUTHOR
- COPYRIGHT
- LICENSE

# NAME

Math::Random::MTwist - A fast stateful Mersenne Twister pseudo-random number generator.

# SYNOPSIS

```
# object-oriented inteface
use Math::Random::MTwist;
my $mt = Math::Random::MTwist->new(); # seed from /dev/urandom
my $int = $mt->irand(); # [0 .. 2^64-1 or 2^32-1]
my $double = $mt->rand(73); # [0 .. 73)
$mt->goodseed(); # seed from /dev/random
$mt->savestate("/tmp/foobar"); # save current state to file
$mt->loadstate("/tmp/foobar"); # load past state from file
my @dist = map $mt->rd_triangular(1, 3, 2), 1 .. 1e3; # triangular dist.
# function-oriented interface (OO interface may be used in parallel)
use Math::Random::MTwist qw(seed32 seedfull
timeseed fastseed goodseed bestseed);
use Math::Random::MTwist qw(:seed) # gives you all of the above
use Math::Random::MTwist qw(srand rand rand32 irand irand32 irand64);
use Math::Random::MTwist qw(:rand); # gives you all of the above
use Math::Random::MTwist qw(rd_exponential rd_triangular rd_normal ...);
use Math::Random::MTwist qw(:dist); # gives you all of the above
use Math::Random::MTwist qw(savestate loadstate getstate setstate);
use Math::Random::MTwist qw(:state); # gives you all of the above
use Math::Random::MTwist qw(:all); # import all functions
```

# DESCRIPTION

Math::Random::MTwist is a Perl interface to Geoff Kuenning's mtwist C library. It provides several seeding methods and various random number distributions.

All functions are available through a function-oriented interface and an object-oriented interface. The function-oriented interface maintains a single global state while the OO interface gives you an individual state per instance.

The function-oriented interface provides drop-in replacements for Perl's built-in `rand()`

and `srand()`

functions.

If you `use`

the module with an import list, the global state is seeded automatically using `fastseed()`

. In this case, if you need the `MT_`

constants, you must import them explicitly through the `:DEFAULT`

tag.

# CONSTRUCTOR

**new()**,**new($seed)**-
Takes an optional argument specifying the seed. If you omit the seed,

`MT_FASTSEED`

is the default.The seed can be a number (will be coerced to an unsigned 32-bit integer), an array reference holding up to 624 such numbers (missing values are padded with zeros, excess values are ignored) or one of the special values

`MT_TIMESEED`

,`MT_FASTSEED`

,`MT_GOODSEED`

or`MT_BESTSEED`

that choose one of the corresponding seeding methods (see below).Each instance maintains an individual PRNG state allowing multiple independent random number streams.

# SEEDING

**seed32($number)**-
Seeds the generator with

`$number`

, coercing it to an unsigned 32-bit integer. Calls mtwist's`mts_seed32new()`

. Returns the seed. **srand()**,**srand($number)**-
Calls

`seed32`

if`$number`

is given,`fastseed()`

otherwise. Returns the seed. **seedfull($seeds)**-
Seeds the generator with up to 624 numbers from the

*array reference*`$seeds`

. The values are coerced to unsigned 32-bit integers. Missing or undefined values are taken as zero, excess values are ignored. Croaks unless you supply at least one non-zero value. Calls mtwist's`mts_seedfull()`

. Returns nothing. **fastseed()**-
Seeds the generator with 4 bytes read from

`/dev/urandom`

(preferably via getrandom()) if available, otherwise from the system time (see details under`timeseed()`

). Calls mtwist's`mts_seed()`

. Returns the seed.This method is called by

`new(MT_FASTSEED)`

. **goodseed()**-
Seeds the generator with 4 bytes read from

`/dev/random`

(preferably via getrandom()) if available, otherwise from the system time (see details under`timeseed()`

). Calls mtwist's`mts_goodseed()`

. Returns the seed.This method is called by

`new(MT_GOODSEED)`

. **bestseed()**-
Seeds the generator with 642 integers read from

`/dev/random`

if available. This might take a very long time and is probably not worth the waiting. If`/dev/random`

is unavailable or there was a reading error it falls back to`goodseed()`

. Calls mtwist's`mts_bestseed()`

.This method is called by

`new(MT_BESTSEED)`

. **timeseed()**-
Seeds the generator from the current system time obtained from

`Time::HiRes::gettimeofday()`

by calculating`seconds * 1e6 + microseconds`

and coercing the result to an unsigned 32-bit integer. Returns the seed.This method is called by

`new(MT_TIMESEED)`

.`timeseed`

doesn't correspond to any of mtwist's functions. The rationale behind it is that mtwist uses the system time if neither`/dev/urandom`

nor`/dev/random`

is available. On Windows, the time source it uses has only millisecond resolution in contrast to microseconds from`gettimeofday()`

, so`fast/good/bestseed()`

and`srand()`

(w/o seed argument) call`timeseed()`

directly in this case.

# STATE HANDLING

**savestate($filename or $filehandle)**-
Saves the current state of the generator to a file given either by a filename (file will be truncated) or an open Perl file handle.

Returns 1 on success, 0 on error (you might want to check

`$!`

). **loadstate($filename or $filehandle)**-
Loads the state of the generator from a file given either by a filename or an open Perl file handle.

Returns 1 on success, 0 on error (you might want to check

`$!`

). **getstate()**-
Returns the current state of the generator as a binary string.

**setstate($string)**-
Sets the state of the generator from

`$string`

, which you should have obtained with`getstate()`

. croak()s if`$string`

is not a string of the correct size.

`savestate()`

and `loadstate()`

are portable because they save the state as decimal numbers. `getstate()`

and `setstate()`

are not portable because they simply use a memory dump for laziness reasons.

However, depending on your system's architecture, you can convert `getstate()`

to `savestate()`

format using something like `join ' ', (reverse unpack 'L624i', getstate())[1..624,0];`

.

# FLOATING POINT PRECISION

The rand() and rd_l* functions return whatever NVTYPE your Perl uses (i.e. quadmath, long double or double). A double gives you 53-bit precision. However, with larger double types you always get 64-bit precision since the mtwist library is limited to 64-bit. With quadmath or long double the corresponding math functions are used (sqrtq/sqrtl etc.).

The rand32() and non-l rd_* functions always return a double.

# UNIFORMLY DISTRIBUTED RANDOM NUMBERS

**irand()**-
Returns a random unsigned integer, 64-bit if your system supports it (see

`irand64()`

), 32-bit otherwise. **irand32()**-
Returns a random unsigned 32-bit integer. Calls mtwist's

`mts_lrand()`

. **irand64()**-
If your Perl uses 64-bit integers, returns a 64-bit unsigned integer. If your Perl uses 32-bit integers but your OS knows the

`uint64_t`

type, returns a 64-bit unsigned integer as a decimal string. Otherwise it returns undef. Calls mtwist's`mts_llrand()`

. **rand()**,**rand($bound)**-
Returns a random double with 53-bit precision in the range

`[0, $bound)`

. Calls mtwist's`mts_ldrand()`

.`$bound`

may be negative. If`$bound`

is omitted or zero it defaults to 1. **rand32()**,**rand32($bound)**-
Returns a random double with 32-bit precision in the range

`[0, $bound)`

. Slightly faster than rand(). Calls mtwist's`mts_drand()`

.`$bound`

may be negative. If`$bound`

is omitted or zero it defaults to 1. **rd_iuniform(IV lower, IV upper)**-
Returns a signed integer in the range [lower, upper) of your Perl's IVTYPE (32-bit or 64-bit). Takes signed integer arguments.

**rd_iuniform32(IV lower, IV upper)**-
Returns a signed 32-bit integer in the range [lower, upper). Takes signed 32-bit arguments.

**rd_iuniform64(IV lower, IV upper)**-
Returns a signed 64-bit integer in the range [lower, upper) if your Perl uses 64-bit integers. Otherwise it returns undef. Note that unlike irand64() it doesn't return a decimal string in the 32-bit IV + uint64_t case because you could only pass it 32-bit arguments anyway.

**randstr()**,**randstr($length)**-
Returns a random binary string. The default length is 8 bytes. Returns undef if there is not enough memory.

# NON-UNIFORMLY DISTRIBUTED RANDOM NUMBERS

With the exception of `rd_double()`

the following methods come in two variants:

and **rd_**xxx

. They all return a double but the **rd_l**xxx

versions provide 32-bit precision while the **rd_**xxx

versions provide 53-bit precision at the expense of speed.**rd_l**xxx

TODO: If your Perl's NVs are long doubles, the

functions provide 64-bit precision.**rd_l**xxx

**rd_double()**,**rd_double($index)**-
This is kind of a FUNction (that's the "Fun with flags" sort of fun).

It generates a random double in the complete (signed) double range. It does that by drawing a random 64-bit integer (if available, otherwise two 32-bit integers) and interpreting the bit pattern as a double. That's the same as saying

`unpack 'd', pack 'Q', irand64()`

. The results follow a Benford distribution (each range [2^n, 2^(n+1)[ can hold 2^52 values). Be prepared to meet some NaNs, Infs and subnormals (see POSIX::2008 for floating point check functions).In scalar context it returns a double. In list context it returns the double, the corresponding integer (undef if your Perl doesn't have 64-bit integers) and the packed string representation.

For convenience, you can call

**rd_double()**with an optional argument**$index**to get the same result as with**(rd_double())[$index]**, just a bit more efficiently. **rd_(l)uniform(NV lower, NV upper)**-
Generates floating point numbers from a uniform distribution in the range [lower, upper).

**rd_(l)exponential(double mean)**-
Generates an exponential distribution with the given mean.

**rd_(l)erlang(int k, double mean)**-
Generates an Erlang-k distribution with the given mean.

**rd_(l)weibull(double shape, double scale)**-
Generates a Weibull distribution with the given shape and scale.

**rd_(l)normal(double mean, double sigma)**-
Generates a normal (Gaussian) distribution with the given mean and standard deviation sigma.

**rd_(l)lognormal(double shape, double scale)**-
Generates a log-normal distribution with the given shape and scale.

**rd_(l)triangular(double lower, double upper, double mode)**-
Generates a triangular distribution in the range

`[lower, upper)`

with the given mode.

# EXPORTS

By default the module exports the constants MT_TIMESEED, MT_FASTSEED, MT_GOODSEED and MT_BESTSEED that can be used as an argument to the constructor.

The following export tags are available:

**:dist**-
rd_double rd_erlang rd_lerlang rd_exponential rd_lexponential rd_lognormal rd_llognormal rd_normal rd_lnormal rd_triangular rd_ltriangular rd_weibull rd_lweibull

**:rand**-
rand rand rand32 rand64 irand irand32 irand64

**:seed**-
seed32 seedfull timeseed fastseed goodseed bestseed

**:state**-
savestate loadstate getstate setstate

**:all**-
All of the above.

**:DEFAULT**-
MT_TIMESEED MT_FASTSEED MT_GOODSEED MT_BESTSEED

# NOTES

This module is not `fork()/clone()`

aware, i.e. you have to take care of re-seeding/re-instantiating in new processes/threads yourself.

Imported functions and OO methods have the same names. This works by symbol table "redirection", e.g. non-OO irand() is actually _irand() internally and so on (note the underscore). The minor drawback is that you can't use fully qualified names like `Math::Random::MTwist::irand()`

etc. Instead you have to say `Math::Random::MTwist::_irand()`

. I considered avoiding this by checking if the first argument is a blessed reference but I discarded that in favor of speed.

# SEE ALSO

http://www.cs.hmc.edu/~geoff/mtwist.html

Math::Random::MT and Math::Random::MT::Auto are significantly slower than Math::Random::MTwist. MRMA has some additional sophisticated features but it depends on non-core modules.

# AUTHOR

Carsten Gaebler (cgpan ʇɐ gmx ʇop de). I only accept encrypted e-mails, either via SMIME or GPG.

# COPYRIGHT

Perl and XS portion: Copyright © 2014 by Carsten Gaebler.

mtwist C library: Copyright © 2001, 2002, 2010, 2012, 2013 by Geoff Kuenning.

# LICENSE

Perl and XS portion: WTFPL.

mtwist C library: LGPL