Algoritmo ziggurat: differenze tra le versioni
Contenuto cancellato Contenuto aggiunto
Funzionalità collegamenti suggeriti: 2 collegamenti inseriti. |
|||
(24 versioni intermedie di 19 utenti non mostrate) | |||
Riga 1:
{{
L<nowiki>'</nowiki>'''algoritmo ziggurat'''<ref>{{Cita web|url=https://www.no-regime.com/ru-it/wiki/Ziggurat_algorithm|titolo=Algoritmo di Ziggurat - Ziggurat algorithm - www.no-regime.com|sito=www.no-regime.com|lingua=it|accesso=2022-07-02}}</ref> è un [[algoritmo]] di [[rejection sampling]] utilizzato per il campionamento numerico pseudo-casuale. È stato sviluppato negli anni '60 da [[George Marsaglia]] ed è utilizzato per generare valori con una [[Variabile casuale#Distribuzione di probabilità|distribuzione di probabilità]] [[Funzione monotona|decrescente monotona]] partendo da una sorgente di numeri casuali uniformemente distribuiti (solitamente un [[Numeri pseudo-casuali|generatore di numeri pseudo-casuali]]) e da una tabella precalcolata. Può anche essere applicato a distribuzioni unimodali [[Funzione simmetrica|simmetriche]], come la [[distribuzione normale]].
[[File:Ziggurat_method.gif|miniatura|300x300px| L'algoritmo Ziggurat utilizzato per generare valori campione con una [[distribuzione normale]] (solo i valori positivi sono mostrati per semplicità). I punti rosa sono inizialmente numeri casuali distribuiti uniformemente. La funzione di distribuzione desiderata viene prima segmentata in aree uguali "A". Uno strato ''i'' è selezionato a caso dalla fonte uniforme a sinistra. Quindi un valore casuale dalla sorgente viene moltiplicato per la larghezza del livello scelto e il risultato viene ''x'' testato per vedere in quale regione della fenditura cade. I possibili risultati sono: 1) (sinistra, regione nera) il campione chiaramente sotto la curva e viene passato direttamente all'output, 2) (a destra, regione a strisce verticali) il valore del campione può trovarsi sotto la curva e deve essere ulteriormente testato. In tal caso, viene generato un valore ''y'' casuale all'interno del layer scelto e confrontato con ''f (x)'' . Se inferiore, il punto è sotto la curva e viene emesso il valore ''x'' . In caso contrario, il punto scelto ''x'' viene rifiutato e l'algoritmo viene riavviato dall'inizio. ]]▼
L'algoritmo ziggurat è più veloce rispetto ad altri metodi di generazione di numeri casuali normalmente utilizzati, come ad esempio il metodo polare di Marsaglia e la [[trasformazione di Box-Muller]]. Tuttavia, poiché questo algoritmo è anche più complesso da implementare, solitamente è utilizzato solo a fronte di una grande richiesta di numeri pseudo-casuali.
Il termine ''ziggurat'' è stato utilizzato per la prima volta in un articolo di [[George Marsaglia]] e [[Wai Wan Tsang]] nel 2000. Lo chiamarono così per via del modo in cui distribuisce la [[probabilità]]: la distribuzione ricorda la forma di una [[Ziqqurat|ziggurat]]<ref>{{Cita web|url=https://iris.univr.it/handle/11562/942488|titolo=Piramidi e ziqqurat|sito=iris.univr.it|accesso=2022-07-02}}</ref> a causa dei segmenti rettangolari impilati in ordine decrescente da cui è formata.
▲[[File:Ziggurat_method.gif|miniatura|300x300px| L'algoritmo Ziggurat utilizzato per generare valori campione con una [[distribuzione normale]] (solo i valori positivi sono mostrati per semplicità). I punti rosa sono inizialmente numeri casuali distribuiti uniformemente. La funzione di distribuzione desiderata viene prima segmentata in aree uguali "A". Uno strato ''i'' è selezionato a caso dalla fonte uniforme a sinistra. Quindi un valore casuale dalla sorgente viene moltiplicato per la larghezza del livello scelto e il risultato viene testato ''x''
== Teoria del funzionamento ==
L'algoritmo ziggurat è
Dato un punto casuale al di sotto di una curva di [[densità di probabilità]], la sua coordinata ''x'' è un numero casuale con la distribuzione desiderata.
La distribuzione scelta dall'algoritmo ziggurat è composta da ''n'' regioni di uguale area. ▼
Sopra di esso, viene costruito un altro strato rettangolare di larghezza ''x''<sub>1</sub> e altezza ''A'' / ''x''<sub>1</sub>, così da mantenere anche per esso un'area pari ad ''A.'' La parte superiore di questo livello si trova a ''y''<sub>2</sub> = ''y''<sub>1</sub> + ''A'' / ''x''<sub>1</sub> e interseca la funzione di densità di probabilità in un punto (''x''<sub>2</sub>, ''y''<sub>2</sub>), dove ''y'' <sub>2</sub> = ''f'' (''x''<sub>2</sub>). Questo strato include ogni punto della funzione di densità di probabilità compreso tra ''y''<sub>1</sub> e ''y''<sub>2</sub>, ma, a differenza del livello base, include anche punti come (''x''<sub>1</sub>, ''y''<sub>2</sub>) che non si trovano nella distribuzione desiderata.
Ulteriori strati vengono poi impilati. Per utilizzare una tabella precalcolata di dimensione ''n'' (256 solitamente), viene scelta ''x''<sub>1</sub> tale che ''x''<sub>''n''</sub> = 0, il che significa che il livello superiore, il livello ''n'' - 1, raggiunge esattamente il picco di distribuzione a (0, ''f'' (0)). ▼
▲Ulteriori strati vengono poi impilati mantenendo costante l'area. Per utilizzare una tabella precalcolata di dimensione ''n'' (256 solitamente), viene scelta ''x''<sub>1</sub> tale che ''x''<sub>''n''</sub> = 0, il che significa che il livello superiore, il livello ''n'' - 1, raggiunge esattamente il picco di distribuzione a (0, ''f'' (0)).
Lo strato ''i'' si estende verticalmente da ''y''<sub>''i''</sub> a ''y''<sub>''i''+1</sub> e può essere diviso orizzontalmente in due regioni: la porzione (generalmente più grande) da 0 a ''x''<sub>''i''+1</sub> che è interamente contenuta nella distribuzione desiderata e la porzione (piccola) da ''x''<sub>''i''+1</sub> a ''x''<sub>''i''</sub>, che è solo parzialmente contenuta. ▼
▲
Ignorando per un momento il problema del livello 0, e date le variabili casuali uniformi ''U''<sub>0</sub> e ''U''<sub>1</sub> ∈ [0,1), l'algoritmo ziggurat opera in questi passi: ▼
▲Ignorando per un momento il problema del livello 0, e date le [[Variabile casuale|variabili casuali]] uniformi ''U''<sub>0</sub> e ''U''<sub>1</sub>
# Scegli un livello casuale 0 ≤ ''i'' < ''n'' .
# Sia ''x'' = ''U''<sub>0</sub>''x''<sub>''i''</sub> .
# Se ''x''
# Sia ''y'' = ''y''<sub>''i''</sub> + ''U''<sub>1</sub>(''y''<sub>''i'' +1</sub> - ''y''<sub>''i''</sub> ).
# Calcola ''f'' (''x''). Se ''y''
# Altrimenti, scegli nuovi numeri casuali e torna al passaggio 1.
Il passaggio 1 equivale alla scelta di una coordinata ''y''. Il passaggio 3 verifica se la coordinata ''x'' è all'interno della funzione di densità desiderata. In caso contrario, il passo 4 sceglie una coordinata ''y'' e il passo 5 esegue il test di accettazione.
Si noti che per il livello superiore ''n'' - 1 questo test fallisce sempre, perché ''x'' <sub>''n''</sub> = 0.
=== Ottimizzazioni ===
L'algoritmo può essere eseguito in modo efficiente utilizzando tabelle precalcolate per ''x''<sub>''i''</sub> e ''y''<sub>''i''</sub> = ''f'' (''x''<sub>''i''</sub>), ma
*
* Invece di confrontare ''U''<sub>0</sub>''x<sub>i</sub>'' con ''x''<sub>''i''+1</sub> al punto 3, è possibile
* Quando si generano valori in virgola mobile a precisione singola (a standard [[IEEE 754]]), che hanno solo una mantissa a 24 bit (incluso l'iniziale implicita 1), i bit meno significativi di un numero casuale intero a [[32 bit]] non vengono utilizzati. Questi bit possono essere usati per selezionare il numero di livelli.
== Note ==
<references />
== Altri progetti ==
{{interprogetto}}
== Collegamenti esterni ==
▲* Nulla nell'algoritmo ziggurat dipende dalla normalizzazione della funzione di distribuzione di probabilità (integrale sotto la curva uguale a 1) quindi la rimozione delle [[Normalizzazione (matematica)|costanti di normalizzazione]] può accelerare il calcolo di ''f'' (''x'').
▲* Invece di confrontare ''U''<sub>0</sub>''x<sub>i</sub>'' con ''x''<sub>''i''+1</sub> al punto 3, è possibile precomputare ''x''<sub>''i''+1</sub> / ''x''<sub>''i''</sub> e confrontarlo con ''U''<sub>0</sub> direttamente. Se ''U'' <sub>0</sub> è un generatore di numeri casuali intero, questi limiti possono essere premoltiplicati di 2 <sup>32</sup> (o 2 <sup>31</sup>, a seconda dei casi) in modo da poter utilizzare un confronto di numeri interi.
▲* Quando si generano valori in virgola mobile a precisione singola [[IEEE 754]], che hanno solo una mantissa a 24 bit (incluso l'iniziale implicita 1), i bit meno significativi di un numero casuale intero a 32 bit non vengono utilizzati. Questi bit possono essere usati per selezionare il numero di livelli.
* [https://www.jstatsoft.org/article/view/v005i08 The Ziggurat Method for Generating Random Variables]
{{portale|matematica}}
|