Tạo mẫu ngẫu nhiên từ một phân phối tùy chỉnh


16

Tôi đang cố gắng tạo các mẫu ngẫu nhiên từ pdf tùy chỉnh bằng R. pdf của tôi là:

fX(x)= =32(1-x2),0x1

Tôi đã tạo các mẫu thống nhất và sau đó cố gắng chuyển đổi nó sang phân phối tùy chỉnh của mình. Tôi đã làm điều này bằng cách tìm cdf phân phối của tôi ( FX(x) ) và đặt nó vào mẫu thống nhất ( bạn ) và giải cho x .

FX(x)= =Pr[Xx]= =0x32(1-y2)dy= =32(x-x33)

Để tạo một mẫu ngẫu nhiên với phân phối trên, hãy lấy một mẫu thống nhất và giải cho trongbạn[0,1]x

32(x-x33)= =bạn

Tôi đã thực hiện nó Rvà tôi không nhận được phân phối dự kiến. Bất cứ ai có thể chỉ ra lỗ hổng trong sự hiểu biết của tôi?

nsamples <- 1000;
x <- runif(nsamples);

f <- function(x, u) { 
  return(3/2*(x-x^3/3) - u);
}

z <- c();
for (i in 1:nsamples) {
  # find the root within (0,1) 
  r <- uniroot(f, c(0,1), tol = 0.0001, u = x[i])$root;
  z <- c(z, r);
}

1
Phải là một lỗi mã hóa. Tôi không sử dụng R, vì vậy tôi không thể nói chính xác lỗi là gì - nhưng tôi chỉ mã hóa giải pháp của bạn (chú ý lấy gốc giữa của đa thức bậc ba, luôn nằm trong khoảng từ 0 đến 1) và Tôi nhận được thỏa thuận tốt giữa các mẫu và phân phối dự kiến. Nó có thể là một vấn đề với công cụ tìm root của bạn? Có gì sai với các mẫu bạn đang nhận được?
jpvel

Tôi đã thử mã của bạn (không hiệu quả lắm, nhân tiện) và nhận được phân phối dự kiến.
Aniko

@jpvel và @Aniko Sai lầm của tôi. Khi tôi sử dụng nsamples <- 1e6nó là một trận đấu tốt.
Anand

2
@Anand Một cách là quan sát rằng , cho phép tính trực tiếp theo . x ux= =2tội(arcsin(bạn)/3)xbạn
whuber

Câu trả lời:


11

Có vẻ như bạn đã tìm ra rằng mã của bạn hoạt động, nhưng @Aniko chỉ ra rằng bạn có thể cải thiện hiệu quả của nó. Tốc độ tăng tốc lớn nhất của bạn có thể đến từ bộ nhớ cấp phát trước zđể bạn không phát triển nó trong vòng lặp. Một cái gì đó như z <- rep(NA, nsamples)nên làm các thủ thuật. Bạn có thể nhận được một mức tăng tốc độ nhỏ từ việc sử dụng vapply()(chỉ định loại biến được trả về) thay vì một vòng lặp rõ ràng (có một câu hỏi SO tuyệt vời về họ áp dụng).

> nsamples <- 1E5
> x <- runif(nsamples)
> f <- function(x, u) 1.5 * (x - (x^3) / 3) - u
> z <- c()
> 
> # original version
> system.time({
+ for (i in 1:nsamples) {
+   # find the root within (0,1) 
+   r <- uniroot(f, c(0,1), tol = 0.0001, u = x[i])$root
+   z <- c(z, r)
+ }
+ })
   user  system elapsed 
  49.88    0.00   50.54 
> 
> # original version with pre-allocation
> z.pre <- rep(NA, nsamples)
> system.time({
+ for (i in 1:nsamples) {
+   # find the root within (0,1) 
+   z.pre[i] <- uniroot(f, c(0,1), tol = 0.0001, u = x[i])$root
+   }
+ })
   user  system elapsed 
   7.55    0.01    7.78 
> 
> 
> 
> # my version with sapply
> my.uniroot <- function(x) uniroot(f, c(0, 1), tol = 0.0001, u = x)$root
> system.time({
+   r <- vapply(x, my.uniroot, numeric(1))
+ })
   user  system elapsed 
   6.61    0.02    6.74 
> 
> # same results
> head(z)
[1] 0.7803198 0.2860108 0.5153724 0.2479611 0.3451658 0.4682738
> head(z.pre)
[1] 0.7803198 0.2860108 0.5153724 0.2479611 0.3451658 0.4682738
> head(r)
[1] 0.7803198 0.2860108 0.5153724 0.2479611 0.3451658 0.4682738

Và bạn không cần ;ở cuối mỗi dòng (bạn có phải là người chuyển đổi MATLAB không?).


Cảm ơn câu trả lời chi tiết của bạn và đã chỉ ra vapply. Tôi đã mã hóa trong C/C++một thời gian rất dài và đó là lý do cho ;phiền não!
Anand

1
uniroot107
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.