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
import numpy as np
import matplotlib.pyplot as plt
# congruence en python avec %
10%3, 49 % 7
# afficher un histogramme normalise d'une liste de valeurs
values = np.random.rand(1000000)
_ = plt.hist(values, bins=20, density=True)
# somme cumulee d'un tableau numpy ou d'une liste
np.cumsum([1, 2, 3])
# les valeurs a, b et m prises de Scilab pour le generateur aleatoire
# par congurences
a, b, m = 843314861, 453816693, 2**31
# on definit la fonction de recurrence
def f_rec(x):
return (a*x + b) % m
# on choisit un x_0 comme on veut
x_0 = 674268427
f_rec(x_0)
# 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
# on verifie que la moyenne empirique est proche de 0.5
np.sum(valeurs_norm) / N
# 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')
# on affiche l'histogramme des valeurs pour verifier
# qu'il est a peu pres constant
_ = plt.hist(valeurs_norm, bins=20, density=True)