Meine Frage ist inspiriert R ‚s built-in exponentiellem Zufallszahlengenerator, die Funktion rexp()
. Bei dem Versuch, exponentiell verteilte Zufallszahlen zu generieren, empfehlen viele Lehrbücher die inverse Transformationsmethode, wie auf dieser Wikipedia-Seite beschrieben . Mir ist bewusst, dass es andere Methoden gibt, um diese Aufgabe zu erfüllen. Insbesondere verwendet der Quellcode von R den Algorithmus, der in einem Artikel von Ahrens & Dieter (1972) beschrieben wurde .
Ich habe mich davon überzeugt, dass die Ahrens-Dieter (AD) -Methode richtig ist. Dennoch sehe ich keinen Vorteil in der Verwendung ihrer Methode im Vergleich zur inversen Transformationsmethode (IT). AD ist nicht nur komplexer zu implementieren als IT. Es scheint auch keinen Geschwindigkeitsvorteil zu geben. Hier ist mein R- Code zum Benchmarking beider Methoden, gefolgt von den Ergebnissen.
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)))
Ergebnisse:
[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
Beim Vergleich des Codes für die beiden Methoden zeichnet AD mindestens zwei einheitliche Zufallszahlen (mit der C- Funktion unif_rand()
), um eine exponentielle Zufallszahl zu erhalten. Die IT benötigt nur eine einheitliche Zufallszahl. Vermutlich hat sich das R- Kernteam gegen die Implementierung der IT entschieden, da davon ausgegangen wurde, dass der Logarithmus langsamer ist als die Generierung einheitlicherer Zufallszahlen. Ich verstehe, dass die Geschwindigkeit der Logarithmen maschinenabhängig sein kann, aber zumindest für mich ist das Gegenteil der Fall. Vielleicht gibt es Probleme mit der numerischen Genauigkeit der IT, die mit der Singularität des Logarithmus bei 0 zu tun haben? Aber dann der R-
Quellcode sexp.czeigt, dass die Implementierung von AD auch eine gewisse numerische Genauigkeit verliert, da der folgende Teil des C-Codes die führenden Bits aus der einheitlichen Zufallszahl u entfernt .
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 wird später im Rest von sexp.c als einheitliche Zufallszahl recycelt . Bisher scheint es so
- IT ist einfacher zu codieren,
- IT ist schneller und
- Sowohl IT als auch AD verlieren möglicherweise an numerischer Genauigkeit.
Ich würde mich sehr freuen, wenn jemand erklären könnte, warum R AD immer noch als einzige verfügbare Option für implementiert rexp()
.
quelle
rexp(n)
es zu einem Engpass kommen würde, ist der Geschwindigkeitsunterschied (zumindest für mich) kein starkes Argument für Veränderungen. Ich bin möglicherweise mehr besorgt über die numerische Genauigkeit, obwohl mir nicht klar ist, welche numerisch zuverlässiger wäre.Antworten:
Auf meinem Computer (entschuldigen Sie mein Französisch!):
Die inverse Transformation ist schlimmer. Sie sollten jedoch auf Variabilität achten. Die Einführung eines Ratenparameters führt zu einer noch größeren Variabilität der inversen Transformation:
Hier sind die Vergleiche mit
rbenchmark
:Der Kilometerstand variiert also immer noch, je nach Maßstab!
quelle
microbenchmark
stattdessen eine durchführen?rexp
-log(runif())
R
log
runif
Dies zitiert nur den Artikel im Abschnitt "Algorithmus LG: (Logarithmus-Methode)":
Es sieht also so aus, als hätten sich die Autoren für andere Methoden entschieden, um diese "Hersteller" -Einschränkung langsamer Logarithmen zu vermeiden. Vielleicht wird diese Frage dann am besten in den Stapelüberlauf verschoben, wo jemand mit Kenntnissen über die Eingeweide von R Kommentare abgeben kann.
quelle
Führen Sie dies einfach mit
microbenchmark
; Auf meiner Maschine ist Rs nativer Ansatz gleichmäßig schneller:quelle