有没有办法通过RcppEigen将随机状态传递给Eigen的setRandom
,还是需要使用runif
?
以下是一个例子:
// [[Rcpp::depends(RcppEigen)]]
#include <RcppEigen.h>
using namespace Rcpp;
using Eigen::MatrixXd;
using Eigen::VectorXd;
// [[Rcpp::export]]
NumericVector fx() {
RNGScope scope;
MatrixXd x(3,2);
x=x.setRandom();
x.col(1)=as<VectorXd>(runif(3,0,1));
return wrap(x);
}
测试它:
set.seed(42); fx()
# [,1] [,2]
#[1,] -0.8105760 0.9148060
#[2,] 0.6498853 0.9370754
#[3,] 0.6221027 0.2861395
set.seed(42); fx()
# [,1] [,2]
#[1,] -0.9449154 0.9148060
#[2,] 0.8063267 0.9370754
#[3,] -0.0673205 0.2861395
请注意第2列(即runif
)是如何重现的,但第1列(即setRandom
)不是。
答案 0 :(得分:3)
Eigen中的RNG与R的RNG正交。我们RNGScope
处理R并允许您set.seed()
如您所知;你对Eigen的RNG所做的是独立的。
特别是,您必须添加胶水以将Eigen的RNG注册为R的用户提供的RNG。默认情况下,R不知道Eigen,这在R用户期望R的RNG时是有意义的。
你的问题似乎是一个带有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的评论:
我不希望Eigen在Rcpp::runif()
和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也更慢。但我们在这里谈论微秒,这可能不是我在真正的应用程序中担心的问题,这很可能会产生其他瓶颈。