Eigen 中的 RNG 与 R 的 RNG 正交。我们有RNGScope 处理R 并允许您set.seed() 如您所知;你用 Eigen 的 RNG 做什么是分开的。
特别是,您必须添加胶水将 Eigen 的 RNG 注册为 R 的用户提供的 RNG。默认情况下,R 不知道 Eigen,这是有道理的,因为 R 用户期望 R 的 RNG。
您的问题似乎是一个普通的“使用 Eigen 编程”问题,您无法初始化 Eigen RNG。与Rcpp无关。
编辑:这是您的示例,已更正。原来 Eigen 使用系统 RNG,所以你需要 srand() 来播种它。
R> sourceCpp("/tmp/roland.cpp")
R> set.seed(42); fx(42)
[,1] [,2]
[1,] -0.933060 0.914806
[2,] -0.340072 0.937075
[3,] 0.381271 0.286140
R> set.seed(42); fx(42)
[,1] [,2]
[1,] -0.933060 0.914806
[2,] -0.340072 0.937075
[3,] 0.381271 0.286140
R>
它使用你的代码的这个修改版本:
// [[Rcpp::depends(RcppEigen)]]
#include <RcppEigen.h>
using namespace Rcpp;
using Eigen::MatrixXd;
using Eigen::VectorXd;
// [[Rcpp::export]]
RNGScope scope;
MatrixXd x(3,2);
srand(seed);
x=x.setRandom();
x.col(1)=as<VectorXd>(runif(3,0,1));
return wrap(x);
}
编辑 2 以响应 OP 的 cmets:
我不认为 Rcpp::runif() 和 Eigen 发出的 srand() 调用之间的速度差异很大,所以你仍然坚持srand() 一直存在问题,并且系统之间的行为可能不同.
快速演示脚本:
#include <RcppEigen.h>
// [[Rcpp::depends(RcppEigen)]]
// [[Rcpp::export]]
Rcpp::NumericVector v1(int n) {
return Rcpp::runif(n);
}
// [[Rcpp::export]]
Rcpp::NumericVector v2(int n) {
Eigen::VectorXd x(n);
x = x.setRandom();
return Rcpp::wrap(x);
}
/*** R
library(rbenchmark)
N <- 1e7
benchmark(v1(N), v2(N))
*/
产生
R> sourceCpp("/tmp/roland.cpp")
R> library(rbenchmark)
R> N <- 1e7
R> benchmark(v1(N), v2(N))
test replications elapsed relative user.self sys.self user.child sys.child
1 v1(N) 100 12.633 1.000 11.356 1.261 0 0
2 v2(N) 100 17.222 1.363 13.981 3.198 0 0
R>
请注意,RcppEigen 在这里较慢,即使在仅创建向量的更简单设置中也是如此。但是我们在这里讨论的是微秒,这可能不是我担心的任何一种方式,在一个很可能有其他瓶颈的真正的应用程序中。