在R代码中传递种子/设置种子/ C.

时间:2012-12-29 04:13:59

标签: c r

我在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")

提前致谢。

1 个答案:

答案 0 :(得分:7)

这是您思考中的逻辑错误 - 您正确设置种子,从代码初始化R RNG ...但是然后调用系统RNG 而不是R RNG。

rand()替换为unif_rand()(或norm_rand()),您应该进行设置。

Rcpp使所有这一切变得更加容易,并且您可以从各种分发函数中获取对绘图的矢量化访问权限(但如果您愿意,您当然可以在C中手动完成所有这些操作)。

通过使用Rcpp中的cppFunction(),我们现在还会处理RNGScopeGetRNGstate()反过来提供PutRNGstate() / RNGScope(而较旧的示例仍显示实例化) 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()

最后,如果您真的希望您当然可以继续使用{{1}}(但请参阅有关其糟糕性能的文献),然后使用其播种功能而不是R的。