2015-04-07 37 views
11

Mi piacerebbe generare numeri casuali identici in R e Julia. Entrambi i linguaggi sembrano utilizzare la libreria Mersenne-Twister per impostazione predefinita, ma in Julia:Genera numeri casuali identici in R e Julia

srand(3) 
rand() 

Produce 0.975, mentre in R:

set.seed(3) 
runif(1) 

produce 0.168.

Qualche idea?

domande SO correlate here e here.

mio caso d'uso per coloro che sono interessati: Nuovo codice di Julia che richiede la generazione di numeri casuali (ad esempio bootstrapping statistica) confrontando uscita che dalle biblioteche equivalenti in R.

+2

Un modo approssimativo sarebbe quello di generare tutti i replicati di bootstrap (o forse solo gli indici) in primo piano e memorizzarli in un file che entrambi i programmi potrebbero utilizzare. – joran

+1

Questa non è una risposta, ma suppongo che il modo in cui il seme viene trasformato nello stato iniziale per la libreria MT non sia lo stesso. Presumo che le risposte possano e debbano essere trovate nella fonte (yay per l'open source). – IainDunning

+0

@joran D'accordo, e questo è quello che potrei finire a fare. C'è un po 'di lavoro a questo però (almeno per me - sono un parente novizio in R) in quanto implica alterare sia la fonte R che quella di Julia per cercare numeri casuali nel file. –

risposta

4

Questo è un vecchio problema.

Paul Gilbert ha affrontato lo stesso problema alla fine degli anni '90 (!!) quando cercava di affermare che le simulazioni in R (allora nuovo arrivato) davano lo stesso risultato di quelle in S-Plus (quindi l'incumbent).

La sua soluzione, e ancora l'approccio d'oro AFAICT: re-implementare in codice fresco in entrambe le lingue in quanto questo è l'unico modo per garantire lo stesso seeding, lo stato, ... e quant'altro lo influenzi.

+0

In altre parole, nessuna scorciatoia magica :-) Grazie per la risposta, mi terrò in gioco dando il segno di spunta per un giorno o due nel caso qualcuno possa inventarsi qualcosa che funziona nel mio particolare caso particolare. –

1

See:

?set.seed 

"Mersenne-Twister": Da Matsumoto e Nishimura (1998). Un GFSR contorto con periodo 2^19937-1 e equidistribuzione in 623 dimensioni consecutive (per l'intero periodo). Il 'seme' è un insieme 624-dimensionale di numeri interi a 32 bit più una posizione corrente in quel set.

E si potrebbe vedere se è possibile collegarsi allo stesso codice C da entrambe le lingue. Se volete vedere la lista/vettore, tipo:

.Random.seed 
+0

Sì, "ma" se fosse così facile otterrete gli stessi risultati anche tramite il Mersenne Twister di GSL o altro. Di solito, la piccola differenza locale nella creazione di set, nella manipolazione ecc. Vorrei solo scrivere una semplice routine ... –

+4

Nel caso qualcuno si chiedesse a chi di noi credere, ... credo a Dirk. Probabilmente ti farà risparmiare un sacco di tempo. –

3

Praticando il RCall suggerimento di @Khashaa, è chiaro che è possibile impostare il seme e ottenere i numeri casuali da R.

julia> using RCall 

julia> RCall.reval("set.seed(3)") 
RCall.NilSxp(16777344,Ptr{Void} @0x0a4b6330) 

julia> a = zeros(Float64,20); 

julia> unsafe_copy!(pointer(a), RCall.reval("runif(20)").pv, 20) 
Ptr{Float64} @0x972f4860 

julia> map(x -> @printf("%20.15f\n", x), a); 
    0.168041526339948 
    0.807516399072483 
    0.384942351374775 
    0.327734317164868 
    0.602100674761459 
    0.604394054040313 
    0.124633444240317 
    0.294600924244151 
    0.577609919011593 
    0.630979274399579 
    0.512015897547826 
    0.505023914156482 
    0.534035353455693 
    0.557249435689300 
    0.867919487645850 
    0.829708693316206 
    0.111449153395370 
    0.703688358888030 
    0.897488264366984 
    0.279732553754002 

e da R:

> options(digits=15) 
> set.seed(3) 
> runif(20) 
[1] 0.168041526339948 0.807516399072483 0.384942351374775 0.327734317164868 
[5] 0.602100674761459 0.604394054040313 0.124633444240317 0.294600924244151 
[9] 0.577609919011593 0.630979274399579 0.512015897547826 0.505023914156482 
[13] 0.534035353455693 0.557249435689300 0.867919487645850 0.829708693316206 
[17] 0.111449153395370 0.703688358888030 0.897488264366984 0.279732553754002 

** EDIT **

Per il suggerimento di @ColinTBowers, ecco un modo più semplice/pulitore per accedere R numeri casuali da Julia.

julia> using RCall 

julia> reval("set.seed(3)"); 

julia> a = rcopy("runif(20)"); 

julia> map(x -> @printf("%20.15f\n", x), a); 
    0.168041526339948 
    0.807516399072483 
    0.384942351374775 
    0.327734317164868 
    0.602100674761459 
    0.604394054040313 
    0.124633444240317 
    0.294600924244151 
    0.577609919011593 
    0.630979274399579 
    0.512015897547826 
    0.505023914156482 
    0.534035353455693 
    0.557249435689300 
    0.867919487645850 
    0.829708693316206 
    0.111449153395370 
    0.703688358888030 
    0.897488264366984 
    0.279732553754002 
+1

Bello. Quindi c'è una scorciatoia tramite 'RCall' che potrebbe probabilmente essere incartata. Ma sottolinea solo il punto principale: se si desidera lo stesso flusso RNG, si * vuole * lo stesso codice da eseguire. Potrei partire da un semplice generatore (ad esempio il KISS di Marsaglia) e codificarli solo su entrambi i lati –

+0

@DirkEddelbuettel, ho cercato i tweeter Mersenne open source e ho trovato esempi sul [sito web di Makoto Matsumoto] (http: //www.math .sci.hiroshima-u.ac.jp/~ m-mat/MT/SFMT /) (molte versioni del codice sorgente per il download e la carta originale che includeva il codice sorgente), [codice sorgente R] (https: // github .com/wch/r-source/blob/07ac1e21db175ac877530a5d0105906911e56c18/src/main/RNG.C# L561) e [GSL] (https://www.gnu.org/software/gsl/manual/html_node/Random-number GENERATORE-algorithms.html). Sono tutti un po 'diversi. Fortunatamente l'interfaccia C di Julia funziona bene e R fornisce una libreria condivisa, ecc. – rickhg12hs

+0

MT è troppo complicato. Usa qualcosa come i semplici generatori lineari congruenti (per creare uniformi, ad esempio qualcosa come KISS), ad esempio in Ziggurat (che crea le normali). Ziggurat è utilizzato in Julia e ho un pacchetto RcppZiggurat per R. –