我正在用 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")
提前致谢。
最佳答案
这是您思维中的逻辑错误——您正确设置了种子,从代码初始化 R RNG ...但随后调用系统 RNG 而不是R RNG。
将 rand()
替换为 unif_rand()
(或 norm_rand()
),您应该设置好了。
Rcpp使这一切变得更容易,并让您从各种分布函数中矢量化访问绘图(但如果您愿意,您当然也可以在 C 中手动完成所有这些操作)。
通过使用来自 Rcpp 的 cppFunction()
,我们现在还处理 RNGScope
,它反过来提供 GetRNGstate()
/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()
(但请参阅有关其糟糕性能的文献),然后使用 它的播种功能而不是R。
关于c - 在 R 代码中传递种子/设置种子/C,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/14078636/