从自定义分布生成随机样本


16

我正在尝试使用R从自定义pdf生成随机样本。我的pdf是:

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

我生成了统一的样本,然后尝试将其转换为我的自定义发行版。我通过找到分布的cdf(FX(x))并将其设置为统一样本(u)并求解x

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

为了生成与上述分布的随机样本,得到均匀的样品和求解X3u[0,1]x

32(xx33)=u

我实现了它,R但没有得到预期的分布。谁能指出我的理解上的缺陷?

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
必须是编码错误。我不使用R,所以我无法说出确切的错误-但我只是对您的解决方案进行了编码(请注意三次多项式的中间根,该根始终在0到1之间),并且我在样本和预期的分布之间达成了良好的协议。您的寻根器可能有问题吗?您得到的样品怎么了?
jpillow 2011年

我尝试了您的代码(顺便说一句,效率不是很高),并且确实获得了预期的分发。
Aniko

@jpillow和@Aniko我的错。当我使用nsamples <- 1e6它的时候很合适。
阿南德(Anand

2
@Anand一种方式是观察到,允许直接计算X来讲üx=2sin(arcsin(u)/3)xu
ub

Answers:


11

看来您发现您的代码有效,但是@Aniko指出您可以提高其效率。最大的速度收益可能来自为分配内存,z这样就不会在循环内增加内存。这样的事情z <- rep(NA, nsamples)应该可以解决。通过使用vapply()(指定返回的变量类型)而不是使用显式循环(在apply系列中存在一个很大的SO问题),您可能会获得较小的速度增益。

> 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

而且您不需要;每行的末尾(您是MATLAB转换吗?)。


感谢您的详细回答和指出 vapply。我已经编码C/C++了很长时间了,这就是造成;痛苦的原因!
阿南德

1
uniroot107每秒变量就可以毫无问题。
ub
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.