1

I would like to do the equivalent of R's set.seed() inside of a C++ function. How do I do this?

Note that I make this C++ function available in R via the Rcpp package. I would like myfun(seed=42) to return the same result each time it is called in R. I do not want to set the rng seed in R via set.seed() prior to calling myfun every time.

C++ file:

#include <Rcpp.h>
using namespace Rcpp;

// [[Rcpp::export]]
double myfun(double seed) {
  std::srand(seed); // <-- this doesn't do what i want
  return R::rnorm(0,1);
}

/*** R
myfun(42)
myfun(42)
*/

This currently returns:

> myfun(42)
[1] 0.737397

> myfun(42)
[1] -0.02764103

What I want is:

> myfun(42)
[1] 0.737397

> myfun(42)
[1] 0.737397
DanY
  • 5,920
  • 1
  • 13
  • 33
  • If it were trivial we would have done it. Call it from R, be done. Else ... use a different RNG (family). The code in base R is _complicated_ but can also be assumed to be correct. Pick your poison :) – Dirk Eddelbuettel Mar 21 '19 at 20:08
  • Bummer, but OK. Thanks, Dirk – DanY Mar 21 '19 at 20:20
  • There may be one odd way out. I think we added an option to leave the RNG-setting handshake we do from R to C++ alone (so "you are on your own" to keep the state of the RNGs sane) and you could then use `Rcpp::Function()` to call `set.seed()`. But if you read this far you probably also convinced yourself already that that is brittle. Now: What do you _really_ want to do? – Dirk Eddelbuettel Mar 21 '19 at 20:29
  • I have a likelihood function in which I approximate an integral with an average (think multinomial probit with an accept-reject simulator). I have the whole likelihood function coded up in C++ (using quite a bit of your Rcpp Sugar). I just want to run `optim` from R on this function, but I don't want the random draws to change for each step taken by the optimizer (hence, I would like to set the seed inside of the C++ function). It sounds like you're suggesting I wrap the C++ likelihood function in a simple R function that just sets the seed and then calls the C++ function... am I right? – DanY Mar 21 '19 at 20:32
  • 3
    You could use a non-R-based RNG and side-step the issue. Some are even faster: RcppZiggurat, dqrng, ... – Dirk Eddelbuettel Mar 21 '19 at 20:36
  • (And with `nloptr` you may get by without `optim()` ... but I am fully ignorant of whatever detailed issues you face there...) – Dirk Eddelbuettel Mar 21 '19 at 20:37
  • I will look into those - thank you. I'm quite new to C++ so I've been sticking to the world of Rcpp and optim() thus far. – DanY Mar 21 '19 at 20:37
  • That's not a approach -- robust and trusted. In which case you can just call `set.seed(123)` before calling `optim()` as you _are_ at the R level. – Dirk Eddelbuettel Mar 21 '19 at 20:40
  • Hi @DirkEddelbuettel -- I'm sorry but I don't understand the first sentence of your last comment. Can you elaborate? What is (or is not?) robust and trusted? – DanY Mar 22 '19 at 00:33
  • 1
    . Misses 'bad' ie not a bad approach. – Dirk Eddelbuettel Mar 22 '19 at 00:52

0 Answers0