Ma question est inspirée du générateur exponentiel de nombres aléatoires intégré de R , la fonction rexp()
. Lorsque vous essayez de générer des nombres aléatoires distribués de façon exponentielle, de nombreux manuels recommandent la méthode de transformation inverse, comme indiqué dans cette page Wikipedia . Je suis conscient qu'il existe d'autres méthodes pour accomplir cette tâche. En particulier, le code source de R utilise l'algorithme décrit dans un article d'Ahrens & Dieter (1972) .
Je me suis convaincu que la méthode Ahrens-Dieter (AD) est correcte. Pourtant, je ne vois pas l'avantage d'utiliser leur méthode par rapport à la méthode de transformation inverse (IT). AD n'est pas seulement plus complexe à mettre en œuvre que l'informatique. Il ne semble pas non plus y avoir de gain de vitesse. Voici mon code R pour comparer les deux méthodes suivies des résultats.
invTrans <- function(n)
-log(runif(n))
print("For the inverse transform:")
print(system.time(invTrans(1e8)))
print("For the Ahrens-Dieter algorithm:")
print(system.time(rexp(1e8)))
Résultats:
[1] "For the inverse transform:"
user system elapsed
4.227 0.266 4.597
[1] "For the Ahrens-Dieter algorithm:"
user system elapsed
4.919 0.265 5.213
En comparant le code pour les deux méthodes, AD dessine au moins deux nombres aléatoires uniformes (avec la fonction Cunif_rand()
) pour obtenir un nombre aléatoire exponentiel. Le service informatique n'a besoin que d'un nombre aléatoire uniforme. On peut supposer que l' équipe principale R a décidé de ne pas mettre en œuvre l'informatique, car elle a supposé que la prise du logarithme peut être plus lente que la génération de nombres aléatoires plus uniformes. Je comprends que la vitesse de prise des logarithmes peut être dépendante de la machine, mais au moins pour moi, le contraire est vrai. Peut-être y a-t-il des problèmes de précision numérique de l'informatique liés à la singularité du logarithme à 0? Mais alors, le
code source R sexp.crévèle que la mise en œuvre de AD perd également une certaine précision numérique car la partie suivante du code C supprime les bits de tête du nombre aléatoire uniforme u .
double u = unif_rand();
while(u <= 0. || u >= 1.) u = unif_rand();
for (;;) {
u += u;
if (u > 1.)
break;
a += q[0];
}
u -= 1.;
u est ensuite recyclé comme un nombre aléatoire uniforme dans la suite de sexp.c . Jusqu'à présent, il semble que
- IL est plus facile de coder,
- L'informatique est plus rapide et
- IT et AD perdent probablement la précision numérique.
J'apprécierais vraiment si quelqu'un pouvait expliquer pourquoi R implémente toujours AD comme seule option disponible pour rexp()
.
rexp(n)
serait le goulot d'étranglement, la différence de vitesse n'est pas un argument solide pour le changement (du moins pour moi). Je pourrais être plus préoccupé par la précision numérique, bien qu'il ne soit pas clair pour moi lequel serait le plus fiable numériquement.