Qualità dei generatori congruenziali lineari per numeri casuali


14

Sto facendo alcune simulazioni dell'equazione di Langevin, per varie forze esterne. Essendo detto che C è rand()da stdlib.hpuò introdurre pregiudizi nei miei risultati, sto usando un Mersenne Twister.

Tuttavia, vorrei sapere (e vedere) esattamente quale tipo di errori un generatore congruenziale lineare può introdurre nella mia simulazione. Queste sono cose che ho provato:

  • Generazione di tuple 3D di random per cercare di vedere iperpiani. Non vedo niente.
  • Fare la FFT di un grande vettore di numeri casuali. È quasi lo stesso sia per Mersenne Twister che per rand().
  • Verifica del principio di equipartizione per una particella in moto browniano. Entrambi gli integratori concordano sul valore atteso di con lo stesso numero di cifre significative.KE=12kBT
  • Vedendo quanto bene inseriscono un numero di bin che non è un potere due. Entrambi danno gli stessi risultati qualitativi, nessuno è migliore.
  • Osservando i percorsi browniani per vedere chiare divergenze da . Ancora una volta, senza fortuna.x=0
  • Distribuzione dei punti in un cerchio. Riempito e solo nel perimetro. Tra tutti loro e tra i vicini più vicini (la risposta di Shor, sotto nei commenti). Disponibile in questa sintesi , basta eseguirlo con Julia 0.5.0 dopo aver installato le librerie necessarie (consultare la guida per le istruzioni).

Vorrei sottolineare che sto cercando una distorsione introdotta nel contesto delle simulazioni fisiche. Ad esempio, ho visto come rand()falliscono miseramente i test dieharder mentre il Mersenne Twister non lo fa, ma per il momento questo non significa troppo per me.

Hai qualche esempio fisico, concreto, su come un cattivo generatore di numeri casuali distrugge una simulazione di Montecarlo?

Nota: ho visto come PRNG RANDUpuò essere terribile. Sono interessato a esempi non ovvi, di generatori che sembrano innocenti ma che alla fine introducono pregiudizi.


1
Non ho gli esempi richiesti, ma ho usato drand48 () / srand48 () anziché rand () / srand () nei miei programmi C. Le loro rispettive pagine man documentano i diversi algoritmi prng usati (vedi man random per l'algoritmo di rand), e credo che drand48 sia generalmente preferibile, sebbene la mia comprensione dettagliata sia vanificante. Quando desidero la riproducibilità portatile garantita su più piattaforme, ho codificato ran1 () da Ricette numeriche in C, 2a edizione, WHPress, et al, Cambridge UP 1992, ISBN 0-521-43108-5, pagina 280. Funziona alla perfezione Posso dirlo, ma non ho testato quantitativamente.

Usa random () o drand48 () / lrand48 () (utilizzo sempre quest'ultimo per le dinamiche molecolari e le simulazioni Monte Carlo ed è piuttosto buono). Inoltre, prova a utilizzare un seme casuale. Questo dovrebbe essere più che sufficiente per una simulazione dell'equazione di Langevin a singola particella.
valerio,

Abbiamo usato una circonferenza, non un cerchio.

@PeterShor Grazie per la correzione. Ho aggiornato la risposta, ancora nessuna fortuna temo.
RedPointyJackson,

1
@DanielShapero random e urandom dovrebbero essere RNG crittograficamente sicuri, destinati a scopi crittografici, come la generazione di chiavi. L' aspetto hardware è che su Linux usano l'entropia ambientale, non è la stessa cosa dell'accelerazione hardware. In realtà non sono destinati a nulla di simile alle simulazioni Monte Carlo.
Kirill,

Risposte:


3

Un riferimento interessante che descrive un fallimento di una simulazione Monte Carlo di un sistema fisico a causa di inadeguato RNG (anche se non hanno usato un LCG) è:

A. Ferrenberg e DP Landau. Simulazioni Monte Carlo: errori nascosti da "buoni" generatori di numeri casuali. Physical Review Letters 63 (23): 3382-3384, 1992.

I modelli Ising studiati da Ferrenberg e Landua sono buoni test di RNG perché è possibile confrontare con una soluzione esatta (per il problema 2-D) e trovare errori nelle cifre. Questi modelli dovrebbero mostrare i guasti in un PMMLCG aritmetico a 32 bit vecchio stile senza troppe difficoltà.

Un altro riferimento interessante è:

H. Bauke e Stephan Mertens. Le monete pseudo casuali mostrano più teste che code. arXiv: cond-mat / 0307138 [cond-mat.stat-mech]

Bauke e Mertens sono un valido esempio nei confronti dei generatori di numeri casuali di numeri di registro a scorrimento lineare a feedback lineare. Bauke e Mertens hanno altri articoli relativi a questo.

Può essere difficile trovare gli aerei Marsaglia in un diagramma a dispersione 3D. Puoi provare a ruotare la trama per avere una visione migliore e a volte ti esploderanno. Puoi anche fare test 3D di uniformità statistica: per i vecchi LCG a 32 bit, questi falliranno con un numero piuttosto piccolo di bin. ad esempio, un test di uniformità con una griglia di contenitori 20x20x20 in 3 dimensioni è sufficiente per rilevare la mancanza di uniformità per il PMMLCG ampiamente usato (e precedentemente ben considerato) con m = 2 ^ 31-1, a = 7 ^ 5.


1

È possibile utilizzare la suite TestU01 di test PRNG per scoprire quale di questi test ha randesito negativo. (Vedi TestU01: Libreria AC per test empirici di generatori di numeri casuali per una panoramica della suite di test.) È più facile che realizzare simulazioni Monte Carlo personalizzate. In un certo senso, è anche una questione di compostabilità del software (e correttezza del software): dato un PRNG che sembra funzionare bene su piccoli e semplici test, come fai a sapere che i suoi comportamenti patologici non saranno attivati ​​da un programma più ampio?

Ecco il codice:

#include "TestU01.h"

int main() {
  // Same as rand() on my machine
  unif01_Gen* gen = ulcg_CreateLCG(2147483647, 16807, 0, 12345);

  bbattery_SmallCrush(gen);
  bbattery_Crush(gen);

  return 0;
}

Per la suite SmallCrush , ci sono 3 test che falliscono su 15 (vedere guidelongtestu01.pdf in TestU01 per descrizioni lunghe e tutti i riferimenti; si tratta di 15 statistiche di 10 test).

  • n tdtdtI1,...{Ij+1Ij}

  • n t[0,1)tdt

  • nt[0,1)XnP(X<x)=xtn=2×106t=6χ2<10300

Supponendo che queste siano tutte simulazioni "tipiche" di Monte Carlo (anche se potrebbero non essere come i problemi che avevi in ​​mente), la conclusione è che randfallisce qualche sottoinsieme sconosciuto di esse. Non so perché sia ​​specificamente quel sottoinsieme, quindi è impossibile per me dire se funzionerà sul tuo problema o meno.

MaxOft sembra particolarmente sospetto, data la semplicità della descrizione.

Tra i test nella suite Crush , randfallisce 51 su 140 (140 statistiche in 96 test). Alcuni dei test falliti (come Fourier3 ) vengono eseguiti su stringhe di bit, quindi forse è possibile che non siano rilevanti per te. Un altro curioso test che fallisce è GCD , che verifica la distribuzione del GCD di due numeri interi casuali. (Ancora una volta, non so perché questo particolare test fallisca o se la tua simulazione ne soffrirà.)

PS : Un'altra cosa da notare è che in rand()realtà è più lento di alcuni PRNG che superano con successo tutti i test SmallCrush , Crush , BigCrush , come MRG32k3a (vedi il documento L'Ecuyer & Simard sopra).

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.