The Mersenne Twister (MT) is one of the most widely used pseudorandom number generators (PRNG). Takuji Nishimura and Makoto Matsumoto in 1997 developed it.
The Mersenne Twister uses a seed value of 19,937 bits long stored in an array of 624 elements containing 32-bit values. It was given this name because it has a period of 219937- 1 called the Mersenne prime.
The Mersenne prime is any prime number defined as Mn = 2n - 1. Its name is derived from Marin Mersenne, a French Minim friar who studied them in the early 17th century.
The Mersenne Twister algorithm has the following advantages:
It furnishes a long period of 219937-1 and 623-dimensional equidistribution up to 32 bits accuracy.
Perfect computation time since it is based on binary operations.
Very effective use of memory since its code consumes only 624 words of the working area.
Even though Mersenne Twister is extensively used and considered the default
It is predictable. We can retrieve its past bits and predict its future bits.
It is rigid. Also, it is massive.
It fails standard statistical tests despite its massive state size.
In contrast to the Mersenne Twister implementation, the counter-based random number generators (aka. CBRNG) like Threefry or Threefish are better suited for generating random numbers in a highly parallelized fashion using multiple CPU threads or GPUs.
The Mersenne Twister algorithm revolves around two main functions as follows:
Seeding initializes a state according to a seed value.
Generating A random number function pulls a single integer from the predefined state, makes some bit-shifting, and generates a number. After consuming all the state integers (624), the algorithm executes a “reload” operation by twisting the existing integers and generating a new set of state numbers.
The random library in Python refers to a C library implementing the Mersenne Twister algorithm. To better understand the process, let us consider the following examples:
Within this example, we will use the Python random
library to generate an array of random numbers between 0 and 100.
import randomtrials = 10**3random.seed(5489)values = [random.randint(0,100) for i in range(trials)]count_of_values = [values.count(num) for num in range(101)]print('Count of Distinct Values')print(count_of_values)
Now, let us explain the code widget above:
Line 1: Import the required Python libraries.
Line 2: Specify the number of trials for generating a random number between 0 and 100.
Line 3: Initialize the seed to a preset value.
Line 4: Generate an array of values between 0 and 100 while using the function randint
.
Line 5: Count the number of times each value occurred in the previously generated array.
Line 6–7: Display the resulting count.
The following example illustrates the impact of changing the seed value on the returned results:
import randomfor s in [10,20,30]:random.seed(s)for i in range(5):print('Seed = {} - Value = {}'.format(s, random.random()))print()
Now, let us explain the code widget above:
Line 1: Import the random
Python library.
Line 2: Specify a range of seed values.
Line 3: Initialize the random number generator with a base seed value.
Line 4–5: Loop 5 times and display a message showing a random number floating number between 0 and 1 that by invoking the function random()
.
Line 6: Display an empty blank line to indicate a new seed value.