Graine de passage / Réglage de la graine / C dans le code R

Je fabrique C dans les codes R.

Dans mon code C, j’utilise la fonction rand () pour générer un nombre aléatoire. Le fichier R-ext.pdf indique que je dois définir une graine à l’aide des commandes;

GetRNGstate(); PutRNGstate(); 

Bien que j’utilise les commandes ci-dessus, je reçois toujours des valeurs différentes pour la même graine. Pourriez-vous me donner de l’aide?

L’exemple minimum est:

En C:

 # include  # include  # include  # include  SEXP example(){ SEXP output; GetRNGstate(); PROTECT(output = allocVector(INTSXP, 1)); INTEGER(output)[0] = rand() % 50; PutRNGstate(); UNPROTECT(1); return(output); } 

En R:

 dyn.load("example.so") ## The following codes return different values at ever run set.seed(1) .Call("example") 

Merci d’avance.

C’est une erreur de logique dans votre façon de penser: vous définissez correctement le germe, initialisez le R RNG à partir du code … mais appelez ensuite le RNG système au lieu du R RNG.

Remplacez rand() par unif_rand() (ou norm_rand() ) et vous devriez être défini.

Rcpp facilite tout cela et vous donne un access vectorisé aux tirages à partir des différentes fonctions de dissortingbution (mais vous pouvez bien sûr faire tout cela à la main aussi en C si vous préférez).

En utilisant cppFunction() de Rcpp , nous prenons également en charge RNGScope qui fournit à son tour GetRNGstate() / PutRNGstate() (alors que des exemples plus anciens montrent encore une instanciation de RNGScope ; l’append ne nuit pas à l’équivalent du comptage de références). .

Donc, il s’agit vraiment d’un one-liner pour définir, étendre automatiquement, comstackr et charger ceci:

 R> cppFunction("double myrand() { return norm_rand(); }") R> for (i in 1:5) { set.seed(42); cat(i, " -- ", myrand(), "\n") } 1 -- 1.37096 2 -- 1.37096 3 -- 1.37096 4 -- 1.37096 5 -- 1.37096 R> 

alors que sans la ré-ensemencement nous obtenons

 R> for (i in 1:5) { cat(i, " -- ", myrand(), "\n") } 1 -- -0.564698 2 -- 0.363128 3 -- 0.632863 4 -- 0.404268 5 -- -0.106125 R> 

Enfin, si vous le souhaitez vraiment, vous pouvez bien sûr continuer à utiliser rand() (mais consultez la littérature sur ses performances médiocres), mais utilisez ensuite sa fonction de classement plutôt que celle de R.