6

効率的にベクトル化できると思われるコードの一部に while ループをラップするという問題があります。ただし、各ステップでの停止条件は、その段階での値に依存します。この例を私の問題の表現モデルと考え
rnorm()くださいk

編集:コメントで説明されている私の問題の警告は、停止条件の前に取得するサンプル数の適切な近似値を先験的に知ることができないことです。

1 つのアプローチ:

  1. while ループを使用して、適切なサイズの法線ランダム ベクトルをサンプリングします (たとえば、rnorm(50)一度に 50 個の標準法線をサンプリングするrnorm(1)場合、または k がゼロに近い場合)。このベクトルをチェックして、k より大きい観測値があるかどうかを確認します。

  2. はいの場合は、停止して先行するすべての値を返します。それ以外の場合は、手順 1 のベクターを、手順 1 を繰り返して作成した新しいベクターと組み合わせます。

別のアプローチは、その特定の k に対して完全に過剰な数のランダム ドローを指定することです。これは、k=2 の場合、 を使用して 1,000 個の正規確率変数をサンプリングすることを意味する場合がありますrnorm(1000)

2 番目のケースで R が提供するベクトル化を利用すると、オーバーキル数が必要以上に大きくない場合にループ バージョンよりも高速な結果が得られますが、私の問題では、必要な実行回数について十分な直感がありません。するので、保守的になる必要があります。

質問は次のとおりです。方法 2 のように高度にベクトル化された手順を実行する方法はありますが、方法 1 のような条件付きチェックを使用する方法はありますか? rnorm(50)高度にベクトル化された方法が要素ごとに高速であることを考えると、「最速」の方法のような小さなベクトル化された操作を行っていますが、無駄が多いですか?

4

1 に答える 1

1

これは私の以前の提案の実装です: 最初のアプローチを使用しますが、各反復間で新しいサンプルの数を増やします。たとえば、各反復で新しいサンプルの代わりに、各反復間でその数を502 倍します:50100200400

サンプルサイズが発散幾何級数に従うため、「数回」の反復で終了することが保証されます。

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
于 2012-04-21T17:30:50.263 に答える