Numeri Random D.E.I.S. Università di Bologna DEISNet http://deisnet.deis.unibo.it/ Introduzione • Può sembrare assurdo usare un computer per generare numeri casuali: – Il computer è una macchina deterministica - l’output è perfettamente predicibile a priori. • Tuttavia le sequenze di numeri casuali prodotte da computer sono di uso comune. • Nel seguito chiameremo – Sequenze casuali (random) • sequenze di numeri prodotte da fenomeni fisici intrinsecamente aleatori (ad es.: tempo trascorso fra due impulsi successivi di un contatore Geiger) – Sequenze pseudo-casuali (pseudo-random) • sequenze di numeri prodotte dal calcolatore utilizzabili “come se “ fossero sequenze casuali. 2 Sequenze pseudo-random • Definizione operativa di sequenza pseudo-random – “una sequenza di numeri si assimila ad una sequenza casuale se il programma che la produce è diverso e, sotto ogni aspetto misurabile, statisticamente incorrelato dal programma che usa il suo output” • In altre parole la sequenza pseudo-casuale deve “apparire” del tutto casuale all’applicazione che la utilizza, per servire allo scopo • Pertanto: – Due generatori di sequenze pseudo-casuali devono produrre lo stesso risultato (dal punto di vista statistico) se utilizzati come ingresso dello stesso programma • In caso contrario, almeno uno dei due non è un buon generatore – Esiste una serie di test statistici per valutare la bontà di un generatore • Un generatore che non supera tali test potrebbe non essere un buon generatore 3 Variabili Aleatorie Uniformi • Variabile aleatoria (VA) uniforme – I valori della v.a. sono equiprobabili e cadono in uno specifico intervallo • Nell’implementazione al calcolatore tipicamente da 0 a 1 • Nell’implementazione della generazione di sequenze pseudo-random le VA uniformi sono un punto di riferimento – VA con altre distribuzioni di probabilità vengono quasi sempre generate a partire da VA uniformi, mediante opportune operazioni • La VA uniforme è il mattoncino elementare per ogni modello stocastico implementato utilizzando sequenze pseudo-random 4 Numeri Random in C L’ANSI C fornisce le seguenti funzioni per la generazione di numeri casuali (V. Numerical Recipes in C): #include <stdlib.h> #define RAND_MAX... void srand(unsigned seed); int rand(void); srand(seed): serve per inizializzare il generatore con un arbitrario valore di seed: a valori uguali di seed corrispondo identiche sequenze. rand(): restituisce il successivo numero, compreso fra 0 e RAND_MAX 5 Generatori lineari congruenziali • I generatori di numeri casuali più semplici sono di tipo lineare congruenziale • Se Zi è il generico numero i-esimo della sequenza pseudo-casuale allora: Zi-1 = a · Zi + c (mod m) • Dove: – l’operatore mod indica il resto della divisione – a si chiama moltiplicatore e c viene detto incremento. – Z0 (primo valore della sequenza) si chiama seme (seed). • Il generatore si dice moltiplicativo se c = 0 – Quindi vengono generati al più m numeri interi Zi distinti con 0 ≤ Zi ≤ m - 1. • Per ottenere numeri casuali Ui uniformemente distribuiti in [0,1) è sufficiente definire Ui = Zi /m 6 Generatori lineari congruenziali Pro: 1. Estrema velocità di generazione Contro: 1. Sequenza periodica di periodo al più pari a m. • Occorre scegliere un valore di m elevato e valori di a, c e Z0 tali da avere periodo massimo. 2. Ogni valore di Zi è completamente determinato dai quattro parametri m, a, c e Z0. 3. Non c’è assenza di correlazione fra chiamate successive del generatore. 7 Correlazione • Se k numeri consecutivi della sequenza vengono utilizzati come coordinate di punti in uno spazio kdimensionale (ciascuna coordinata fra 0 e 1) – Se i numeri fossero assolutamente incorrelati i punti tenderebbero a coprire tutto lo spazio – In realtà i punti vanno a cadere in “piani” (k-1) - dimensionali, il cui numero è al massimo m1/k. Esempio: m = 32768 ( cattiva scelta) k=3 #piani = 327681/3 = 32 Occorre una scelta accurata di m, a e c al fine di massimizzare k 8 Esempi: ran0 • Non è un ottimo generatore ma costituisce uno standard minimo qualitativo per un generatore di numeri casuali. • Generatore lineare congruenziale con: a = 75 =16807 m = 231 - 1 = 2147483647 c =0 Difetti: – Non si può usare seed = 0 – A causa dell’estrema semplicità della routine, numeri piccoli tendono ad essere seguiti sempre da numeri grandi: • Normalizzando i valori ad 1, mediamente c’è un valore < 10-6 ogni 106 chiamate. Questo però è sempre seguito da un valore ≤ 0.0168. – Correlazione fra numeri successivi • Si nota disponendo i numeri, presi a coppie, in un grafico bidimensionale 9 Esempi: ran1 • Risolve il problema della correlazione fra chiamate successive di ran0 – genera i numeri con ran0 e permuta l’uscita È necessaria una fase di inizializzazione del vettore iv, con valori calcolati con ran0. Ad ogni chiamata il valore nel vettore iv, alla posizione iy è scelto come uscita e come successivo iy. L’elemento scelto viene sostituito da uno nuovo, calcolato ancora con ran0. 10 Esempi: ran2 • Ran1 supera i test in cui ran0 fallisce. – Inizia ad avere problemi quando il numero di chiamate è abbastanza elevato, > 108 cioè circa m/20. • Il rimedio consiste nel combinare due sequenze di numeri casuali con diversi periodi m1 e m2 – Il periodo della sequenza risultante diventa il minimo comune multiplo dei due periodi. • L’idea base consiste nel sommare i valori ottenuti dai due generatori. – Questo accorgimento è implementato nella routine ran2, la quale adotta anche una permutazione dell’uscita simile a ran1. • Con i valori di m1 e m2 adottati, ran2 ha un periodo di circa 2.3x1018 e costituisce un ottimo generatore di numeri casuali. 11 Mersenne Twister (MT) • Sviluppato nel 1997 da Makoto Matsumoto e Takuji Nishimura • Provvede alla generazione veloce di numeri casuali di qualità molto elevata • Principali caratteristiche: – Periodo ben più lungo e migliore equidistribuzione rispetto a qualsiasi generatore precedente: • È stato dimostrato che il periodo è 219937 -1 e i numeri sono distribuiti uniformemente in un iperspazio a 623 dimensioni. • Questo significa che la correlazione fra valori successivi della sequenza è praticamente trascurabile. – Generazione veloce: la velocità di generazione di numeri casuali è sostanzialmente uguale a quella di rand() presente nella libreria standard dell’ANSI C. – Uso efficiente della memoria: la versione in C del generatore è costituita da 624 parole di codice. 12 Mersenne Twister (MT) In dettaglio: • Il generatore MT è stato progettato rispettando le condizioni pratiche che un buon generatore di numeri random deve soddisfare. Non esistono infatti metodi matematici rigorosi per dimostrare l’assenza di difetti di un generatore. Una della prove più forti per selezionare un buon generatore è sicuramente il test spettrale. MT è in grado di superare un test di questo tipo, ed in particolare il k-distribution test: se si osserva un periodo dell’uscita del generatore con 32 bit di accuratezza, le n-uple di numeri con n=623, si distribuiscono uniformemente in uno spazio a 623 dimensioni. Analogamente, con un’accuratezza a 16 bit, le n-uple di numeri con n=1246, si distribuiscono uniformemente in uno spazio a 1246 dimensioni e con un’accuratezza a 2 bit in 9968 dimensioni. 13 Esempi: altri • Si ricordano altri tipi di generatori: – Ran3: non utilizza il metodo lineare congruenziale ma il metodo sottrattivo; – generatori “Quick and Dirty”: molto semplici, permettono di ottenere numeri casuali con poche linee di codice e limitate risorse di elaborazione 14 Esempi • A partire da ran0 sono stati introdotti generatori via via più complicati, in grado di superare test statistici più stringenti. • La maggiore complicazione di questi generatori causa un tempo di esecuzione maggiore di ran0. Nella tabella seguente si riportano i tempi di esecuzione relativi, ponendo come riferimento il generatore ran0. • Nella scelta di un generatore si deve tener presente il periodo: la sequenza di numeri da generare deve essere molto minore del periodo 15 Considerazioni conclusive • Le caratteristiche che deve avere un generatore di sequenze pseudocasuali: – Ripetibilità, affinché sia possibile ripetere gli stessi esperimenti più volte – Soddisfacimento dei test: servono per verificare che il generatore sia quanto più simile ad un generatore di numeri casuali ideale. – Semplicità e rapidità: un simulatore che usa il generatore risulta quindi efficiente. – Periodicità lunga, in modo da poter effettuare simulazioni lunghe senza riutilizzare più volte la stessa sequenza. – Portabilità, cioè rendere l’implementazione del generatore indipendente dalla piattaforma. 16 Test Statistici • Per valutare la bontà di un generatore si eseguono test statistici sulle sequenze ottenute. • I tre metodi fondamentali sono: – test di uniformità o del χ2 (chi quadro) – test di Kolmogorov-Smirnov 17 Test di uniformità o del χ2 • Serve per misurare l'uniformità della distribuzione di una sequenza. – Si applica a variabili casuali discrete o discretizzate • Dati k eventi possibili: E1, E2, … , Ek con probabilità p1, p2, … , pk si fanno n esperimenti in cui si osservano y1 eventi di tipo E1, y2 eventi di tipo E2, … , yk eventi di tipo Ek. Vale: • La variabile: ha una distribuzione detta χ2 con k-1 gradi di libertà. Nota: il termine npi rappresenta la frequenza attesa di istanze di Ei. 18 Test di uniformità o del χ2 • V è indipendente da pi se n è grande (si richiede di solito che ). • Per verificare l’uniformità di un generatore di numeri random distribuiti uniformemente in [0,1]: – Si creano k-sottointervalli di ampiezza 1/k. – Si genera un gran numero di istanze della va uniforme e si conta per ogni intervallo il numero yi di istanze che sono cadute all’interno dell’intervallo. Poiché il generatore è uniforme si ha: pi = 1/k 1/k 1 1/k 1 19 Test di uniformità o del χ2 – Si calcola il valore di V. Se il generatore è buono, la variabile V risulta avere la distribuzione χ2 con k-1 gradi di libertà. df = # gradi di libertà = k - 1 – Il test è superato se, fissato un certo valore critico χ21-α , V non è maggiore a tale valore. – Tipicamente 1 - α = 0,95 ; il valore corrispondente χ21-α si trova in forma tabulare. 20 Test di uniformità o del χ2 df 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 1 - ! = 0.95 3.84 5.99 7.82 9.49 11.07 12.59 14.07 15.51 16.92 18.31 19.68 21.03 22.36 23.69 25.00 26.30 27.59 28.87 30.14 31.41 1 - ! = 0.99 6.64 9.21 11.35 13.28 15.09 16.81 18.48 20.09 21.67 23.21 24.73 26.22 27.69 29.14 30.58 32.00 33.41 34.81 36.19 37.57 1 - ! = 0.999 10.83 13.82 16.27 18.47 20.52 22.46 24.32 26.13 27.88 29.59 31.26 32.91 34.53 36.12 37.70 39.25 40.79 42.31 43.82 45.32 21 Test di Kolmogorov-Smirnov • È un metodo che si applica a variabili casuali continue. – Data una sequenza di n istanze xi della variabile casuale X , si fissa un valore di x e si calcola il numero mx di istanze minori di x all’interno della sequenza: • Si costruisce quindi la funzione: FN (x) = mx / n che si confronta con F(x) 22 Test di Kolmogorov-Smirnov • D è la differenza massima, in valore assoluto, tra la distribuzione teorica F(x) e quella osservata FN(x): D = max | FN(x) - F(x) | • Se x1, x2, ..., xN è un campione casuale, FN(x) rappresenta il numero (rapportato ad N) degli elementi del campione xi, minori od uguali ad x. – Nella figura si vede che, da come è stata definita, FN(x) è costante tra xi e xi+1 e ogni gradino è pari ad 1/N. 23 Test di Kolmogorov-Smirnov • Analogamente al caso del test del chi-quadro, D viene confrontato con certi valori critici Da (ad esempio 0.01 o 0.05) per decidere se accettare o meno l'ipotesi che i numeri ui siano equamente distribuiti. • A differenza del test del chi-quadrato, il test di Kolmogorov e Smirnov offre il vantaggio di non richiedere che i dati siano in qualche modo raggruppati e, quindi, non dipende da come vengono scelte le categorie nelle quali ripartire la sequenza. 24 Distribuzioni non uniformi • A partire da un algoritmo di generazione di numeri uniformemente distribuiti è possibile ricavare sequenze con distribuzioni diverse. Gli approcci da seguire sono: – Metodo della trasformazione inversa – Metodo della reiezione 25 Metodo della trasformazione inversa Si vuole generare una variabile aleatoria X con funzione di densità di probabilità fX(x). 1. Si calcola la funzione di distribuzione di probabilità o funzione cumulativa di probabilità: Tale funzione è continua, monotona crescente ed è sempre compresa tra 0 e 1 (per definizione FX(x) = P[X ≤ x]) 2. Si pone y = FX(x) ∈ [0,1] dove y è un’istanza di una variabile casuale Y con distribuzione uniforme in [0,1] 3. L’operazione x = F-1(y) fornisce un’istanza della variabile X. 26 Metodo della trasformazione inversa • Poiché Y è una variabile aleatoria uniformemente distribuita in [0,1], si ha: P{Y ≤ y} = y cioè: P{Y ≤ F(x)} = F(x) Se esiste la F-1(), possiamo scrivere: P{F-1(Y) ≤ F-1(F(x))} = P{F-1(Y) ≤ x} = F(x) cioè F-1(Y), ha distribuzione F(x). 27 Metodo della trasformazione inversa Questo metodo si giustifica intuitivamente in modo grafico come segue Si scelgono due intervalli con la medesima ampiezza Δx1 e Δx2 ai quali corrispondono gli intervalli Δy1 e Δy2. Generando uniformemente y in [0,1] osserveremo molto più frequentemente valori di y nell’intervallo Δy1 che all’interno dell’intervallo Δy2 Applicando il metodo dell’inversa verranno generati più frequentemente valori in Δx1 che in Δx2. 28 Esempio • Generazione di una variabile aleatoria con distribuzione esponenziale • Invertendo la F(x): F(x) 1 F(x) = 1 – e –µx y = 1 – e –µx ln( 1 – y ) = –µx x = – ln( 1 – y )/µ x • Quindi, generando y uniforme in [0,1] e calcolando x come nella formula precedente, si ottiene un’istanza x di una variabile aleatoria esponenziale a valore medio µ. 29 Metodo di reiezione • È un metodo molto utile quando la funzione cumulativa non è nota o non è invertibile analiticamente. Affinché sia applicabile è necessario che la funzione densità di probabilità f(x) abbia supporto finito: f(x) M a b x Nell’esempio il supporto è l’intervallo [a,b]; M è il valore massimo assunto da f(x). 30 Metodo di reiezione - procedura 1. Si generano coppie di numeri casuali (x,y) con x distribuito uniformemente in [a,b] e y in [0,M]. 2. Interpretando (x,y) come un punto del piano, si osserva la sua posizione rispetto la curva f(x): f(x) M A a B b x 3. Se il punto cade al di sotto della curva f(x) viene considerata l’ascissa, cioè x (caso A); se il punto cade all’esterno della curva, si genera una nuova coppia (caso B). 31 Metodo di reiezione • I punti (x,y) vengono generati in modo uniforme pertanto la probabilità di accettare il valore x è pari al rapporto fra l’area sottesa da f(x) cioè 1 e l’area del rettangolo: P = 1 / [ M (b - a) ] • Il numero medio di punti generati nel piano per ottenere un’istanza valida della variabile è: Quindi il numero di istanze di variabile aleatoria uniforme che devono essere generate è pari a 2M(b-a). • L’efficienza di questo metodo risulta dipendente dalla forma f(x) e in particolare della dimensione della dimensione del rettangolo che la racchiude. 32 Distribuzione Gaussiana • La densità di probabilità di una distribuzione gaussiana non è invertibile analiticamente. Di solito viene generata nei seguenti metodi: – Si sommano 12 v.a. uniformi indipendenti tra -0,5 e 0,5. Per il teorema del limite centrale il risultato tende alla distribuzione gaussiana. La media è nulla e la varianza diventa 1. Da notare che il supporto della v.a. risulta limitato tra -6 e +6 – Si approssima l’andamento della gaussiana con archi di sinusoide 33