Pertanyaan saya terinspirasi oleh generator nomor acak eksponensial bawaan R , fungsinya rexp()
. Ketika mencoba untuk menghasilkan angka acak yang didistribusikan secara eksponensial, banyak buku teks merekomendasikan metode transformasi terbalik seperti yang diuraikan dalam halaman Wikipedia ini . Saya sadar bahwa ada metode lain untuk menyelesaikan tugas ini. Secara khusus, kode sumber R menggunakan algoritma yang digariskan dalam sebuah makalah oleh Ahrens & Dieter (1972) .
Saya telah meyakinkan diri saya sendiri bahwa metode Ahrens-Dieter (AD) benar. Namun, saya tidak melihat manfaat dari menggunakan metode mereka dibandingkan dengan metode inverse transform (IT). AD tidak hanya lebih kompleks untuk diterapkan daripada IT. Sepertinya tidak ada manfaat kecepatan juga. Berikut adalah kode R saya untuk membandingkan kedua metode yang diikuti oleh hasilnya.
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)))
Hasil:
[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
Membandingkan kode untuk dua metode, AD menggambar setidaknya dua angka acak seragam (dengan fungsi Cunif_rand()
) untuk mendapatkan satu nomor acak eksponensial. TI hanya membutuhkan satu nomor acak yang seragam. Agaknya tim inti R memutuskan untuk tidak mengimplementasikan TI karena diasumsikan bahwa mengambil logaritma mungkin lebih lambat daripada menghasilkan angka acak yang lebih seragam. Saya mengerti bahwa kecepatan mengambil logaritma dapat bergantung pada mesin, tetapi setidaknya bagi saya yang sebaliknya adalah benar. Mungkin ada masalah di sekitar ketepatan numerik IT yang berkaitan dengan singularitas logaritma pada 0? Tapi kemudian,
kode sumber R sexp.cmengungkapkan bahwa implementasi AD juga kehilangan beberapa ketepatan numerik karena bagian berikut dari kode C menghilangkan bit-bit utama dari nomor acak seragam 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 kemudian didaur ulang sebagai nomor acak seragam dalam sisa sexp.c . Sejauh ini, tampak seolah-olah
- IT lebih mudah untuk dikodekan,
- TI lebih cepat, dan
- IT dan AD mungkin kehilangan akurasi numerik.
Saya akan sangat menghargai jika seseorang dapat menjelaskan mengapa R masih mengimplementasikan AD sebagai satu-satunya pilihan yang tersedia untuk rexp()
.
rexp(n)
akan menjadi hambatan, perbedaan dalam kecepatan bukanlah argumen yang kuat untuk perubahan (setidaknya bagi saya). Saya mungkin lebih peduli tentang akurasi numerik, meskipun tidak jelas bagi saya yang mana yang lebih dapat diandalkan secara numerik.