TP 4 : Générateurs pseudo-aléatoires et applications Un générateur de nombres pseudo-aléatoires, pseudorandom number generator (PRNG) en anglais, est un algorithme qui génère une séquence de nombres présentant certaines propriétés du hasard. Cependant, les sorties d un tel générateur ne sont pas entièrement aléatoires ; elles s approchent seulement des propriétés idéales des sources complètement aléatoires. John von Neumann insista sur ce fait avec la remarque suivante : Quiconque considère des méthodes arithmétiques pour produire des nombres aléatoires est, bien sûr, en train de commettre un péché. De vrais nombres aléatoires peuvent être produits avec du matériel qui tire parti de certaines propriétés physiques. L objectif de ce TP est d introduire les principales méthodes de génération de nombre pseudoaléatoires. Elles seront appliquées dans le cadre de méthodes de Monte-Carlo. 1 Générateurs à Congruences Linéaires (GCL) Ces générateurs produisent la suite de nombres (X n ) n 0 définis par la relation : pour n 0, X n+1 = (a X n + c) mod m, où m est un entier positif (le module), a, c et X 0 sont des entiers compris entre 0 et m respectivement appelés multiplicateur, incrément et graine (seed en anglais). La suite (X n ) ainsi définie est périodique à partir d un certain rang. Afin d obtenir un générateur aléatoire performant, il faudra donc commencer par avoir une période suffisamment longue. 1.1 Un premier cas : m = 2 n. Il est plus facile pour un ordinateur (qui gère les données en binaire) de calculer avec des modulo 2 n. C est pourquoi on se restreindra à ce cas dans cette sous-partie. Considérons le générateur suivant : le GCL avec m = 65536 = 2 16, a = 422, c = 987, X 0 = 641. Calculons la suite produite en utilisant les commandes suivantes : > a*641+c > 271489 %% m > a*9345 +c > 3944577 %% m > a*12417 +c > 5240961 %% m Il est indispensable de rejeter des générateurs ayant une période trop petite. On peut procéder de deux façons : trouver des conditions sur a et c qui assurent une période assez grande pour le GCL. déterminer la période du GCL choisi, et rejeter le générateur si la période est trop courte. Le théorème suivant donne une condition nécessaire et suffisante sur la période du GCL : Théorème 1.1 Dans le cas où m = 2 n, la période du GCL est maximale (vaut m) si et seulement si c est impair et a = 1 mod 4 Que pensez-vous de la période du générateur précédent? Déterminer et vérifier numériquement la période du GCL avec m = 4, a = 5, c = 7, X 0 = 15. 1
1.2 Cas plus général Dans cette sous-partie, le module n est plus nécessairement une puissance de 2. Nous avons le résultat suivant : Théorème 1.2 (Hull-Dobel 1962) Soit la suite (X n ) produite par l algorithme X n+1 = (a X n + c) mod m,. Alors le cycle maximal est de longueur m si et seulement si les trois hypothèses suivantes sont vérifiées : 1. PGCD(a, m) = 1, PGCD(c, m) = 1 ; 2. si un nombre premier p divise m, alors p divise a 1; 3. si 4 divise m, alors 4 divise a 1. Vérifier les conditions du théorème pour les valeurs a = 4, c = 2, m = 9, a = 2, c = 2, m = 9, a = 3, c = 3, m = 9, a = 1, c = 1, m = 9. Voici quelques générateurs : X n+1 = (7 5 X n ) mod 2 31 1, (générateur IBM) X n+1 = (427419669081 X n ) mod 999999999989, (générateur Maple 999999999989 est premier) dont les périodes respectives sont 2 30 = 1073741824 et 2 29 = 536870912. 1.3 Premiers tests de la pertinence de ces générateurs 1.3.1 Tests visuels pour la pertinence du générateur d IBM Le GCL précédemment étudié permet de générer des entiers entre 0 et m 1. Afin de se ramener à des réels compris entre 0 et 1, on étudie la suite U n = Xn. Le but de cette partie est d obtenir des m critères visuels de la proximité de la suite U n obtenue par le générateur d IBM avec des réalisations indépendantes de la loi uniforme sur [0,1]. Pour commencer, on pourra écrire la fonction suivante qui permet de générer la suite U n : randomgeneration=function(x0,a,c,m,n) #Cette fonction permet de generer les n premiers termes de la suite de nombres #pseudo-aleatoires issu de la definition X_{n+1}= a*x_n+c mod m. Cette suite de # nombres est divisee par m pour avoir des reels entre 0 et 1. #X0 est suppose etre entre 0 et m. { #debut de la fonction x=c() #initialisation de x 2
x[1]=x0 #initialisation de x for (i in 1:n) { #debut de la boucle for y=a*x[i]+c r=y %% m #calcul du modulo x[i+1]=r #affectation } #fin de la boucle for u=x/m #sortie de la fonction } #fin de la fonction On pourra utiliser ce script avec les valeurs de a, m et c du générateur d IBM pour obtenir une suite de n réels entre 0 et 1. On souhaite comparer la distribution de ces n nombres avec la distribution uniforme sur [0,1]. Pour cela, on peut produire les deux graphiques suivants : Comparaison de l histogramme des valeurs obtenues avec la densité de la loi uniforme sur [0,1]. > hist(u) > abline(h=1,col= red ) Tracer les fonctions de répartition empirique et théorique > plot(sort(u),1:1:length(u)/length(u)) > abline(0,1,col= blue ) Que pensez-vous de la qualité du générateur d IBM? On pourra faire varier la valeur de n. On pourra reproduire la même étude pour étudier la pertinence du générateur de nombre uniforme sur [0,1] de R. On obtiendra alors la suite de nombre pseudo-aléatoire par la commande: > ur=runif(n,0,1) 1.3.2 Comparaison des générateurs de nombres aléatoires de R et d IBM Par la sous-partie précédente, on sait obtenir deux échantillons de même taille de nombre pseudoaléatoires entre 0 et 1 : l un issu du générateur d IBM et l autre de la fonction runif de R. Que pouvez-vous dire des temps de calculs quand n = 100000? Dans ce paragraphe, on souhaite tester visuellement si ces deux échantillons suivent la même loi. Le scatter-plot des deux échantillons > plot(u,ur) semble-t-il indiquer une dépendance entre ces deux échantillons? Les points ainsi obtenus vous semblent-ils avoir été tirés uniformément dans le carré? Le QQ-plot (Quantile to Quantile) suivant indique-t-il que la distribution est la même? > plot(sort(u),sort(ur)) 3
1.3.3 Mise en évidence de l aspect déterministe Des tirages aléatoires successifs doivent être indépendants. Ce n est évidemment pas le cas pour les générateurs pseudo-aléatoires. Un générateur pseudo-aléatoire doit toujours être utilisé avec méfiance. Dans certains cas, on peut voir apparaître le déterminisme de l algorithme. Par exemple, soit le générateur aléatoire X n+1 = (11 X n + 1) mod 71. Ce générateur est de période 70 mais que se passe-t-il si pour choisir des points aléatoires dans le plan, on prend (X n+1,x n )? Comparer la figure obtenue avec celle pour le générateur X n+1 = (24298 X n + 99991) mod 199017. 2 Applications 2.1 Un premier pas vers les méthodes de Monte-Carlo En utilisant le générateur de nombres pseudo-aléatoire de votre choix, simuler un échantillon u de taille n de nombres uniformément tirés entre 0 et 1. Calculer les valeurs successives de la moyenne empirique des i premières valeurs pour i allant de 1 à n. représenter graphiquement ces valeurs en bleu et superposer sur le même graphique la droite horizontale d ordonnée 0.5 en rouge. On pourra utiliser les commandes suivantes: > moyennes=cumsum(u)/(1:100000) > plot(moyennes,pch=".",col="blue") > abline(h=0.5,col="red") Etudier le comportement de ce graphique lorsque n et la méthode de simulation de nombres aléatoires varient. 2.2 Un générateur particulier On considère le générateur suivant : X=0 Y=1 repeter X=X+1 et Y=Y/2 jusqu a runif(1,0,1)>y Return X Déterminer la loi de X. Simuler n réalisations indépendantes de X. On pourra le faire avec une condition while comme dans le script suivant: X=0 Y=1 while (runif(1,0,1) < Y) { X=X+1 Y=Y/2 4
} X Superposer les fréquences empiriques obseervées avec les probabilités théoriques données par la loi de X. (fonction table puis barplot). 5