Generating Random Numbers/fr

From Free Pascal wiki
Jump to: navigation, search

Deutsch (de) English (en) suomi (fi) français (fr)

fpc source logo.png

(Ndt : quelques réserves sur la traduction, n'étant pas spécialiste)

Les nombres aléatoires sont une importante ressource pour les applications scientifiques, l'éducation, le développement de jeu et la visualisation. Ils jouent un rôle clé dans la simulation scientifique.

les nombres aléatoires générés par des algorithmes sont des nombres pseudo-aléatoires. Ils appartiennent à un (large) ensemble de nombres répétitifs, en une suite qui est impossible ou au moins difficilement prédictible. Contrairement à Delphi, Free Pascal utilise un algorithme MersenneTwister pour sa fonction standard random comme définie dans la RTL. Avant sa première utilisation, le générateur de nombres aléatoires doit être initialisé avec un simple appel à la fonction randomize, laquelle mets la graine du générateur. De préférence, cela est fait à la phase de lancement du programme.

Alternativement, dans les systèmes basés sur Linux et Unix, les périphériques virtuels /dev/random et /dev/urandom sont disponibles. Ils générent des nombres (pseudo) aléatoires basés sur le matériel.

Une troisième option est d'utiliser des nombres aléatoires depuis une source externe, comme des périphériques spécialisés ou depuis des sources publiques, p.ex. basées sur des données de désintégration nucléaire.

Loi uniforme

La loi uniforme (aussi appelée loi rectangulaire) représente une famille de loi de probabilité symétriques. Là, pour chaque membre de la famille, tous les intervalles de même longueur sur le support de la loi sont également probable.

La fonction standard RTL random génère des nombres aléatoires qui remplissent une loi uniforme. Si appelée sans paramètre, random délivre un nombre flottant pseudo-aléatoire dans l'intervalle [0,1[ (i.e. 0 <= result < 1). Si random est appelée avec un argument Longint L, elle délivre un Longint aléatoire dans l'intervalle [0, L[. Pour créer des nombres aléatoires, d'autres algorithmes de loi spéciales sont nécessaires.

Loi Normale (gaussienne)

Un des algorithmes les plus courants pour produire des nombres aléatoires normalement distribués depuis des nombres aléatoires uniformément distribués est l'approche de Box-Müller. La fonction suivante calcule des nombres aléatoires selon une distribution gaussienne :

 function rnorm (mean, sd: real): real;
 {Calculates Gaussian random numbers according to the Box-Müller approach}
  var
   u1, u2: real;
 begin
   u1 := random;
   u2 := random;
   rnorm := mean * abs(1 + sqrt(-2 * (ln(u1))) * cos(2 * pi * u2) * sd);
  end;

Le même algorithme est utilisé par la fonction randg de l'unité RTL math :

function randg(mean,stddev: float): float;

Loi Exponentielle

Une loi exponentielle se rencontre souvent dans les problèmes du monde réel. Un exemple classique est la distribution des temps d'attente entre des événements Poisson-aléatoire indépendants, p.ex. la désintégration radioactive des noyaux [Press et al. 1989].

La fonction suivante délivre un nombre aléatoire en réel à partir de la loi exponentielle. Rate est l'inverse de la moyenne, et la constante RESOLUTION détermine la granularité des nombres aléatoires générés.

function randomExp(a, rate: real): real;
const
  RESOLUTION = 1000;
var
  unif: real;
begin
  if rate = 0 then
    randomExp := NaN
  else
  begin
    repeat
      unif := random(RESOLUTION) / RESOLUTION;
    until unif <> 0;
    randomExp := a - rate * ln(unif);
  end;
end;

Loi Gamma

La loi gamma est une famille à deux paramètres de distributions aléatoires continues. C'est une généralisation à la fois de la loi exponentielle et de la loi d'Erlang. Les applications possibles de la loi gamma incluent la modélisation et la simulation des files d'attente et la science actuarielle.

La fonction suivante délivre un nombre aléatoire réel à partir d'une gamma. La structure de la distribution est définie par les paramètres a, b et c. La fonction fait usage de la fonction randomExp définie ci-dessus.

function randomGamma(a, b, c: real): real;
const
  RESOLUTION = 1000;
  T = 4.5;
  D = 1 + ln(T);
var
  unif: real;
  A2, B2, C2, Q, p, y: real;
  p1, p2, v, w, z: real;
  found: boolean;
begin
  A2 := 1 / sqrt(2 * c - 1);
  B2 := c - ln(4);
  Q := c + 1 / A2;
  C2 := 1 + c / exp(1);
  found := False;
  if c < 1 then
  begin
    repeat
      repeat
        unif := random(RESOLUTION) / RESOLUTION;
      until unif > 0;
      p := C2 * unif;
      if p > 1 then
      begin
        repeat
          unif := random(RESOLUTION) / RESOLUTION;
        until unif > 0;
        y := -ln((C2 - p) / c);
        if unif <= power(y, c - 1) then
        begin
          randomGamma := a + b * y;
          found := True;
        end;
      end
      else
      begin
        y := power(p, 1 / c);
        if unif <= exp(-y) then
        begin
          randomGamma := a + b * y;
          found := True;
        end;
      end;
    until found;
  end
  else if c = 1 then
    { Gamma distribution becomes exponential distribution, if c = 1 }
  begin
    randomGamma := randomExp(a, b);
  end
  else
  begin
    repeat
      repeat
        p1 := random(RESOLUTION) / RESOLUTION;
      until p1 > 0;
      repeat
        p2 := random(RESOLUTION) / RESOLUTION;
      until p2 > 0;
      v := A2 * ln(p1 / (1 - p1));
      y := c * exp(v);
      z := p1 * p1 * p2;
      w := B2 + Q * v - y;
      if (w + D - T * z >= 0) or (w >= ln(z)) then
      begin
        randomGamma := a + b * y;
        found := True;
      end;
    until found;
  end;
end;

Loi d'Erlang

La loi d'Erlang est une famille à deux paramètres de distributions de probabilité continues. C'est une généralisation de la loi exponentielle et un cas particulier de la loi gamma, où c est un entier. L loi d'Erlang La loi d'Erlang a été décrite d'abord par Agner Krarup Erlang en vue de modéliser le délai entre des appels téléphoniques. Elle est utilisée dans la théorie des files d'attente et pour simuler les files d'attente.

  function randomErlang(mean: real; k: integer): real;
  const
    RESOLUTION = 1000;
  var
    i: integer;
    unif, prod: real;
  begin
    if (mean <= 0) or (k < 1) then
      randomErlang := NaN
    else
    begin
      prod := 1;
      for i := 1 to k do
      begin
        repeat
          unif := random(RESOLUTION) / RESOLUTION;
        until unif <> 0;
        prod := prod * unif;
      end;
      randomErlang := -mean * ln(prod);
    end;
  end;

Loi de Poisson

La loi de Poisson s'applique aux valeurs entières. Elle représente la probabilité de k succès, quand la probabilité de réussite à chaque essai est petite et le taux d'occurrences (la valeur mpoyenne) est constant.

function randomPoisson(mean: integer): integer;
{ Generator for Poisson distribution (Donald Knuth's algorithm) }
const
  RESOLUTION = 1000;
var
  k: integer;
  b, l: real;
begin
  assert(mean > 0, 'mean < 1');
  k := 0;
  b := 1;
  l := exp(-mean);
  while b > l do
  begin
    k := k + 1;
    b := b * random(RESOLUTION) / RESOLUTION;
  end;
  randomPoisson := k - 1;
end;

Loi t

La loi t (également appelée loi t de Student, puisqu'elle a été publiée par William Sealy Gosset en 1908 sous le pseudonyme Student) est une loi de probabilité continue. Sa structure est définie par un paramètre, le degré de liberté (df). En statistiques, plusieurs estimateurs sont t-distribués. Donc, la loi t de Student joue un rôle majeur dans nombre d'analyses statistiques largement utilisées, incluant le t-test de Student pour évaluer l'importance statistique de la différence entre deux moyennes d'échantillonnage, la construction d'intervalle de confiance pour la différence entre deux moyennes de population et dans les analyses de régression linéaire. La loi t surgit aussi dans l'analyse de donnée bayésienne d'une famille normale.

L'algorithme suivant dépend de la fonction random de la RTL et de la fonction randomChisq.

function randomT(df: integer): real;
{ Generator for Student's t distribution }
begin
  if df < 1 then randomT := NaN
  else
  begin
    randomT := randg(0, 1) / sqrt(randomChisq(df) / df);
  end;
end;

Loi Chi carré

La loi Chi carré est une loi continue de nombres aléatoires avec df degrés de liberté. C'est la loi de la somme des carrés de df variables aléatoires normal standard indépendantes. La loi Chi carré a de nombreuses applications en statistiques inférentielles, p.ex. dans l'estimation de la variance et pour les tests chi-carré. C'est une loi gamma spéciale avec c = df/ 2 et b = 2. Donc, la fonction suivante dépend de la fonction randomGamma.

function randomChisq(df: integer): real;
begin
  if df < 1 then randomChisq := NaN
  else
  randomChisq := randomGamma(0, 2, 0.5 * df);
end;

Loi F

La loi F, appelée aussi loi Fisher-Snedecor, est un loi de probabilité continue. Elle est utilisée pour le test F et l'ANOVA. Elle a deux degrés de liberté qui serve de paramètre de structure v et w qui sont des entiers positifs. La fonction suivante randomF fait usage de randomChisq.

function randomF(v, w: integer): real;
begin
  if (v < 1) or (w < 1) then
    randomF := NaN
  else
  randomF := randomChisq(v) / v / (randomChisq(w) / w);
end;

Voir aussi

Références

(non traduit...)

  1. G. E. P. Box and Mervin E. Muller, A Note on the Generation of Random Normal Deviates, The Annals of Mathematical Statistics (1958), Vol. 29, No. 2 pp. 610–611
  2. Dietrich, J. W. (2002). Der Hypophysen-Schilddrüsen-Regelkreis. Berlin, Germany: Logos-Verlag Berlin. ISBN 978-3-89722-850-4. OCLC 50451543.
  3. Press, W. H., B. P. Flannery, S. A. Teukolsky, W. T. Vetterling (1989). Numerical Recipes in Pascal. The Art of Scientific Computing, Cambridge University Press, ISBN 0-521-37516-9.
  4. Richard Saucier, Computer Generation of Statistical Distributions, ARL-TR-2168, US Army Research Laboratory, Aberdeen Proving Ground, MD, 21005-5068, March 2000.
  5. R.U. Seydel, Generating Random Numbers with Specified Distributions. In: Tools for Computational Finance, Universitext, DOI 10.1007/978-1-4471-2993-6_2, © Springer-Verlag London Limited 2012
  6. Christian Walck, Hand-book on STATISTICAL DISTRIBUTIONS for experimentalists, Internal Report SUF–PFY/96–01, University of Stockholm 2007