# Assunzioni Ogni assunzione ha un identificativo (A1, A2, …) richiamato nel codice e negli altri documenti. Per ognuna: cosa si assume, perché è ragionevole, **dove** il codice ne dipende e **cosa succede se è falsa**. Le assunzioni sul segnale valgono per i dati del generatore `../gen_data` (sezione finale): su dati reali vanno verificate. ## Dati | ID | Assunzione | Dove | Se è falsa | |---|---|---|---| | **A1** | Il tempo è **strettamente crescente**, anche non uniforme (jitter del campionamento) | `dati.leggi_csv` | il CSV è rifiutato (exit 4). Il programma non riordina né deduplica | | **A2** | Il CSV ha l'intestazione e tutte le colonne richieste da `[dati]` (tempo e serie), tutte numeriche, senza celle vuote | `dati.leggi_csv` | exit 4 con il nome della colonna mancante | | **A3** | Il tempo è in `ms` o `s` come dichiarato in `[dati] unita_tempo` | `dati.leggi_csv` | tutti i tempi e le costanti $\tau$ risultano scalati di 1000 senza avvisi: controlla l'unità | | **A4** | Le serie condividono gli **stessi domini** (stessi istanti di rottura) | `analisi.analizza_domini`, `domini.proponi` | i domini sono cercati solo su `serie_riferimento` (default `T_C`); una serie con gradini diversi non è gestita: si lancia l'analisi due volte | ## Struttura del segnale | ID | Assunzione | Dove | Se è falsa | |---|---|---|---| | **A5** | I **gradini di riscaldamento** sono salti positivi tra due campioni consecutivi molto più grandi del rumore **e** degli scarti casuali: `soglia_gradino_c` (20 °C) $\gg$ ampiezza massima degli scarti (≤ 4 °C) | `domini.trova_gradini` | gradini più piccoli della soglia non sono visti (il segnale resta un unico tratto); scarti più grandi della soglia sono scambiati per gradini. Soluzione: adattare la soglia o correggere `domini.toml` a mano | | **A6** | La **salita dura pochi campioni** (2–3): il sensore ha costante di tempo ($\tau_\text{sensore} \approx 0.07$ s) minore dell'intervallo di campionamento (≈ 0.15 s) | `domini.trova_gradini` (estensione ai campioni adiacenti), `analisi._gradino` | con un sensore più lento la salita avrebbe più campioni: verrebbe comunque raggruppata finché il salto resta sopra `soglia_bordo_sigma`$\cdot\sigma$, ma non sarebbe fittata | | **A7** | Dopo ogni gradino la temperatura **decade esponenzialmente** verso un asintoto: $y = c + A\,e^{-t'/\tau}$ | `modelli.MODELLI["esp_decad"]` | residui sistematici, `ρ₁` alto, «modello non adeguato». Con più processi di raffreddamento servirebbe un modello a più esponenziali (non presente, vedi [limiti.md](limiti.md)) | | **A8** | Tutti i raffreddamenti hanno la **stessa costante di tempo $\tau$ e lo stesso asintoto $c$** (stesso processo fisico: dispersione verso l'ambiente). Anche nel generatore il decadimento dopo più gradini è la somma di esponenziali con lo stesso $k$, quindi un'unica esponenziale | `analisi.analizza_domini` (parametri `raffreddamento_intermedio_fissa_da_finale`) | gli intermedi sono forzati a $\tau$ e $c$ del finale: se in realtà differiscono, il fit dell'ampiezza $A$ è distorto e i residui lo mostrano. Per rimuovere il vincolo: `raffreddamento_intermedio_fissa_da_finale = []` | | **A9** | Il **raffreddamento finale** è l'ultimo dominio ed è abbastanza lungo (centinaia di campioni) da stimare $c$, $A$, $\tau$ **liberamente** | `analisi.analizza_domini` | se il CSV finisce subito dopo un gradino, il finale è corto e $\tau$ può risultare non identificabile; allora anche gli intermedi restano liberi e possono essere indeterminati | | **A10** | Il **riposo** (prima del primo gradino) è una baseline costante, lineare o esponenziale lenta (l'ambiente che si assesta) | `[fit.modelli_per_tipo] riposo` | il modello scelto è solo descrittivo: con una deriva lenta vince `lineare` o `esp_decad` | | **A11** | Ogni dominio è **indipendente**: nessun vincolo di continuità tra domini | `analisi` | i modelli adiacenti possono non combaciare ai confini; il «salto» tra due raffreddamenti è il gradino | | **A12** | Non esistono gradini **discendenti** (un calo brusco non è un evento): si cercano solo salti positivi | `domini.trova_gradini` (`d > soglia`) | un calo brusco resterebbe dentro un raffreddamento, aumentando RMSE e $\rho_1$ | ## Rumore | ID | Assunzione | Dove | Se è falsa | |---|---|---|---| | **A13** | Il rumore è circa **gaussiano bianco**, con $\sigma$ stimabile per dominio da $\sigma = 1.4826\,\mathrm{MAD}(\Delta^2 y)/\sqrt{6}$ | `domini.sigma_rumore` | $\sigma$ sottostimata: più domini risultano «non adeguati». La stima ignora la parte lenta del rumore (vedi A14) | | **A14** | Sul rumore bianco si aggiungono **disturbi che il modello non descrive**: deriva lenta (Ornstein–Uhlenbeck, $\tau \approx 3.5$ s) e **scarti casuali** (±4 °C, rientro < 1 s) | `fit.adatta` (perdita robusta), `uscita` (residui) | sono trattati come outlier dalla perdita `soft_l1` (non spostano molto il fit) ma lasciano residui autocorrelati ($\rho_1 \approx 0.7$) e intervalli di confidenza troppo stretti. Non è un errore del fit | | **A15** | La **quantizzazione** (T a 0.01 °C, ambiente a 0.1 °C) è trascurabile rispetto al rumore | — | nessun trattamento specifico | ## Statistica | ID | Assunzione | Dove | Se è falsa | |---|---|---|---| | **A16** | Gli intervalli al 95 % sono **gaussiani asintotici**: $\pm 1.96\,\sigma_p$ con $\mathrm{cov} = s^2 (J^\top J)^{-1}$, $s^2 = \mathrm{RSS}/(n-k)$ | `fit.adatta` | con pochi campioni o residui non gaussiani sono approssimati | | **A17** | L'autocorrelazione dei residui è di tipo AR(1): gli errori si allargano di $\sqrt{(1+\rho_1)/(1-\rho_1)}$ se $\rho_1$ supera `soglia_acf` | `fit.adatta` | correzione approssimata; con autocorrelazione di altra forma gli intervalli restano stretti | | **A18** | Per i parametri **fissi** l'incertezza non si propaga: gli intervalli di $A$ nei raffreddamenti intermedi sono **condizionati** a $c$ e $\tau$ del finale | `fit.adatta`, `uscita._params` | sono sottostimati rispetto all'incertezza totale | | **A19** | AICc e BIC si calcolano da $\mathrm{RSS}$ come se i residui fossero gaussiani, anche se il fit usa la perdita robusta | `fit.adatta` | confronto tra modelli approssimato; sensibile agli outlier | | **A20** | Le serie con $\sigma$ non finita o nulla (dominio troppo corto) usano scala 1 per la perdita robusta | `fit.adatta` | solo robustezza ridotta | ## Progetto | ID | Assunzione | Dove | |---|---|---| | **A21** | La **suddivisione in domini la decide l'utente**: la proposta automatica è modificabile (`domini.toml`) e il fit non la cambia mai | `cli._passo_domini`, `domini.leggi_toml` | | **A22** | Il programma è **deterministico**: nessuna partenza casuale, nessun seme | `fit._partenza` (griglia su $\tau$, minimi quadrati lineari) | | **A23** | Il **riscaldamento non si fitta** (2–3 campioni): si riporta il salto $\Delta = y_\text{fine salita} - y_\text{prima}$, che è una stima per difetto del gradino reale perché parte della salita può cadere sul campione precedente | `analisi._gradino` | | **A24** | I **modelli provati** sono fissati per tipo di dominio in configurazione, non scelti dal programma | `[fit.modelli_per_tipo]` | ## Origine dei dati di prova (`../gen_data`) I CSV in `input/gen_.csv` sono prodotti dal generatore con la sua configurazione d'esempio. Caratteristiche che fondano le assunzioni sopra (dettaglio: `../gen_data/docs/SPEC.md` e `../gen_data/config.toml`): | Aspetto | Valore nel generatore | Assunzioni | |---|---|---| | intervallo di campionamento | 150.5 ms con jitter ±0.6 ms | A1, A6 | | gradini di riscaldamento | 3, a ≈ 15.7, 17.8, 21.7 s, ampiezza ≈ 88, 75, 65 °C (perturbati per seed) | A5, A7 | | raffreddamento | $k = 0.063\ \mathrm{s^{-1}}$, cioè $\tau = 15.9$ s (perturbato del 2 % per seed) | A7, A8 | | risposta del sensore | filtro del primo ordine, $\tau_\text{sensore} = 0.07$ s | A6 | | rumore bianco | $\sigma = 0.11$ °C a freddo, $0.20$ a caldo; la stima per dominio dà ≈ 0.08–0.3 | A13 | | deriva lenta | Ornstein–Uhlenbeck, $\sigma = 0.04$ °C, $\tau = 3.5$ s | A14 | | scarti casuali | in riscaldamento: 0.8 Hz, $\sigma$ 2.5 °C; in raffreddamento: 0.25 Hz, media −1 °C; ampiezza ≤ 4 °C, rientro 0.3–0.7 s | A5, A14 | | ambiente | $23.1 - 0.45\,e^{-t/58}$ °C, non sale quando T è alta | A10; $c$ di `dT_C` ≈ 0 | | `dT_C` | $T - T_\text{amb}$ calcolato dopo rumore e quantizzazione di entrambi i canali | A4 |