- NAME
- SYNOPSIS
- DESCRIPTION
- FLOATING POINT PRECISION
- CONSTRUCTOR
- SEEDING
- STATE HANDLING
- 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.

# FLOATING POINT PRECISION

The rand() and rd_l* functions return whatever NV type your Perl uses (e.g. double, long double or __float128 [quadmath]). However, before version 0.22, the results were limited to 64-bit precision. Since version 0.22 you get the full precision of your Perl's NV.

If your Perl uses long doubles or quadmath, the distribution functions use the corresponding math functions (sqrtl/sqrtq etc.).

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

# 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

`clock_gettime()`

(if your system supports CLOCK_MONOTONIC) or`Time::HiRes::gettimeofday()`

by calculating the total nanoseconds (or microseconds), XORing them with a memory address (hoping for some more randomness from ASLR) 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, so I tried to pimp it a bit.

# 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];`

.

# 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()`

. **irand128()**-
That's pretty standard. ;-) No, it just works with a GCC that has __int128. Returns undef otherwise.

**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.

**rd_(l)uniform(NV lower, NV upper)**-
Generates floating point numbers from a uniform distribution in the range [lower, upper).

**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)exponential(NV mean)**-
Generates an exponential distribution with the given mean.

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

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

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

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

**rd_(l)triangular(NV lower, NV upper, NV 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 (POSIX::AtFork might be useful here).

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.

I made some changes to the mtwist library (not affecting the algorithms) to adapt it to the Perl module. These changes are documented in the patches/ directory.

# SEE ALSO

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

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

# AUTHOR

Carsten Gaebler (cgpan ʇɐ gmx ʇop de).

# 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