Velocità della luce

This commit is contained in:
2026-11-09 18:20:54 +01:00
parent 8425ff90da
commit 4d25330361
9 changed files with 423 additions and 76 deletions
+74 -75
View File
@@ -185,9 +185,15 @@ def _(np, pd, stats):
valori_puliti, rimossi = rimuovi_outlier(valori, err_strum)
n = len(valori_puliti)
s = valori_puliti.std(ddof=1)
if err_della_media: s /= np.sqrt(n)
u = np.sqrt(s**2 + err_strum**2)
if n > 2:
s = valori_puliti.std(ddof=1)
if err_della_media:
s /= np.sqrt(n)
u = np.sqrt(s**2 + err_strum**2)
else:
s = 0.0
u = float(err_strum)
self.analisi_stat.loc[i, prefix] = valori_puliti.mean()
self.analisi_stat.loc[i, f"u{prefix}_strum"] = err_strum
@@ -199,7 +205,7 @@ def _(np, pd, stats):
return self
Data.stat_chauv = stat_chauv
return
return (trova_outlier,)
@app.cell(hide_code=True)
@@ -207,90 +213,83 @@ def _(mo):
mo.md(r"""
# Media pesata
input:
- array x: valori
- array ux: uvalori
output:
- xm: x medio
- uxm: sigma x medio
- chi2: $\chi^2$
- dof: gradi di libertà
- Pchi2: $P(\chi^2)$
**media_pesata( x, ux, chauvenet=True, info_outlier=False )**
*input:*
- array x: valori
- array ux: incertezze (tutte > 0)
- chauvenet: se True applica il criterio di Chauvenet gia' definito
(trova_outlier / p_t_student), con incertezza di_resolutione data
dall'RMS delle ux del campione
- info_outlier: se True aggiunge la lista dei punti scartati
*output:*
- xm: x medio
- uxm: sigma x medio
- chi2: chi quadro ridotto $\tilde\chi^2$
- dof: gradi di liberta
- Pchi2: $P(\chi^2)$
- out: [(valore, incertezza)] rimossi, solo se info_outlier=True
data:
- prefix: prefisso del nome della variabile
- prefix: prefisso del nome della variabile
""")
return
@app.cell
def _(np, stats):
def media_pesata(x, ux):
x, ux = np.asarray(x, float), np.asarray(ux, float)
w = 1 / ux**2
xm = np.sum(w * x) / np.sum(w)
uxm = 1 / np.sqrt(np.sum(w))
chi2 = np.sum(w * (x - xm) ** 2)
dof = len(x) - 1
return xm, uxm, chi2/dof, dof, stats.chi2.sf(chi2, dof)
def _(np, stats, trova_outlier):
def media_pesata(x, ux, chauvenet=True, info_outlier=False):
x, ux = np.asarray(x, float).ravel(), np.asarray(ux, float).ravel()
if x.shape != ux.shape:
raise ValueError("media_pesata: x e ux devono avere la stessa lunghezza")
validi = np.isfinite(x) & np.isfinite(ux)
x, ux = x[validi], ux[validi]
if len(x) and np.any(ux <= 0):
raise ValueError("media_pesata: tutte le incertezze devono essere > 0")
out = []
if chauvenet:
# Chauvenet gia' presente nel notebook: trova_outlier -> p_t_student
# qui l'incertezza di risoluzione e' l'RMS delle ux del campione corrente
while len(x) > 2:
idx = trova_outlier(x, np.sqrt(np.mean(ux**2)))
if idx is None:
break
out.append((x[idx], ux[idx]))
x = np.delete(x, idx)
ux = np.delete(ux, idx)
if len(x) == 0:
return np.nan, np.nan, np.nan, 0, np.nan, []
w = 1 / ux**2
xm = np.sum(w * x) / np.sum(w)
uxm = 1 / np.sqrt(np.sum(w))
chi2 = np.sum(w * (x - xm) ** 2)
dof = len(x) - 1
chi2_red = chi2 / dof if dof > 0 else np.nan
P = stats.chi2.sf(chi2, dof) if dof > 0 else np.nan
if info_outlier:
return xm, uxm, chi2_red, dof, P, out
return xm, uxm, chi2_red, dof, P
def media_pesata_data(self, prefix, chauvenet=True, info_outlier=False):
return media_pesata(self.analisi_stat[prefix],
self.analisi_stat[f"u{prefix}"],
chauvenet=chauvenet,
info_outlier=info_outlier)
def media_pesata_data(self, prefix):
return media_pesata(self.analisi_stat[prefix], self.analisi_stat[f"u{prefix}"])
Data.media_pesata = media_pesata_data
return
@app.cell
def _(np, stats):
def media_pesata_dersimonian_laird(x, ux):
x, ux = np.asarray(x, float), np.asarray(ux, float)
n = len(x)
dof = n - 1
if n <= 1:
raise ValueError("Il dataset deve contenere almeno due misure.")
if np.any(ux <= 0):
raise ValueError("Le incertezze (ux) devono essere strettamente maggiori di zero.")
# --- STEP 1: Calcolo standard (Effetti Fissi) per stimare il Chi2 originale ---
w_fixed = 1 / ux**2
sum_w_fixed = np.sum(w_fixed)
xm_fixed = np.sum(w_fixed * x) / sum_w_fixed
chi2_fixed = np.sum(w_fixed * (x - xm_fixed) ** 2)
# --- STEP 2: Stima della varianza extra (Tau^2) ---
# Formula di DerSimonian-Laird
sum_w2_fixed = np.sum(w_fixed**2)
numerator = chi2_fixed - dof
denominator = sum_w_fixed - (sum_w2_fixed / sum_w_fixed)
# Tau^2 non può essere negativo. Se il Chi2 è minore del dof, Tau^2 = 0
tau2 = max(0.0, numerator / denominator)
# --- STEP 3: Ricalcolo con Effetti Casuali (Random Effects) ---
w_random = 1 / (ux**2 + tau2)
sum_w_random = np.sum(w_random)
xm_random = np.sum(w_random * x) / sum_w_random
uxm_random = 1 / np.sqrt(sum_w_random)
# Nota: Il p-value finale del Chi2 si riferisce alla consistenza iniziale dei dati
p_value = stats.chi2.sf(chi2_fixed, dof)
return {
"media": xm_random,
"errore_media": uxm_random,
"tau2": tau2,
"tau": np.sqrt(tau2),
"chi2_originale": chi2_fixed,
"dof": dof,
"p_value": p_value
}
return
@app.cell(hide_code=True)
def _(mo):
mo.md(r"""