Cours 2

Implementer un generateur pseudo aleatoire a base de congruences, verifier empiriquement que la moyenne des valeurs converge vers 0.5 et que l'histogramme converge vers la densite uniforme

In [1]:
import numpy as np
import matplotlib.pyplot as plt
In [2]:
# congruence en python avec %
10%3, 49 % 7
Out[2]:
(1, 0)
In [3]:
# afficher un histogramme normalise d'une liste de valeurs
values = np.random.rand(1000000)
_ = plt.hist(values, bins=20, density=True)
In [4]:
# somme cumulee d'un tableau numpy ou d'une liste
np.cumsum([1, 2, 3])
Out[4]:
array([1, 3, 6])
In [5]:
# les valeurs a, b et m prises de Scilab pour le generateur aleatoire
# par congurences
a, b, m = 843314861, 453816693, 2**31
In [6]:
# on definit la fonction de recurrence
def f_rec(x):
    return (a*x + b) % m
In [7]:
# on choisit un x_0 comme on veut
x_0 = 674268427
f_rec(x_0)
Out[7]:
1536175076
In [8]:
# partant de x_0 on calcul N valeurs pseudo aleatoire en appliquant N
# fois la fonction de recurrence
N = 1000000
valeurs = np.zeros(N, dtype='int64')
valeurs[0] = x_0
for i in range(1, N):
    valeurs[i] = f_rec(valeurs[i-1])
valeurs_norm = valeurs / m
valeurs_norm
Out[8]:
array([0.3139807 , 0.71533726, 0.08067161, ..., 0.89839037, 0.35214126,
       0.69078737])
In [9]:
# on verifie que la moyenne empirique est proche de 0.5
np.sum(valeurs_norm) / N
Out[9]:
0.49989783066900073
In [10]:
# on affiche la convergence de la moyenne empirique de n termes
# en fonction de n
_ = plt.plot(np.arange(N), np.cumsum(valeurs_norm)/np.arange(1, N+1))
plt.title('Convergence de la moyenne empirique en fonciton de n')
Out[10]:
Text(0.5, 1.0, 'Convergence de la moyenne empirique en fonciton de n')
In [11]:
# on affiche l'histogramme des valeurs pour verifier
# qu'il est a peu pres constant
_ = plt.hist(valeurs_norm, bins=20, density=True)