【问题标题】:Calling C code from R with .C(): random value is the same every time使用 .C() 从 R 调用 C 代码:随机值每次都相同
【发布时间】:2013-01-28 11:58:16
【问题描述】:

我对这个提问者有相反的问题:Passing seed/Setting seed/ C within R code。我的问题是我想使用 R 随机数生成器在 C 代码中生成一个随机数,但是每次运行它时,我都会得到相同的“随机”值。这是我的代码(包括我碰巧正在使用的头文件,这些对于代码 sn-p 来说并非都是必需的):

#include <stdio.h>
#include <stdlib.h>
#include <malloc.h>
#include <math.h>   // C header files

#include <R.h>
#include <R_ext/Utils.h>
#include <Rmath.h>

void main(){
GetRNGstate();
double u = unif_rand();
PutRNGstate();
Rprintf("%f\n",u);
}

现在我在使用 R CMD SHLIB 编译并使用 dyn.load() 后从 R Windows GUI 调用它:

> .C("main")
0.000889
list()

现在如果我关闭 R,重新启动,然后 dyn.load() 再次(但没有第二次编译):

> .C("main")
0.000889
list()

根据我在互联网上找到的各种代码和“编写 R 扩展”手册,这不应该发生。但我可能只是错过了一步?

【问题讨论】:

  • 这不是你的问题,但是 (a) 没有标准的 &lt;malloc.h&gt; 标头;声明malloc的标头是&lt;stdlib.h&gt;,(b)void main()是错误的,应该是int main(void)void main() 经常表示一本 C 教科书,该教科书的作者并不像他认为的那样了解 C。
  • 猜测:你有一个set.seed 调用在你的.Rprofile 或类似的东西,每次你开始一个新的 R 会话时都会修复种子?
  • @CDRV 不幸的是,无法确定,因为当我启动 R 时,会自动加载其他人的 R 配置文件。但看起来这很可能是问题所在!谢谢你。您是否碰巧知道如何重置随机种子,使其不会每次都一样?
  • 没关系,我找到了:stackoverflow.com/questions/10910698/…

标签: c r


【解决方案1】:

我无法复制这个。

这是一个完整且可重现的示例,仅依靠 inline 包来帮助构建、编译、链接和加载最小函数:

R> library(inline)
R> src <- '
+   GetRNGstate();
+   double u = unif_rand();
+   Rprintf("%f\\n",u);
+   PutRNGstate();
+   return R_NilValue;
+ '
R> fun <- cxxfunction(signature(), body=src)
R> set.seed(42)
R> invisible(fun())   # invisible to suppress the NULL return in foo()
0.914806
R> invisible(fun())
0.937075
R> invisible(fun())
0.286140
R> invisible(fun())
0.830448
R> invisible(fun())
0.641746
R> 

如果我重置种子,同样的序列开始:

R> set.seed(42)
R> invisible(fun())
0.914806
R> invisible(fun())
0.937075
R> invisible(fun())
0.286140
R> 

您可能正在加载/运行具有与设置 RNG 相关的副作用的不同功能。此外,以防万一,您的示例无法加载,因为您无法将带有 main() 的函数加载到 R 本身中。

【讨论】:

  • 感谢您的尝试,但是“无法加载”是什么意思?我使用 R CMD SHLIB randtest.c 编译了我的函数,然后使用 dyn.load("randtest.dll") 将其加载到 R 中,然后通过键入 .C("main") 运行它。它产生我上面给出的输出。如果我关闭 R GUI,再次打开它,然后再次重新加载,相同的值会打印到屏幕上。我应该提到我第二次没有再次编译 C 代码。不幸的是,我无法在这台计算机上使用内联包。如果有帮助,我正在使用 R 2.14-1。
  • 安装inline 并运行我的示例时会发生什么?至于main(),也许你很幸运,因为你的返回void 而不是int。每个程序都可以只有一个 main 函数,R 自带。
  • 不幸的是,我无法在我正在使用的计算机上安装任何东西,包括内联。作为一种解决方法,是否有某种方法可以将 R 中的随机种子设置为随机的?
  • 没关系,看起来答案就在这里。 stackoverflow.com/questions/10910698/…。再次感谢您的帮助,希望我能尽快切换到 Rcpp!
  • 只需使用set.seed(as.numeric(Sys.time())
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2023-03-18
  • 1970-01-01
  • 2018-09-08
相关资源
最近更新 更多