...Bisogna attivare Javascript !...

Per fare cicli lunghissimi di generazione di numeri pseudocasuali

Versione del 20140713 : http://www.elegio.it/doc/tn/lunghicicli.html
Dove ho messo altri documenti su questo tema: http://www.elegio.it/doc/tn/

Ovviamente NON suggerisco di fare TUTTO DA SOLO ossia NON usare programmi GARANTITISSIMI DA MOLTI MATEMATICI disponibili in rete più o meno gratuitamente... Ma quando uno, mettiamo il Santo Papa o la Angelica Merkel, affida ad un suo segretario un testo che vuole che resti segreto... che garanzia ha che il suo segretario/segretaria di fiducia non comunichi con molto lucro ai giornalisti o ai servizi segreti degli Stati Amici ( dagli amici mi guardi Dio ) quel messaggio prima di criptarlo ?

Dunque consiglio alla Merkel ( complimenti per la vittoria al mondiale di calcio 2014... io tifavo sia per la Germania che per l'Argentina e sono stato comunque felice ) e consiglio al Papa argentino ed all'eventuale suo successore... ( mah... ci sarà ? ) di provvedere PERSONALMENTE a precriptare il messaggio usando un algoritmo semplice che oltretutto sia a lui perfettamente comprensibile come questo ( insegnare più matematica ai seminaristi ed ai politici ), e solo dopo avere preso questa misura di sicurezza affidare il messaggio segreto ai suoi segretari e camerieri magari persino cardinali, di sua assoluta fiducia...
Che garanzia ha, per esempio, il Papa di essere in mani più sicure di quell' Iscariota amministratore economista, bancario e contabile del Nazareno ?

1) Scegliere e fare un calcolo dimostrativo

Questo documento è dedicato alla verifica del buon funzionamento di questa funzione:

Consiglio vivamente di usare per ogni kaso[k][2], tranne il primo kaso[0][2], un SAFE PRIME spiegato, per esempio, qui: http://it.wikipedia.org/wiki/Numero_primo_sicuro che si ottiene da un primo di Sophie Germain, come spiegato qui : http://en.wikipedia.org/wiki/Sophie_Germain_prime

Per capire l'algoritmo bisogna avere presente il concetto di RADICE PRIMITIVA che viene spiegato qui: http://en.wikipedia.org/wiki/Primitive_root_modulo_n.

Breve spiegazione dell'algoritmo

Il vettore kaso può essere lungo quanto si vuole ed ogni suo elemento deve essere costituito da una terna di numeri interi: il valore del numero pseudocasuale, che cambia di volta in volta, riguardante il numero primo considerato, la radice primitiva usata per il numero primo considerato e il k_esimo numero primo considerato.

Una radice primitiva   a   è un intero che consente di generare tutti i numeri compresi tra 1 e   p−1   facendo ovviamente calcoli in algebra modulare usando come modulo il primo p. Dunque an modulo p, scegliendo un valore opportuno di n, produce un qualsiasi intero tra 1 e p−1. Dato che n può essere un intero gigantesco, l'elevazione a potenza si fa con successive moltiplicazioni e calcolo del resto della divisione per p. Dunque in Javascript si deve scrivere (x*a)%p dove x è l'intero ottenuto al passo precedente e l'operatore % rappresenta in Javascript il calcolo del modulo ( ossia il resto della divisione di x*a diviso p ). Usando wxMaxima ( http://www.elegio.it/max/ ) si otterrebbe lo stesso risultato scrivendo mod(x*a,p).

Solitamente si usano come numeri pseudocasuali tutti i numeri ottenuti col metodo notissimo usato qui ma l'originalità di questo algoritmo consiste nel fatto che vengono scartati i numeri dispari ed utilizzati SOLO I NUMERI PARI DIVISI PER 2 come si vede dalla istruzione do{kaso[k][0]=(kaso[k][0]*kaso[k][1])%kaso[k][2]; }while(kaso[k][0]%2==1).

Questo sperpero di numeri pseudocasuali ha il vantaggio di rendere praticamente imprevedibile il legame matematico tra un numero pseudocasuale e il suo successivo perché a priori è ignoto il numero di passi da fare per ottenere, dopo un numero pari, un altro numero pari.

Dopo che si è generato un numero pseudocasuale lo divido per due per cui il totale dei numeri utilizzati sarà (p−1)/2. Ma se p è un SAFE PRIME allora (p−1)/2 sarà un numero dispari e primo ossia un primo di Sophie Germain.

Per ottenere una uniforme probabilità di generazione di interi compresi tra 0 e kbase−1 bisogna che uno ed uno solo dei primi, diminuito di 1 e diviso per 2, sia esattamente divisibile per kbase mentre tutti gli altri interi, essendo primi di Sophie Germain e diversi l'uno dall'altro, saranno tra loro primi e lo saranno anche nei confronti dell'intero divisibile per kbase.

In generale la generazione equiprobabile dei numeri tra 0 e kbase−1 si ottiene se tutti i numeri (kaso[k][2]-1)/2 sono tra loro primi e uno di essi, di solito (kaso[0][2]-1)/2 è esattamente divisibile per kbase. Poi l'algoritmo somma tutti i numeri pseudocasuali ottenuti ad un dato passo e calcola il modulo di questa sommatoria rispetto a kbase. Vista la grande imprevedibilità ottenuta usando non un solo generatore di numeri pseudocasuali ma parecchi... la pseudocasualità dell'intero ottenuto in questo modo dovrebbe essere elevatissima...

L'avanzamento del calcolo e i risultati vengono visualizzati nei tre capitoli seguenti.

...Clicca per leggere il tipo di problema scelto...

2a) A calcolo terminato visualizza la numerosità delle estrazioni

Visualizza, numero per numero, l'ultima volta che è stato estratto e, soprattutto, QUANTE VOLTE OGNI NUMERO E' STATO ESTRATTO. Se il ciclo è stato fatto tutto, tutti i numeri devono essere stati estratti nella stessa quantità.

...Scegliere il caso da fare ... ma funziona solo se Javascript funziona ...

2b) A calcolo terminato visualizza i ritardi che si sono verificati.

Visualizza un importante segnalatore della casualità dell'estrazione ossia il numero di ritardi registrati nella estrazione di un numero. Se l'estrazione non fosse casuale ogni numero verrebbe estratto con un ritardo costante ma se l'estrazione è veramente casuale sono possibili, anche se rari, ritardi enormi. Qui, oltre al numero delle volte che si è registrato un dato ritardo, specifico anche l'ultimo numero che ha avuto quel ritardo e a quale passo quel ritardo si è verificato per l'ultima volta.

...Scegliere il caso da fare ... ma funziona solo se Javascript funziona ...

2c) A calcolo terminato visualizza qualche numero estratto alla fine...

Visualizza alcune estrazioni ottenute alla fine del calcolo...

...Scegliere il caso da fare ... ma funziona solo se Javascript funziona ...

3) Spiegazione dei metodi applicati.

Uno dei metodi più usati per generare una sequenza di numeri pseudocasuali per simulare, ad esempio, l'estrazione di un numero del LOTTO ( da 1 a 90 ) o di un numero della ROULETTE ( da 0 a 36 ) è il metodo moltiplicativo congruente che consiste in questa procedura.

4) Il sorgente della funzione più importante usata.

Ecco l'applicazione dell'algoritmo che consente una casualità ILLIMITATA anche se non si possono usare numeri primi enormi a causa del linguaggio di programmazione usato ( Javascript ma anche C++ o Fortran ...)

Questa funzione serve a verificare che TUTTI i numeri estratti siano esattamente PROBABILI IN MODO UGUALE ed evidenzia certi aspetti del generatore basato sull'uso di diversi numeri primi, non uno solo...

Ho trascritto qui l'algoritmo usato in questo documento per renderlo evidente il più possibile...

5) Riferimenti internettistici

Bibliografia

6) Variante del generatore

Senza bisogno di usare Primi sicuri e di Sophie Germain

I primi sicuri sono ovviamente più rari dei primi normali e dunque questa variante consente una maggiore arbitrarietà di scelta dei primi. Nella precedente versione vengono scartati la metà dei numeri generati mentre con questa versione il numero di numeri scartati può essere sia più grande che più piccolo. Se la percentuale dei numeri scartati è più grande del 50% questa variante del generatore è più lenta di quella basata sull'eliminazione dei numeri dispari ma la pseudocasualità del numero accettato è maggiore mentre , viceversa, accettando una percentuale maggiore del 50% la velocità di generazione aumenta ma la pseudocasualità diminuisce. Questo difetto lo si può però correggere usando un maggior numero di numeri primi.

Come si vede, le operazioni da fare ad ogni passo sono un po' meno di quelle dell'altra versione e se il terzo intero ossia kaso[k][3], pur essendo obbligatoriamente più piccolo del primo a lui corrispondente ossia kaso[k][2], è quasi uguale a lui, il numero di numeri scartati diventa piccolo con il solo svantaggio che risultano meno casuali ma se già lo sono, questo inconveniente non è grave...

Sottolineo che, per garantire il corretto funzionamento dell'algoritmo è OBBLIGATORIO che kaso[k][0] sia un numero positivo minore di kaso[k][2], inoltre kaso[k][1] deve essere una radice primitiva del numero primo kaso[k][2] ed ovviamente tutti i numeri primi usati debbono essere diversi l'uno dall'altro... ed infine kaso[k][3] deve essere minore di kaso[k][2] ma non c'è il vincolo che sia un numero primo ma tutti i kaso[k][3] DEBBONO essere PRIMI TRA LORO ossia il massimo comune divisore ( in inglese : gcd ) tra ciascuna coppia di loro deve essere sempre 1.

Infine per garantire che tutti i numeri estratti abbiano una esattamente identica probabilità di estrazione bisogna scegliere uno solo dei kaso[k][3] in modo che sia divisibile esattamente per kbase ma rispettare comunque il vincolo che tutti i kaso[k][3] non abbiano tra loro alcun divisore comune.
Qui ci sono esempi che evidenziano questo rischio ossia esempi in cui si vede che NON SI HA una probabilità ESATTAMENTE uguale se kbase possiede un divisore comune con due numeri kaso[k][3]. È il caso di 6 o di 90 che hanno un fattore comune sia con 12987 ( il 3 ) che con 500 ( il 2 e con 90 anche il 5 ). Tuttavia, data la lunghezza del ciclo globale, la probabilità NON è ESATTAMENTE uguale ma è QUASI UGUALE.... Provare per constatarlo direttamente !

I risultati di queste sperimentazioni vengono scritti nei capitoli immediatamente successivi a questo...

...
...Clicca per leggere il tipo di problema scelto...

7a) A calcolo terminato visualizza la numerosità delle estrazioni

Visualizza, numero per numero, l'ultima volta che è stato estratto e, soprattutto, QUANTE VOLTE OGNI NUMERO E' STATO ESTRATTO. Se il ciclo è stato fatto tutto, tutti i numeri devono essere stati estratti nella stessa quantità.

...Scegliere il caso da fare ... ma funziona solo se Javascript funziona ...

7b) A calcolo terminato visualizza i ritardi che si sono verificati.

Visualizza un importante segnalatore della casualità dell'estrazione ossia il numero di ritardi registrati nella estrazione di un numero. Se l'estrazione non fosse casuale ogni numero verrebbe estratto con un ritardo costante ma se l'estrazione è veramente casuale sono possibili, anche se rari, ritardi enormi. Qui, oltre al numero delle volte che si è registrato un dato ritardo, specifico anche l'ultimo numero che ha avuto quel ritardo e a quale passo quel ritardo si è verificato per l'ultima volta.

...Scegliere il caso da fare ... ma funziona solo se Javascript funziona ...

7c) A calcolo terminato visualizza qualche numero estratto alla fine...

Visualizza alcune estrazioni ottenute alla fine del calcolo...

...Scegliere il caso da fare ... ma funziona solo se Javascript funziona ...

8) Qualche grosso primo utile
Per evitare di dovere fare indagini con wxMaxima scrivo qui alcuni grossi primi di poco superiori ai 10 miliardi e dotati tutti della stessa radice primitiva 123457. In questo modo, lavorando in Javascript non faccio mai overflow ed usando una radice primitiva grossa ho la forte probabilità di generare anche usando un solo primo una buona sequenza pseudocasuale apparentemente molto casuale.

[10000000259, 10000002263, 10000003199, 10000005347, 10000006967, 10000007327, 10000007387, 10000008443, 10000009763]

Ovviamente al minimo, con questo algoritmo andrebbero usati DUE numeri primi e come massimo primo accettato si può usare il numero primo precedente ( per esempio usando 10000009763 come primo usare 10000008443 come intero limite ) e come numero limite al primo primo, usare un grosso intero non primo che però sia esattamente divisibile per il numero di base che si vuole generare a caso ossia, per esempio, 37 se si vuole simulare una roulette, o 6 se si vuole simulare il lancio di un dado o 90 se si vuole simulare l'estrazione di un numero del lotto...
9) Conclusioni

Conclusione

Se ipotizziamo che l'Universo abbia una età minore di un migliaio di miliardi di anni ossia un milione di milioni di anni e se suddividiamo un anno in un miliardo di istanti, ogni istante dura circa 3 centesimi di secondo per cui generando un numero pseudocasuale ogni 3 centesimi di secondo ( una frequenza simile alla successione dei fotogrammi di un film ), per generarne un migliaio di miliardi di miliardi non basterebbe l'intera età attuale dell' Universo. Con questo algoritmo posso facilmente ottenere un periodo di ripetizione di un miliardo di miliardi di miliardi di passi... Chi vorrebbe sostenere che i numeri generati siano solo PSEUDOCASUALI ?