R 递归生成指数随机变量

R 递归生成指数随机变量,r,recursion,random,exponential-distribution,R,Recursion,Random,Exponential Distribution,我不熟悉R中的递归。我试图生成满足R中特定条件的指数随机变量。下面是一个简单的示例,显示了我生成两个独立指数随机变量的尝试 代码 当我运行上述代码时,会出现以下错误: 错误:计算嵌套太深:无限递归/optionsexpressions=? wrapup期间出错:计算嵌套太深:无限递归/optionsexpressions=? 我已经尝试过修改optionsexpressions=10000,以允许R增加迭代次数。这似乎对我的情况没有帮助,也许我没有正确地使用这个选项。我理解用上述严格标准生成连续

我不熟悉R中的递归。我试图生成满足R中特定条件的指数随机变量。下面是一个简单的示例,显示了我生成两个独立指数随机变量的尝试

代码

当我运行上述代码时,会出现以下错误:

错误:计算嵌套太深:无限递归/optionsexpressions=? wrapup期间出错:计算嵌套太深:无限递归/optionsexpressions=? 我已经尝试过修改optionsexpressions=10000,以允许R增加迭代次数。这似乎对我的情况没有帮助,也许我没有正确地使用这个选项。我理解用上述严格标准生成连续分布可能是个问题。话虽如此,是否仍有避免错误的方法?或者至少在发生错误时重复递归?递归在这里是一种过度杀戮吗?是否有更简单/更好的方法生成所需的随机变量?
我非常感谢您的见解。

不要对此使用递归:

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.
让我们尝试更多的迭代:

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

当然,这个RNG非常慢,几乎没有用。最好同时生产更大批量的a和b。

不要对此使用递归:

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.
让我们尝试更多的迭代:

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

当然,这个RNG非常慢,几乎没有用。最好同时生产更大批量的a和b。

您使用的是一个具有两种条件的简单拒收取样器

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

为了生成指数随机数,我们使用以下公式

-rate * log(U)
其中U是一个U0,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次迭代。

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

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

为了生成指数随机数,我们使用以下公式

-rate * log(U)
其中U是一个U0,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次迭代。

罗兰说的。一般来说,当函数调用16的输入依赖于函数调用15的结果时,我使用递归,以此类推。这里不是这样。关于表达式参数;如果你正确地使用它,很明显你已经达到了你设定的极限,或者50万个嵌套计算的硬编码极限。一般来说,当函数调用16的输入依赖于函数调用15的结果时,我使用递归,以此类推。这里不是这样。关于表达式参数;如果您正确地使用了它,那么很明显,您将遇到您设置的限制或500000个嵌套计算的硬编码限制。