对于需要条件检查的东西,是否有比循环更有效的方法?

时间:2012-04-20 18:53:22

标签: r loops

我遇到一个问题,涉及我在一些代码中包含一个while循环,我认为这些代码可以有效地进行矢量化。但是,在每一步中,我的停止条件都依赖于该阶段的值。将此示例视为我的问题的代表性模型:
使用rnorm()生成N(0,1)个随机变量,直到您采样大于任意值k的值。

编辑:在评论中讨论我的问题的一个警告是,我不能先验地知道在停止条件之前要采取多少样本的近似值。

一种方法:

  1. 使用while循环,采样适当大小的正常随机向量(例如,rnorm(50)一次采样50个标准法线,或者如果k接近零则采用rnorm(1)。检查此向量以查看是否有任何观察值大于k。

  2. 如果是,请停止并返回所有前面的值。否则,将步骤1中的矢量与重复步骤1制作的新矢量组合。

  3. 另一种方法是为给定的k指定一个完全过度杀戮的随机抽取数。这可能意味着如果k = 2,则使用rnorm(1000)采样1,000个正常随机变量。

    在第二种情况下利用R提供的向量化比在过度杀伤数量不是太大的情况下提供比循环版本更快的结果,但在我的问题中,我对多少没有很好的直觉我需要做的,所以我需要保守。

    问题如下:有没有办法像方法2那样进行高度向量化的过程,但是使用方法1之类的条件检查?当考虑到高度向量化的方法是元素元素更快但更浪费时,像rnorm(50)这样的小矢量化操作是“最快”的方法吗?

1 个答案:

答案 0 :(得分:1)

以下是我之前建议的实现:使用您的第一种方法但增加每次迭代之间的新样本数量,例如,在每次迭代时代替50个新样本,在每次迭代之间将该数字乘以2 :50,然后是100200400等。

如果您的样本量遵循不同的几何系列,则可以保证在“少量”迭代中退出。

sample.until.thresh <- function(FUN, exit.thresh,
                                sample.start = 50,
                                sample.growth = 2) {

   sample.size    <- sample.start
   all.values     <- list()
   num.iterations <- 0L

   repeat {
      num.iterations <- num.iterations + 1L
      sample.values  <- FUN(sample.size)
      all.values[[num.iterations]] <- sample.values

      above.thresh <- sample.values > exit.thresh
      if (any(above.thresh)) {
         first.above <- match(TRUE, above.thresh)
         all.values[[num.iterations]] <- sample.values[1:first.above]
         break
      }

      sample.size <- sample.size * sample.growth
   }

   all.values <- unlist(all.values)

   return(list(num.iterations = num.iterations,
               sample.size    = length(all.values),
               sample.values  = all.values))
}

set.seed(123456L)
res <- sample.until.thresh(rnorm, 5)
res$num.iterations
# [1] 16
res$sample.size
# [1] 2747703