【发布时间】:2019-08-19 06:29:52
【问题描述】:
我目前正在构建的 R 包中有一个名为 rbinom01 的辅助函数。请注意,它调用random(3)。
int rbinom01(int size) {
if (!size) {
return 0;
}
int64_t result = 0;
while (size >= 32) {
result += __builtin_popcount(random());
size -= 32;
}
result += __builtin_popcount(random() & ~(LONG_MAX << size));
return result;
}
当R CMD check my_package时,我收到以下警告:
* checking compiled code ... NOTE
File ‘ my_package/libs/my_package.so’:
Found ‘_random’, possibly from ‘random’ (C)
Object: ‘ my_function.o’
Compiled code should not call entry points which might terminate R nor
write to stdout/stderr instead of to the console, nor use Fortran I/O
nor system RNGs.
See ‘Writing portable packages’ in the ‘Writing R Extensions’ manual.
我前往the Document,它说我可以使用*_rand 函数之一,以及distribution functions 家族。这很酷,但我的包只需要一个随机位流而不是一个随机的double。最简单的方法是使用random(3) 或从/dev/urandom 读取,但这会使我的包“不可移植”。
This post 建议使用sample,但不幸的是它不适合我的用例。对于我的应用程序,生成随机位显然对性能至关重要,所以我不希望它浪费任何时间调用unif_rand,将结果乘以N 并四舍五入。无论如何,我使用 C++ 的原因是利用位级并行性。
当然,我可以手动滚动自己的 PRNG 或复制并粘贴最先进的 PRNG 的代码,例如 xoshiro256**,但在此之前,我想看看是否有更简单的替代方案。
顺便说一句,有人可以将 Rcpp 的简短教程链接给我吗? 编写 R 扩展 内容全面且很棒,但我需要数周时间才能完成。我正在寻找一个更简洁的版本,但最好它应该比调用Rcpp.package.skeleton 提供更多信息。
正如@Ralf Stubner 的回答所建议的那样,我重新编写了原始代码,如下所示。但是,我每次都得到相同的结果。我怎样才能正确地播种它,同时保持我的代码“便携”?
int rbinom01(int size) {
dqrng::xoshiro256plus rng;
if (!size) {
return 0;
}
int result = 0;
while (size >= 64) {
result += __builtin_popcountll(rng());
Rcout << sizeof(rng()) << std::endl;
size -= 64;
}
result += __builtin_popcountll(rng() & ((1LLU << size) - 1));
return result;
}
【问题讨论】:
-
您可以通过dqrng包获取xoshiro256+和xoroshiro128+。
标签: c++ r random rcpp r-package