2012-12-29 10 views
5

Sto creando C nei codici R.Passaggio di seme/Impostazione di seme/C nel codice R

Nel mio codice C sto usando la funzione rand() per generare un numero casuale. R-ext.pdf dice che devo impostare un seme usando i comandi;

GetRNGstate(); 
    PutRNGstate(); 

Anche se sto usando questi comandi sopra, sto ancora ottenendo valori diversi per lo stesso seme. Potresti darmi un aiuto?

L'esempio è minima:

In C:

# include <R.h> 
# include <Rinternals.h> 
# include <Rmath.h> 
# include <R_ext/Linpack.h> 

SEXP example(){ 

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

In R:

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

Grazie in anticipo.

risposta

7

Questo è un errore logico nel vostro modo di pensare - si correttamente imposta il seme, inizializzare l'R RNG dal codice ... ma poi chiamare il RNG sistema invece della R RNG.

Sostituire rand() con unif_rand() (o norm_rand()) e si dovrebbe essere impostato.

Rcpp rende tutto più semplice e ti dà accesso vettoriale ai disegni dalle varie funzioni di distribuzione (ma puoi ovviamente farlo anche a mano in C se preferisci).

Utilizzando cppFunction() da Rcpp, abbiamo ora anche occupiamo di RNGScope che a sua volta fornisce GetRNGstate()/PutRNGstate() (mentre gli esempi più vecchi mostrano ancora istanziazione di RNGScope; aggiunta non è dannoso come fa un equivalente di conteggio di riferimento).

così è davvero una battuta per definire, auto-estende, compilare e caricare questo:

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> 

mentre senza la ri-semina otteniamo

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> 

Infine, se è davvero vuoi che tu possa naturalmente continuare a usare rand() (ma vedere la letteratura sulle sue prestazioni allucinanti), ma poi usa la sua funzione di semina invece di R.

+0

Una fodera! davvero potente! – agstudy

+0

Sì, anche se il 'cppFunction()' fa un po 'di magia dietro le quinte per far funzionare quella linea - si espande. Ma per noi da usare, è abbastanza vicino alla magia ;-) –

+0

Ma io è meglio usare sourceCpp (almeno per scopi di debug)? – agstudy

Problemi correlati