Answers:
从正常模拟的分布,直到结果落在间隔内(一个,b )是细当概率 ρ = ∫ b 一个 φ μ ,σ 2(X ) 足够大。如果它太小,此过程是过于昂贵的,因为平的平均数目为一个接受是 1 / ρ。
如蒙特卡洛统计方法(第2章,示例2.2)以及我的arXiv文件中所述,一种模拟此截断正态的更有效方法是使用基于指数分布的接受拒绝方法。
不失一般性地考虑和σ = 1的情况。当b = + ∞,一个潜在的器乐分布是翻译的指数分布, È(α ,一),用密度 克α(ż )= α ë - α (ž - 一) 比值 p 一个,∞(Ž )/ 克α(ż )α ë - α (ž - 一个) ë - Ž 2 / 2 然后,通过有界 EXP (α 2 / 2 - α 一) 如果 α > 一个和由实验值(- 一个2 / 2 ) 以其它方式。相应的(上限)为
qnorm
在R循环中运行不是一个好主意。
从正态分布采样,但是在仿真之前忽略所有落在指定范围之外的随机值。
此方法是正确的,但是,正如@西安在他的回答中提到的那样,当范围较小时(更确切地说,在正态分布下其度量较小时)将花费很长时间。
:
a <- 1
b <- 5
nsims <- 10^5
sims <- tan(runif(nsims, atan(a), atan(b)))
Now one has to calculate the weight for each sampled value , defined as the ratio of the two densities up to normalization, hence we can take
log_w <- -sims^2/2 + log1p(sims^2)
w <- exp(log_w) # unnormalized weights
w <- w/sum(w)
The weighted sample allows to estimate the measure of every interval under the target distribution, by summing the weights of each sampled value falling inside the interval:
u <- 2; v<- 4
sum(w[sims>u & sims<v])
## [1] 0.1418
This provides an estimate of the target cumulative function.
We can quickly get and plot it with the spatsat
package:
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
Of course, the sample is definitely not a sample of the target distribution, but of the instrumental Cauchy distribution, and one gets a sample of the target distribution by performing weighted resampling, for instance using the multinomial sampling:
msample <- rmultinom(1, nsims, w)[,1]
resims <- rep(sims, times=msample)
hist(resims)
mean(resims>u & resims<v)
## [1] 0.1446
Olver and Townsend developed a sampling method for a broad class of continuous distribution. It is implemented in the chebfun2 library for Matlab as well as the ApproxFun library for Julia. I have recently discovered this library and it sounds very promising (not only for random sampling). Basically this is the inversion method but using powerful approximations of the cdf and the inverse cdf. The input is the target density function up to normalization.
The sample is simply generated by the following code:
using ApproxFun
f = Fun(x -> exp(-x.^2./2), [1,5]);
nsims = 10^5;
x = sample(f,nsims);
As checked below, it yields an estimated measure of the interval close to the one previously obtained by importance sampling:
sum((x.>2) & (x.<4))/nsims
## 0.14191