Reputation: 21
I am writing a class in c++ that uses a c++ rng to produce random numbers. The constructor takes the seed for the rng as an argument. However, when I expose the class to r using the rcpp package setting the seed does not work as I get different random numbers every time I instantiate a member of that class even though I pass the same seed. Is there a trick how to set the seed in c++ when using rcpp? Happy for all the help I can get.
Upvotes: 0
Views: 774
Reputation: 21
Thanks for all the help. I found the problem. I was using a C++ RNG and initialised the generator as a static variable in a member function without making it an explicit member of the class. It works fine in C++, but does not seem to work when the code is called from R for some Reason. To clarify:
//.h file
class RandomGen{
private:
const unsigned int seed;
public:
RandomGen(unsigned int _seed);
double get_num();
};
//.cpp file
RandomGen::RandomGen(unsigned int _seed):
seed(_seed)
{}
double RandomGen::get_num(){
static std::mt19937 generator(seed);
static std::exponential_distribution<double> distrMarket(1);
return distrMarket(generator);
}
Reproduces the problem. Making the rng generator a static member variable of the class fixes the problem. I just have no idea why.
Upvotes: 0
Reputation: 368211
Which RNG are you trying to seed? If it is R's you are more or less out of luck as Writing R Extensions clearly says you should do it from R.
There are workarounds (eg via Rcpp::Function()
) but maybe you should rethink the problem.
If however your are seeding your own RNG, it should work, and works eg for my RcppZiggurat package:
R> library(RcppZiggurat)
R> zsetseedLZLLV(12345) # set seed
R> zrnormLZLLV(3)
[1] 1.297770 -0.699053 0.443079
R> zsetseedLZLLV(12345) # re-set seed
R> zrnormLZLLV(3)
[1] 1.297770 -0.699053 0.443079 # same number
R> zrnormLZLLV(3)
[1] -0.405296 -1.771543 0.319896 # diff. now
R>
Lastly, if your question about to make your RNG be used by R's functions: that is possible (again, see Writing R Extensions) but maybe not such a great idea as code calling runif()
or rnorm()
has some (implicit) expectactions about what would get called.
Upvotes: 1