Lezione 10
Lezione 10
Numeri Casuali

In questa lezione impareremo a costruire un generatore di numeri casuali. Lo utilizzeremo quindi per generare numeri secondo una distribuzione uniforme, esponenziale e Gaussiana. Come applicazione utilizzeremo la generazione di numeri casuali per calcolare numericamente integrali mono e multi-dimensionali.

ESERCIZIO 10.0 - Generatore di numeri casuali (da consegnare):

Scrivere un programma che produca quattro istogrammi contenenti ciascuno 10000 numeri pseudo-casuali estratti da :
  1. una distribuzione uniforme tra 5 e 10.
  2. una distribuzione esponenziale tra 0 e + ∞ con costante k=1.
  3. una distribuzione gaussiana centrata in 1 e larghezza 1 con il metodo di Box-Muller.
  4. una distribuzione gaussiana centrata in 1 e larghezza 1 con il metodo accept-reject.
Per risolvere questo esercizio si può seguire lo schema seguente:
Brevi richiami

Generatore Lineare congruenziale

Generatore esponenziale

Metodo di Box Muller

Metodo Accept-Reject

ESERCIZIO 10.1 - Verifica del Teorema del Limite Centrale (facoltativo):

Generare una serie di numeri casuali uniformemente distribuiti in [0,1] e calcolare la somma eseguita su un numero n di elementi consecutivi della serie generata. Calcolare la varianza della serie di numeri generata e della serie delle somme. Verificare che questa scala con n. Passare da riga di comando sia il numero di elementi della serie di partenza (10000 può essere un buon numero) ed il numero di elementi su cui fare la somma. Creare due istogrammi che contengano la distribuzione dei numeri generata e la distribuzione delle somme. Verificare come cambia la distribuzione delle somme al variare di n.

Brevi richiami
Il Teorema del Limite Centrale

ESERCIZIO 10.2 - Calcolo di integrali con metodi MonteCarlo (da consegnare):
  1. Calcolare 10000 volte il valore dell'integrale di sin(x) tra [0,π] utilizzando il metodo della media a 100 punti e fare un grafico ( istogramma ) della distribuzione dei valori ottenuti.
  2. Estendere il punto precedente calcolando 10000 volte il valore dell'integrale di sin(x) tra [0,π] utilizzando il metodo della media a N punti con N pari a 100, 500, 1000, 5000, 10000 punti. Per ogni valore di N produrre il grafico della distribuzione dei 10000 valori ottenuti. [NOTA: poichè il calcolo degli integrali con N molto elevato potrebbe richiedere un certo tempo, potrebbe essere utile salvare in diversi files i valori degli integrali calcolati per un determinato N e svolgere i punti successivi con un secondo programma che utilizzi come input i files di integrali del programma precedente.]
  3. Stimare l'errore sul calcolo dell'integrale a 100, 500, 1000, 5000, 10000 punti come deviazione standard dei 10000 valori calcolati per ogni N. Far un grafico di questo errore in funzione di N.
  4. Assumendo che l'andamento dell'errore sia noto ( del tipo k/ √N ) si determini quanti punti sono necessari per ottenere una precisione di 0.001. Si ripeta lo stesso lavoro con il metodo hit-or-miss.


Per il calcolo di integrali con metodi MonteCarlo si può decidere di scrivere una nuova classe dedicata o estendere la classe Integral della lezione 8. In ogni caso ci dovrà essere un puntatore ad un oggetto di tipo RandomGen e due metodi che implementino le due tecniche discusse. A titolo di esempio si può considerare l'header file seguente:
Integrazione Montecarlo:

Brevi richiami

Calcolo di integrali con il metodo della media

Calcolo di integrali con il metodo hit-or-miss

ESERCIZIO 10.3 - Calcolo di integrali multidimensionali con metodi MonteCarlo (facoltativo):

Provare a risolvere il seguente integrale con una precisione di 0.01
Metodo hit-or-miss
utilizzando per esempio il metodo della media.

Suggerimento: si potrebbe costruire una classe FunzioneScalareBase astratta da cui la funzione integranda erediti. La classe FunzioneScalareBase avrà un metodo virtuale puro
virtual double Eval(const vector<double>&) const=0; .
Alla classe che calcola l'integrale si dovrà aggiungere un metodo dedicato del tipo
double Media(const FunzioneScalareBase* f, const vector<double>& inf, const vector& sup, unsigned int punti);

ESERCIZIO 10.4 - Errore nel caso di integrali multimensionali (facoltativo) :

Provare a ripetere le consegne dell'esercizio 10.2 applicate all'integrale multidimensionale dell'esercizio 10.3. In questo modo si può facilmente verificare che la legge con cui scala l'errore è indipendente dalla dimensione dell'integrale.

Qualche approfondimento su generatori di numeri casuali in C++11



Back to Home Page