Sampel dari distribusi Normal tetapi abaikan semua nilai acak yang berada di luar rentang yang ditentukan sebelum simulasi.
Metode ini benar, tetapi, seperti yang disebutkan oleh @ Xi'an dalam jawabannya, akan membutuhkan waktu yang lama ketika kisarannya kecil (lebih tepatnya, ketika ukurannya kecil di bawah distribusi normal).
F−1(U)FU∼Unif(0,1)FG(a,b)G−1(U)U∼Unif(G(a),G(b))
G−1G−1GG−1abG
Simulasikan distribusi terpotong dengan menggunakan sampling penting
N(0,1)GGG(q)=arctan(q)π+12G−1(q)=tan(π(q−12))
U∼Unif(G(a),G(b))G−1(U)tan(U′)U′∼Unif(arctan(a),arctan(b))
a <- 1
b <- 5
nsims <- 10^5
sims <- tan(runif(nsims, atan(a), atan(b)))
xiϕ(x)/g(x)
w(x)=exp(−x2/2)(1+x2),
log_w <- -sims^2/2 + log1p(sims^2)
w <- exp(log_w) # unnormalized weights
w <- w/sum(w)
(xi,w(xi))[u,v]
u <- 2; v<- 4
sum(w[sims>u & sims<v])
## [1] 0.1418
Ini memberikan perkiraan fungsi kumulatif target. Kami dapat dengan cepat mendapatkan dan merencanakannya dengan spatsat
paket:
F <- spatstat::ewcdf(sims,w)
# estimated F:
curve(F(x), from=a-0.1, to=b+0.1)
# true F:
curve((pnorm(x)-pnorm(a))/(pnorm(b)-pnorm(a)), add=TRUE, col="red")
# approximate probability of u<x<v:
F(v)-F(u)
## [1] 0.1418
(xi)
msample <- rmultinom(1, nsims, w)[,1]
resims <- rep(sims, times=msample)
hist(resims)
mean(resims>u & resims<v)
## [1] 0.1446
Metode lain: pengambilan sampel transformasi invers cepat
Olver dan Townsend mengembangkan metode pengambilan sampel untuk kelas luas distribusi berkelanjutan. Ini diimplementasikan di perpustakaan chebfun2 untuk Matlab serta perpustakaan ApproxFun untuk Julia . Baru-baru ini saya menemukan perpustakaan ini dan kedengarannya sangat menjanjikan (tidak hanya untuk pengambilan sampel acak). Pada dasarnya ini adalah metode inversi tetapi menggunakan perkiraan kuat dari cdf dan invers cdf. Input adalah fungsi kepadatan target hingga normalisasi.
Sampel hanya dihasilkan oleh kode berikut:
using ApproxFun
f = Fun(x -> exp(-x.^2./2), [1,5]);
nsims = 10^5;
x = sample(f,nsims);
[2,4]
sum((x.>2) & (x.<4))/nsims
## 0.14191