递归地生成指数随机变量

时间:2014-11-27 14:02:47

标签: r recursion random exponential-distribution

我不熟悉R中的递归。我正在尝试生成满足R中某个条件的指数随机变量。这是一个简单的例子,显示我尝试生成两个独立的指数随机变量。

CODE

#### Function to generate two independent exponential random variable that meet two criteria
gen.exp<-function(q1,q2){
  a=rexp(1,q1)  # generate exponential random variable
  b=rexp(1,q2)  # generate exponential random variable
  if((a>10 & a<10.2) & (a+b>15)){ # criteria the random variables must meet
   return(c(a,b))
  }else{
   return(gen.exp(q1,q2)) #if above criteria is not met, repeat the process again
  } 

}

示例:q1 = .25,q2 = 2

     gen.exp(.25,2)

当我运行上面的代码时,我收到以下错误:

  1. 错误:评估嵌套太深:无限递归/选项(表达式=)?
  2. 汇总时出错:评估嵌套太深:无限递归/选项(表达式=)?
  3. 我已经尝试修改options(expressions=10000)并允许R增加迭代次数。这对我的情况似乎没有帮助(也许我没有正确使用该选项)。我理解生成具有严格标准的连续分布,如上所述可能是问题。话虽如此,无论如何都要避免错误?或者至少在发生错误时重复递归?这里的递归过度杀戮了吗?是否有更简单/更好的方法来生成所需的随机变量? 我很欣赏任何见解。

2 个答案:

答案 0 :(得分:4)

您正在使用具有两个条件的简单拒绝采样器

  • a > 10 & a < 10.2
  • a+ b > 15
然而,匹配它们的机会很低,即非常慢。但是,由于您对指数随机数感兴趣,我们可以避免模拟我们拒绝的数字。

要生成指数随机数,我们使用公式

-rate * log(U)

其中UU(0,1)随机数。因此,要从大于10的指数分布生成值(比方说),我们只需

-log(U(0, exp(-10*rate))/rate

或在R代码中

-log(runif(1, 0, exp(-10*rate)))/rate

我们可以使用类似的技巧进行上限。

使用上面的@ Roland函数,这给出了

gen.exp = function(q1, q2, maxiter = 1e3){
  i = 0
  repeat {
    i = i + 1
    upper = exp(-10*q1)
    lower = exp(-10.2*q1)
    a = -log(runif(1, lower, upper))/q1
    b = -log(runif(1, 0, exp(-4.8*q2)))/q2

    if((a>10 & a<10.2) & (a+b>15)) {message(i); return(c(a,b)) 
    if (i > maxiter) stop(paste("Conditions not fulfilled after", maxiter, "tries."))
  }
}

注意,我还打印了它花了多少次迭代。对于您的参数,我需要大约2次迭代。

答案 1 :(得分:2)

不要使用递归:

gen.exp<-function(q1, q2, maxiter = 1e3){
  i <- 0
  repeat {
    i <- i + 1
    a=rexp(1,q1)  # generate exponential random variable
    b=rexp(1,q2)  # generate exponential random variable
    if((a>10 & a<10.2) & (a+b>15)) return(c(a,b)) # criteria the random variables must meet
    if (i > maxiter) stop(paste("Conditions not fulfilled after", maxiter, "tries."))
  }
}

set.seed(42)
gen.exp(.25, 2)
#Error in gen.exp(0.25, 2) : Conditions not fulfilled after 1000 tries.

b大于4.8的概率为:

pexp(4.8, 2, lower.tail = FALSE)
#[1] 6.772874e-05

让我们尝试更多迭代:

gen.exp(.25, 2, maxiter = 1e7)
#[1] 10.08664  5.55414

当然这个RNG太慢了,几乎没用。最好一次生成更大批量的ab