从 Rcpp 中获取与基数 R 相同的整数样本
Get the same sample of integers from Rcpp as base R
是否有可能从 Rcpp
和基数 R 的 sample
中得到相同的 sample
整数?
我曾尝试使用 Rcpp::sample
和 Rcpp::RcppArmadillo::sample
,但它们 return 的值不同 - 下面的示例代码。此外,Quick Example 部分 post https://gallery.rcpp.org/articles/using-the-Rcpp-based-sample-implementation/ returns 来自 Rcpp
和 base R 的相同样本,但是,我不能重现这些结果(我在最后附上这段代码)。
这可以做到吗/请问我做错了什么?
我的尝试:
// [[Rcpp::depends(RcppArmadillo)]]
#include <RcppArmadillo.h>
#include <RcppArmadilloExtensions/sample.h>
// [[Rcpp::export]]
Rcpp::IntegerVector mysamp1( int n) {
Rcpp::IntegerVector v = Rcpp::sample(n, n);
return v;
}
// [[Rcpp::export]]
Rcpp::IntegerVector mysamp2(int n) {
Rcpp::IntegerVector i = Rcpp::seq(1,n);
Rcpp::IntegerVector v = wrap(Rcpp::RcppArmadillo::sample(i,n,false));
return v;
}
// set seed
// [[Rcpp::export]]
void set_seed(double seed) {
Rcpp::Environment base_env("package:base");
Rcpp::Function set_seed_r = base_env["set.seed"];
set_seed_r(std::floor(std::fabs(seed)));
}
// [[Rcpp::export]]
Rcpp::IntegerVector mysamp3( int n, int seed) {
set_seed(seed);
Rcpp::IntegerVector v = Rcpp::sample(n, n);
return v;
}
/***R
set.seed(1)
sample(10)
# [1] 9 4 7 1 2 5 3 10 6 8
set.seed(1)
mysamp1(10)
# [1] 3 4 5 7 2 8 9 6 10 1
set.seed(1)
mysamp2(10)
# [1] 3 4 5 7 2 8 9 6 10 1
mysamp3(10, 1)
# [1] 3 4 5 7 2 8 9 6 10 1
*/
代码来自使用 R 样本的基于 RcppArmadillo 的实现 图库post return FALSE
在我的系统上:
// [[Rcpp::depends(RcppArmadillo)]]
#include <RcppArmadilloExtensions/sample.h>
using namespace Rcpp ;
// [[Rcpp::export]]
CharacterVector csample_char( CharacterVector x,
int size,
bool replace,
NumericVector prob = NumericVector::create()) {
CharacterVector ret = RcppArmadillo::sample(x, size, replace, prob) ;
return ret ;
}
/*** R
N <- 10
set.seed(7)
sample.r <- sample(letters, N, replace=T)
set.seed(7)
sample.c <- csample_char(letters, N, replace=T)
print(identical(sample.r, sample.c))
# [1] FALSE
*/
将评论编译成答案。 Akrun 指出,通过设置 RNGkind
或 RNGversion
我们可以复制结果。来自 DirkEddelbuettel;有一个 "change in R's RNG that came about because someone noticed a bias in, IIRC, use of sampling (at very large N). So thats why you you to turn an option on in R to get the old (matching) behaviour. " 并且 RalfStubner 表示这是一个已知问题:https://github.com/RcppCore/RcppArmadillo/issues/250 and https://github.com/RcppCore/Rcpp/issues/945
目前 R 使用不同的默认采样器,这会导致不同的结果
RNGkind(sample.kind = "Rejection")
set.seed(1)
sample(10)
# [1] 9 4 7 1 2 5 3 10 6 8
set.seed(1)
mysamp1(10)
# [1] 3 4 5 7 2 8 9 6 10 1
但是,可以使用
使用早期版本
RNGkind(sample.kind = "Rounding")
#Warning message:
# In RNGkind("Mersenne-Twister", "Inversion", "Rounding") : non-uniform 'Rounding' sampler used
set.seed(1)
sample(10)
# [1] 3 4 5 7 2 8 9 6 10 1
set.seed(1)
mysamp1(10)
# [1] 3 4 5 7 2 8 9 6 10 1
是否有可能从 Rcpp
和基数 R 的 sample
中得到相同的 sample
整数?
我曾尝试使用 Rcpp::sample
和 Rcpp::RcppArmadillo::sample
,但它们 return 的值不同 - 下面的示例代码。此外,Quick Example 部分 post https://gallery.rcpp.org/articles/using-the-Rcpp-based-sample-implementation/ returns 来自 Rcpp
和 base R 的相同样本,但是,我不能重现这些结果(我在最后附上这段代码)。
这可以做到吗/请问我做错了什么?
我的尝试:
// [[Rcpp::depends(RcppArmadillo)]]
#include <RcppArmadillo.h>
#include <RcppArmadilloExtensions/sample.h>
// [[Rcpp::export]]
Rcpp::IntegerVector mysamp1( int n) {
Rcpp::IntegerVector v = Rcpp::sample(n, n);
return v;
}
// [[Rcpp::export]]
Rcpp::IntegerVector mysamp2(int n) {
Rcpp::IntegerVector i = Rcpp::seq(1,n);
Rcpp::IntegerVector v = wrap(Rcpp::RcppArmadillo::sample(i,n,false));
return v;
}
// set seed
// [[Rcpp::export]]
void set_seed(double seed) {
Rcpp::Environment base_env("package:base");
Rcpp::Function set_seed_r = base_env["set.seed"];
set_seed_r(std::floor(std::fabs(seed)));
}
// [[Rcpp::export]]
Rcpp::IntegerVector mysamp3( int n, int seed) {
set_seed(seed);
Rcpp::IntegerVector v = Rcpp::sample(n, n);
return v;
}
/***R
set.seed(1)
sample(10)
# [1] 9 4 7 1 2 5 3 10 6 8
set.seed(1)
mysamp1(10)
# [1] 3 4 5 7 2 8 9 6 10 1
set.seed(1)
mysamp2(10)
# [1] 3 4 5 7 2 8 9 6 10 1
mysamp3(10, 1)
# [1] 3 4 5 7 2 8 9 6 10 1
*/
代码来自使用 R 样本的基于 RcppArmadillo 的实现 图库post return FALSE
在我的系统上:
// [[Rcpp::depends(RcppArmadillo)]]
#include <RcppArmadilloExtensions/sample.h>
using namespace Rcpp ;
// [[Rcpp::export]]
CharacterVector csample_char( CharacterVector x,
int size,
bool replace,
NumericVector prob = NumericVector::create()) {
CharacterVector ret = RcppArmadillo::sample(x, size, replace, prob) ;
return ret ;
}
/*** R
N <- 10
set.seed(7)
sample.r <- sample(letters, N, replace=T)
set.seed(7)
sample.c <- csample_char(letters, N, replace=T)
print(identical(sample.r, sample.c))
# [1] FALSE
*/
将评论编译成答案。 Akrun 指出,通过设置 RNGkind
或 RNGversion
我们可以复制结果。来自 DirkEddelbuettel;有一个 "change in R's RNG that came about because someone noticed a bias in, IIRC, use of sampling (at very large N). So thats why you you to turn an option on in R to get the old (matching) behaviour. " 并且 RalfStubner 表示这是一个已知问题:https://github.com/RcppCore/RcppArmadillo/issues/250 and https://github.com/RcppCore/Rcpp/issues/945
目前 R 使用不同的默认采样器,这会导致不同的结果
RNGkind(sample.kind = "Rejection")
set.seed(1)
sample(10)
# [1] 9 4 7 1 2 5 3 10 6 8
set.seed(1)
mysamp1(10)
# [1] 3 4 5 7 2 8 9 6 10 1
但是,可以使用
使用早期版本RNGkind(sample.kind = "Rounding")
#Warning message:
# In RNGkind("Mersenne-Twister", "Inversion", "Rounding") : non-uniform 'Rounding' sampler used
set.seed(1)
sample(10)
# [1] 3 4 5 7 2 8 9 6 10 1
set.seed(1)
mysamp1(10)
# [1] 3 4 5 7 2 8 9 6 10 1