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()
.
la source
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.Réponses:
Sur mon ordinateur (pardonnez mon français!):
la transformée inverse fait pire. Mais vous devez faire attention à la variabilité. L'introduction d'un paramètre de taux entraîne encore plus de variabilité pour la transformée inverse:
Voici les comparaisons utilisant
rbenchmark
:Le kilométrage varie donc toujours selon l'échelle!
la source
microbenchmark
place?rexp
, 3% temps utilisateur plus court-log(runif())
et aucune variabilité avec un paramètre de débit ( secondes au total). Nous supposons tous implicitement que les délais et les résultats sont comparables à ceux que l'on obtiendrait avec un sous-programme Fortran.R
log
runif
Ceci ne fait que citer l'article dans la section "Algorithme LG: (méthode du logarithme)":
Il semble donc que les auteurs aient opté pour d'autres méthodes pour éviter cette limitation «constructeur» des logarithmes lents. Peut-être que cette question est alors mieux déplacée vers stackoverflow où quelqu'un ayant des connaissances sur les tripes de R peut commenter.
la source
Il suffit de lancer cela avec
microbenchmark
; sur ma machine, l'approche native de R est uniformément plus rapide:Par souci de nouveauté, assurez-vous que ce n'est pas entièrement dû à la présence de :λ=1
la source