next up previous contents index
Next: 5.2.2 Quelques petites applications Up: Génération de nombres aléatoires Previous: Génération de nombres aléatoires

5.2.1 La fonction rand

Jusqu'à présent elle nous a essentiellement servi à remplir nos matrices et vecteurs... Cette fonction utilise le générateur congruentiel linéaire suivant[*]   :

\begin{displaymath}
X_{n+1} = f(X_n) = (a X_n + c) \mbox{ mod } m, \; n \ge 0, \...
 ...2^{31} \\  a = 843314861 \\  
 c = 453816693\end{array} \right.\end{displaymath}

Sa période est bien sûr égale à m (ceci signifie que f est une permutation cyclique sur [0,m-1].) Notons que tous les générateurs de nombres aléatoires sur ordinateur sont des suites parfaitement déterministes qui << apparaissent >> comme aléatoires (pour les bons générateurs) selon un certain nombre de tests statistiques. Pour se ramener à des nombres réels compris dans l'intervalle [0,1[, on divise les entiers obtenus par m (et l'on obtient un générateur de nombres réels qui semblent suivre une loi uniforme sur [0,1[). Le terme initial de la suite est souvent appelé le germe et celui par défaut est X0 = 0. Ainsi le premier appel à rand (le premier coefficient obtenu si on récupère une matrice ou un vecteur) est toujours :

\begin{displaymath}
u_1 = 453816693 / 2^{31} \approx 0.2113249\end{displaymath}

Il est cependant possible de changer le germe à tout moment avec l'instruction :
  rand("seed",germe)
où germe est un entier compris dans l'intervalle (entier) [0,m-1]. Souvent on ressent le besoin d'initialiser la suite en choisissant un germe plus ou moins au hasard (histoire de ne pas avoir les mêmes nombres à chaque fois) et une possibilité consiste à récuperer la date et l'heure et de fabriquer le germe avec. Scilab possède une fonction getdate qui fournit un vecteur de 9 entiers (voir le détail avec le Help). Parmi ces 9 entiers : Pour obtenir un germe je multiplie ces nombres entre eux[*] (en leur ajoutant 1 au préalable pour éviter d'obtenir le germe 0 au moins une fois sur 60...) et je multiplie le résultat obtenu par 57 de sorte que $13 \times 32 \times 24 \times 60 \times 62 \times 57 \approx 2^{31}$ce qui donne :
  v = getdate()
  rand("seed", 57*prod(1+v([2 6 7 8 9])))
Noter aussi que l'on peut récupérer le germe courant avec :
  germe = rand("seed")
À partir de la loi uniforme sur [0,1[, on peut obtenir d'autres lois et rand fournit aussi une interface qui permet d'obtenir la loi normale (de moyenne 0 et de variance 1). Pour passer de l'une à l'autre, on procède de la façon suivante :
   rand("normal")  // pour obtenir la loi normale
   rand("uniform") // pour revenir a la loi uniforme
Par défaut le générateur fournit une loi uniforme mais il est judicieux dans toute simulation de s'assurer que rand donne bien ce que l'on désire en utilisant l'une de ces deux instructions. On peut d'ailleurs récupérer la loi actuelle avec :
   loi=rand("info")  // loi est l'une des deux chaînes "uniform" ou "normal"
Rappelons que rand peut s'utiliser de plusieurs façons :
1.
A = rand(n,m) remplit la matrice A (n,m) de nombres aléatoires ;
2.
si B est une matrice déjà définie de dimensions (n,m) alors A = rand(B) permet d'obtenir la même chose (ce qui permet d'éviter de récupérer les dimensions de B) ;
3.
enfin, u = rand() fournit un seul nombre aléatoire.
Pour les deux premières méthodes, on peut rajouter un argument supplémentaire pour imposer aussi la loi : A = rand(n,m,loi), A = rand(B,loi), où loi est l'une des deux chaînes de caractères "normal" ou "uniform".


next up previous contents index
Next: 5.2.2 Quelques petites applications Up: Génération de nombres aléatoires Previous: Génération de nombres aléatoires
Pincon Bruno
6/23/2000