6

私はRコード内でCを作っています。

私のCコードでは、rand()関数を使用して乱数を生成しています。R-ext.pdfには、コマンドを使用してシードを設定する必要があると書かれています。

  GetRNGstate();
  PutRNGstate();

上記のコマンドを使用していますが、同じシードに対して異なる値を取得しています。何か助けてもらえますか?

最小の例は次のとおりです。

Cの場合:

# include <R.h>
# include <Rinternals.h>
# include <Rmath.h>
# include <R_ext/Linpack.h> 

 SEXP example(){

   SEXP output;
   GetRNGstate();
   PROTECT(output = allocVector(INTSXP, 1));
   INTEGER(output)[0] = rand() % 50;
   PutRNGstate();
   UNPROTECT(1);
   return(output);
 }

Rの場合:

dyn.load("example.so")
## The following codes return different values at ever run 
set.seed(1)
.Call("example")

前もって感謝します。

4

1 に答える 1

8

これはあなたの考えの論理エラーです-シードを正しく設定し、コードからR RNGを初期化します...しかし、RRNGの代わりにシステムRNGを呼び出します。

(または)に置き換えるrand()と、設定されます。unif_rand()norm_rand()

Rcppを使用すると、これらすべてが簡単になり、さまざまな分布関数からの描画へのベクトル化されたアクセスが可能になります(ただし、必要に応じて、Cでもこれらすべてを手動で行うことができます)。

cppFunction()from Rcppを使用することで、 /RNGScopeを提供するものも処理します(古い例ではまだインスタンス化が示されていますが、参照カウントと同等の機能を追加しても害はありません)。 GetRNGstate()PutRNGstate()RNGScope

したがって、これを定義、自動拡張、コンパイル、およびロードするのは、実際には1つのライナーです。

R> cppFunction("double myrand() { return norm_rand(); }")
R> for (i in 1:5) { set.seed(42); cat(i, " -- ", myrand(), "\n") }
1  --  1.37096 
2  --  1.37096 
3  --  1.37096 
4  --  1.37096 
5  --  1.37096 
R> 

一方、再播種なしでは、

R> for (i in 1:5) { cat(i, " -- ", myrand(), "\n") }
1  --  -0.564698 
2  --  0.363128 
3  --  0.632863 
4  --  0.404268 
5  --  -0.106125 
R> 

最後に、本当に必要な場合は、もちろん引き続き使用できますrand()(ただし、その厄介なパフォーマンスに関する文献を参照してください)が、Rではなくシード関数を使用します。

于 2012-12-29T04:17:32.097 に答える