4

Nこれは、平均ゼロと標準偏差で独立した正規偏差を描画する C++ 関数です。s

// [[Rcpp::depends(RcppArmadillo)]]

#include <RcppArmadillo.h>
using namespace Rcpp;

// [[Rcpp::export]] 
List rnorm_cpp(double s, int N){

    arma::colvec epsilon = s * arma::randn(N);
    return List::create(Named("e") = epsilon);

}

そして、これが(実質的に同一の)Rバージョンです

rnormR <- function(s, N){

  epsilon <- rnorm(N, mean = 0, sd = s)
  return(list(e = epsilon))

}    

調達後rnorm_cpprnormR次を実行しました。

set.seed(1234)
fooR <- rnormR(s = 5, N = 10)

set.seed(1234)
barR <- rnormR(s = 5, N = 10)

set.seed(1234)
fooCpp <- rnorm_cpp(s = 5, N = 10)

set.seed(1234)
barCpp <- rnorm_cpp(s = 5, N = 10)

最後に、実行identicalして次の結果を得ました。

> identical(fooR, barR)
[1] TRUE
> identical(barR, fooCpp)
[1] FALSE
> identical(fooCpp, barCpp)
[1] FALSE

この3つが当たると思っていましたTRUE。(1) の呼び出しでランダムな描画を複製し、(2)とrnorm_cppの呼び出しで同一の描画を取得するにはどうすればよいですか?rnormRrnorm_cpp

4

1 に答える 1

7

関数arma::randn()はR RNG に接続されていないため、呼び出しset.seed()は影響しません。

Rcpp で行うことは、R と C++ から同じRNGにアクセスできる優れた R API を利用することです。また、(自動的に挿入される) インスタンスに注意することでRNGScope、RNG の状態は R と C++ の間で常に正しくなります。

しかし、他のサードパーティの RNG (ここでは Arma の RNG) も自動的に調整されたと想定することはできません。さらに、この特定のケースでは、アルマジロに関するコンラッドのドキュメントは明確です。

シードを変更するには、std::srand()関数を使用します

明確にするために (こんにちは、@DWin) ここに完全な R および C++ の例を示します。

R> set.seed(42); rnorm(5)           ## Five N(0,1) draws in R
[1]  1.3710 -0.5647  0.3631  0.6329  0.4043
R> cppFunction('NumericVector foo(int n) { return rnorm(n); }')
R> set.seed(42); foo(5)             ## Five N(0,1) draws from C++ fun.
[1]  1.3710 -0.5647  0.3631  0.6329  0.4043
R> 

R と C++ を介して同じ数を取得します。a) RNG を同じようにシードし、b) 実際に R によって提供された同じ RNG を呼び出します。

于 2013-10-01T01:00:57.687 に答える