Velocità della luce
This commit is contained in:
+74
-75
@@ -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"""
|
||||
|
||||
Reference in New Issue
Block a user