GitHub - gcomneno/digit-probe: Analizzatore statistico e strutturale per sequenze numeriche — valuta casualità, uniformità, compressione, autocorrelazione, prevedibilità n-gram e schemi additivi di tipo Schur su dati di cifre o interi. (original) (raw)

Analizzatore statistico/strutturale per sequenze numeriche.

Supporta:

Pensato per diagnosticare random-like vs struttura in stream numerici e per ispezionare bucket prodotti da strumenti esterni: (es. Turbo-Bucketizer) (o Turbo-Bucketizer-2)


✨ Cosa misura

Output: stampa leggibile + JSON opzionale con --report-json (compatibile con compare_reports.py).


🚀 Installazione

Richiede Python 3.11+ (ok anche 3.13).

python3 -m venv .venv source .venv/bin/activate pip install -r requirements.txt # leggero: usa solo stdlib + pochi pacchetti

Suggerito: tenere i dataset/risultati fuori dal versionamento (.gitignore già predisposto).


🧩 Struttura repo (essenziale)

src/ digit_probe.py # core analyzer (CLI) compare_reports.py # confronto tra più JSON make_datasets.py # generatori semplici (pi, e, gradienti, ecc.) generative/ gen_rng_digits_zoo.py # RNG Zoo per test di regressione gen_rng_1_90.py # (opzionale) generatori su 1..90

tests/ basic.sh # smoke test rapido advanced.sh # test avanzati (gradienti, bucket, schur-stress) test_rng_digits_ci.py # test di regressione RNG Zoo

datasets/ pi_100k.txt # esempi offline e_100k.txt ... Makefile


⌨️ Uso rapido

Modalità digits (cifre senza spazi “logici”)

python3 src/digit_probe.py --file pi_100k.txt --report-json pi.json

Modalità integers (un intero per riga, serve --alphabet)

Esempio: bucket in [0..4095]

python3 src/digit_probe.py --file buckets_k12.txt --integers --alphabet 4096 --report-json buckets.json

Opzioni principali

--file PATH             input (digits o integers)
--n N                   limita la lunghezza analizzata
--integers              abilita modalità "integers"
--alphabet M            alfabeto per integers (obbligatorio con --integers)
--report-json OUT.json  salva un report JSON
--schur-N R             R massimo per SchurProbe (default: 5000)

🧷 Guida rapida – come preparare un tuo dataset

1. Decidi il tipo di sequenza

2. Preparazione file per modalità digits

Formato consigliato: file di testo con solo cifre (più eventuali newline).

Esempi:

Estrai solo cifre e scrivi in mydigits.txt

tr -cd '0-9' < raw_input.txt > mydigits.txt

3. Preparazione file per modalità integers

Formato: un intero per riga.

Esempi:

4. Confrontare più dataset

Una volta che hai i tuoi JSON (--report-json), puoi confrontarli:

python3 src/compare_reports.py out/mio_dataset.json out/rng_uniform.json --baseline out/rng_uniform.json --md out/compare_mio_vs_rng.md

Questo produce un Markdown con:


🧪 RNG Zoo & test di regressione (CI)

Il progetto contiene una piccola RNG Zoo a cifre per verificare che gli strumenti diagnostici non si rompano nel tempo:

Dataset generati da src/generative/gen_rng_digits_zoo.py:

La CI (GitHub Actions) lancia pytest e verifica che:

Se cambiano algoritmi/parametri interni e questi test iniziano a fallire, è un campanello d’allarme: qualcosa nel motore di analisi si è degradato.


📦 Dataset “famosi” (offline)

Genera 100k cifre di π o e senza rete:

python3 src/make_datasets.py --n 100000 --only pi --offline python3 src/make_datasets.py --n 100000 --only e --offline

Poi analizza:

python3 src/digit_probe.py --file pi_100k.txt --report-json pi.json python3 src/digit_probe.py --file e_100k.txt --report-json e.json


🧪 Suite di test

Comandi:

make test-basic # random, pi (offline), sequenza costante make test-advanced # gradiente, bucket (sintetico o Turbo), schur-stress make selftest # aggrega i JSON in out/SELFTEST_SUMMARY.md

Se hai Turbo-Bucketizer e vuoi usarlo davvero nei test avanzati:

TURBO_BIN=/percorso/turbo-bucketizer make test-advanced

Risultati in out/ (JSON + Markdown di confronto).


🔍 Confronto report (più file)

Confronta due o più JSON:

python3 src/compare_reports.py out/pi.json out/e.json --baseline out/pi.json --md out/compare_pi_e.md

Output sintetico (ordinabile) con indicatori di severità e AnomalyScore.


📘 Esempi interpretativi (due dritte)


🧠 SchurProbe in due righe

Su R simboli (cap a --schur-N), testiamo tutte le coppie i<j e chiediamo se la “somma mod M” riappare in posizione k=(i+j) mod R. Atteso “casuale”: 1 volta su M. Misuriamo quanto te ne discosti con uno z-score binomiale standard.


🔗 Integrazione con Turbo-Bucketizer


🧾 JSON di output (schema minimo)

{ "mode": "digits|integers", "N": 100000, "alphabet": 10, "chi_square": 4.093, "expected_per_bin": 10000.0, "counts": {"0":9999, "1":10137, ...}, "runs": {"Z": 0.565, "p_two_tailed": 0.5724}, "autocorr": {"1": -0.0025, "2": 0.0022, ...}, "compress_ratio": 0.4817, "ngram": {"1": 0.1013, "2": 0.1026, "3": 0.0998}, "schur": { "triples": 12497500, "count": 124749, "expected": 125777.4, "fraction": 0.00998, "z": -2.91, "first_violation_index": 59 } }


🛠️ Note pratiche


Case study


📄 Licenza

MIT. Vedi LICENSE.


💡 Motto

“Se è random-like, non lo è per sempre. Se è strutturato, lo becchiamo.”