Câu hỏi của tôi được lấy cảm hứng từ hàm tạo số ngẫu nhiên theo hàm mũ tích hợp của R , hàm rexp()
. Khi cố gắng tạo các số ngẫu nhiên phân tán theo cấp số nhân, nhiều sách giáo khoa khuyên dùng phương pháp biến đổi nghịch đảo như được nêu trong trang Wikipedia này . Tôi biết rằng có những phương pháp khác để hoàn thành nhiệm vụ này. Cụ thể, mã nguồn của R sử dụng thuật toán được phác thảo trong một bài báo của Ahrens & Dieter (1972) .
Tôi đã thuyết phục bản thân mình rằng phương pháp AhDR-Dieter (AD) là chính xác. Tuy nhiên, tôi không thấy lợi ích của việc sử dụng phương pháp của họ so với phương pháp biến đổi nghịch đảo (IT). AD không chỉ phức tạp để thực hiện hơn CNTT. Dường như cũng không có lợi ích về tốc độ. Đây là mã R của tôi để điểm chuẩn cả hai phương pháp theo sau là kết quả.
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)))
Các kết quả:
[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
So sánh mã cho hai phương thức, AD rút ra ít nhất hai số ngẫu nhiên đồng nhất (với hàm Cunif_rand()
) để có được một số ngẫu nhiên theo cấp số nhân. CNTT chỉ cần một số ngẫu nhiên thống nhất. Có lẽ nhóm lõi R đã quyết định chống lại việc triển khai CNTT vì họ cho rằng việc lấy logarit có thể chậm hơn so với việc tạo ra các số ngẫu nhiên thống nhất hơn. Tôi hiểu rằng tốc độ lấy logarit có thể phụ thuộc vào máy, nhưng ít nhất với tôi thì điều ngược lại là đúng. Có lẽ có những vấn đề xung quanh độ chính xác số của CNTT phải làm với điểm kỳ dị của logarit ở 0? Nhưng sau đó,
mã nguồn R sexp.ccho thấy việc thực hiện AD cũng làm mất một số độ chính xác bằng số vì phần sau của mã C sẽ loại bỏ các bit hàng đầu khỏi số ngẫu nhiên thống nhất 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 sau được tái chế như một số ngẫu nhiên thống nhất trong phần còn lại của sexp.c . Cho đến nay, nó xuất hiện như thể
- CNTT dễ mã hóa hơn,
- CNTT nhanh hơn, và
- cả CNTT và AD đều có thể mất độ chính xác về số.
Tôi thực sự sẽ đánh giá cao nếu ai đó có thể giải thích tại sao R vẫn thực hiện AD là lựa chọn khả dụng duy nhất cho rexp()
.
rexp(n)
sẽ là nút cổ chai, sự khác biệt về tốc độ không phải là một lý lẽ mạnh mẽ để thay đổi (ít nhất là với tôi). Tôi có thể quan tâm nhiều hơn về độ chính xác của số, mặc dù tôi không rõ cái nào đáng tin cậy hơn về mặt số.