## 7.1 Random Numbers

“The generation of random numbers is too important to be left to chance.”

### 7.1.1 Random Numbers

Random numbers are extremely important! For example, random numbers are routinely used to encrypt information on the internet. Random numbers are also heavily used in science for various simulations E.g. the path of an ion through a material and analysisE.g. Monte Carlo integration .

### 7.1.2 RNG vs PRNG

To simulate a random process, we need to use a random number generator (RNG). We can implement a RNG on a computer using various algorithms. Because these RNG are based on a deterministic algorithms one can argue that these RNG are not truly random. So we call them pseudo RNG (PRNG).

One of the concerns with older PRNG was that the algorithms eventually cycle over and start repeating previously generated numbers. However, modern PRNG algorithms are so sophisticated that it takes (for a PRNG called the Mersenne Twister) about $$10^{19937} − 1$$ times before the numbers repeat. This is good enough for most simulations.

### 7.1.3 What is ‘seeding?’

Typical PRNG produce uniformly distributed numbers between 0 and 1. Every call to the PRNG gives a new number. The numbers produced by a PRNG is based on a number called the seed. This is an integer number that ‘kicks off,’ ‘seeds’ the algorithm. You get the same set of ‘random’ numbers if you use the same seedYou can set the seed in Numpy using the function numpy.random.seed() (a feature invaluable when debugging code).

You do not usually have to seed the PRNG. It does it automatically by using ‘some’ number (e.g. the number of milliseconds since January 1970) internally.

### 7.1.4 Using numpy for random numbers

You can generate random numbers using the PRNG of numpy as follows:

import numpy.random as rnd

print(rnd.random())
# 0.30354698431635574
print(rnd.random(5))
# [0.55547193 0.86340501 0.31335737 0.9685174  0.55230518]
print(rnd.random(5))
# [0.76679827 0.39252325 0.39324457 0.42426084 0.47626549]

If you like you can specify a seed.

rnd.seed(123)
print(rnd.random(5))
# [0.69646919 0.28613933 0.22685145 0.55131477 0.71946897]
rnd.seed(123)
print(rnd.random(5))
# [0.69646919 0.28613933 0.22685145 0.55131477 0.71946897]