SPB Git

spb/wp29_uqo

Public
3.2 KB · 76 lines python
1"""F5-conf-03: counterexample to 'sum of normals is normal' (Prop. A) and check of Prop. B.2Run from workspace root: ~/wp29/venv/bin/python out/analysis.py3Reads only data/; writes out/results.json and out/counterexample.csv deterministically."""4import json, os5import numpy as np6import pandas as pd7from scipy import stats89ROOT = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))10D = os.path.join(ROOT, "data"); O = os.path.join(ROOT, "out")1112props = pd.read_csv(os.path.join(D, "propositions.csv"))13design = pd.read_csv(os.path.join(D, "design.csv"))14issues = []15assert set(props["id"]) == {"A", "B"}, "propositions.csv must contain A and B"16p = dict(zip(design["parameter"], design["value"]))17seed = int(p["seed"]); n = int(p["n"])18assert n > 01920# ---- Counterexample to A: X ~ N(0,1), S independent Rademacher (+/-1 w.p. 1/2), Y = S*X.21# Y ~ N(0,1) by symmetry of N(0,1); X+Y = (1+S)X equals 0 w.p. 1/2 and 2X w.p. 1/2.22rng = np.random.default_rng(seed)23x = rng.standard_normal(n)24s = rng.choice(np.array([-1.0, 1.0]), size=n)25y = s * x26z = x + y27pd.DataFrame({"x": x, "y": y}).to_csv(os.path.join(O, "counterexample.csv"), index=False)2829def ks_fit(v):30    return float(stats.kstest(v, "norm", args=(v.mean(), v.std(ddof=1))).statistic)3132cv = {33    "construction": ("X ~ N(0,1); S independent of X with P(S=1)=P(S=-1)=1/2; Y = S*X. "34                     "Then Y ~ N(0,1), but X+Y = (1+S)X equals 0 with probability 1/2 and 2X otherwise "35                     "(atom at 0, non-constant), so X+Y is not normal."),36    "n": int(n), "seed": seed,37    "mean_x": float(x.mean()), "sd_x": float(x.std(ddof=1)),38    "mean_y": float(y.mean()), "sd_y": float(y.std(ddof=1)),39    "mean_sum": float(z.mean()), "sd_sum": float(z.std(ddof=1)),40    "ks_sum_vs_normal": ks_fit(z),41}42# Supplementary numerical checks (illustrative only, not proof)43checks = {44    "ks_x_vs_fitted_normal": ks_fit(x),45    "ks_y_vs_fitted_normal": ks_fit(y),46    "ks_x_vs_N01_pvalue": float(stats.kstest(x, "norm").pvalue),47    "ks_y_vs_N01_pvalue": float(stats.kstest(y, "norm").pvalue),48    "frac_sum_exactly_zero": float(np.mean(z == 0.0)),49    "theoretical_frac_sum_zero": 0.5,50    "theoretical_sd_sum": float(np.sqrt(2.0)),51    "ks_sum_vs_fitted_normal_pvalue": float(stats.kstest(z, "norm", args=(z.mean(), z.std(ddof=1))).pvalue),52}53# Baseline for Prop. B: independent X', Y' ~ N(0,1) (separate stream seeded [seed, 1]), sum vs N(0,2)54rngb = np.random.default_rng([seed, 1])55xb = rngb.standard_normal(n); yb = rngb.standard_normal(n)56checks["propB_ks_sum_independent_vs_N02"] = float(stats.kstest(xb + yb, "norm", args=(0.0, np.sqrt(2.0))).statistic)57checks["propB_ks_pvalue"] = float(stats.kstest(xb + yb, "norm", args=(0.0, np.sqrt(2.0))).pvalue)5859res = {60    "task_id": "F5-conf-03",61    "statement_true": False,62    "counterexample_provided": True,63    "counterexample_values": cv,64    "statement_b_true": True,65    "feasibility": "complete",66    "feasibility_reason": None,67    "data_issues": issues,68    "n_input_rows": {"propositions.csv": int(len(props)), "design.csv": int(len(design))},69    "n_analysed": int(n),70    "random_seed": seed,71    "numerical_checks": checks,72}73with open(os.path.join(O, "results.json"), "w") as f:74    json.dump(res, f, indent=2)75print(json.dumps(res, indent=2))76
Files · main
Menu

Theme