Random Object Generation#

Pseudo-random quantities are used in several Magma algorithms, and may also be generated explicitly by some intrinsics. Throughout the Handbook, the word ‘random’ is used for ‘pseudo-random’.

Since V2.7 (June 2000), Magma contains an implementation of the Monster random number generator of G. Marsaglia [Marsaglia, 2000]. The period of this generator is \(2^{29430} - 2^{27382}\) (approximately \(10^{8859}\)), and passes all of the stringent tests in Marsaglia’s Diehard test suite [Marsaglia, 1995]. Since V2.13 (July 2006), this generator is combined with the MD5 hash function to produce a higher-quality result.

Because the generator uses an internal array of machine integers, one ‘seed’ variable does not express the whole state, so the method for setting or getting the generator state is by way of a pair of values: (1) the seed for initializing the array, and (2) the number of steps performed since the initialization.

SetSeed(s, c): RngIntElt, RngIntElt#
SetSeed(s): RngIntElt#

(Procedure.) Reset the random number generator to have initial seed \(s\) (\(0 \leq s < 2^{32}\)), and advance to step \(c\) (\(0 \leq c < 2^{64})\). If \(c\) is not given, it is taken to be \(0\). Passing -Sn to Magma at startup is equivalent to typing SetSeed(n); after startup.

GetSeed() -> RngIntElt, RngIntElt#

Return the initial seed \(s\) used to initialize the random-number generator and also the current step \(c\). This is the complement to the SetSeed function.

Random(S): Str -> Elt#

Given a finite set or structure \(S\), return a random element of \(S\).

Random(a, b): RngIntElt, RngIntElt -> RngIntElt#

Return a random integer lying in the interval \([a, b]\), where \(a\leq b\).

Random(b): RngIntElt -> RngIntElt#

Return a random integer lying in the interval \([0, b]\), where \(b\) is a non-negative integer. Because of the good properties of the underlying Monster generator, calling Random(1) is a good safe way to produce a sequence of random bits.

Example: Is Intrinsic (ex-a0e14a)#

We demonstrate how one can return to a previous random state by the use of GetSeed and SetSeed. We begin with initial seed 1 at step 0 and create a multi-set of 100,000 random integers in the range \([1..4]\).

> SetSeed(1);
> GetSeed();
1 0
> time S := {* Random(1, 4): i in [1..100000] *};
Time: 0.490
> S;
{* 1^^24911, 2^^24893, 3^^25139, 4^^25057 *}

Run in calculator

We note the current state by GetSeed, and then print 10 random integers in the range \([1..100]\).

> GetSeed();
1 100000
> [Random(1, 100): i in [1 .. 10]];
[ 85, 41, 43, 69, 66, 61, 63, 31, 84, 11 ]
> GetSeed();
1 100014

Run in calculator

We now restart with a different initial seed 23 (again at step 0), and do the same as before, noting the different random integers produced.

> SetSeed(23);
> GetSeed();
23 0
> time S := {* Random(1, 4): i in [1..100000] *};
Time: 0.500
> S;
{* 1^^24962, 2^^24923, 3^^24948, 4^^25167 *}
> GetSeed();
23 100000
> [Random(1, 100): i in [1 .. 10]];
[ 3, 93, 11, 62, 6, 73, 46, 52, 100, 30 ]
> GetSeed();
23 100013

Run in calculator

Finally, we restore the random generator state to what it was after the creation of the multi-set for the first seed. We then print the 10 random integers in the range \([1..100]\), and note that they are the same as before.

> SetSeed(1, 100000);
> [Random(1, 100): i in [1 .. 10]];
[ 85, 41, 43, 69, 66, 61, 63, 31, 84, 11 ]
> GetSeed();
1 100014

Run in calculator