SPB Git

spb/wp29_uqo

Public
3.6 KB · 86 lines python
1"""F5-conf-03: regenerate out/results.json and out/counterexample.csv from data/ only.2Run from workspace root: ~/wp29/venv/bin/python out/analysis.py3"""4import json, os5import numpy as np6import pandas as pd7from scipy import stats89os.makedirs("out", exist_ok=True)10props = pd.read_csv("data/propositions.csv")11design = pd.read_csv("data/design.csv")12d = dict(zip(design["parameter"], design["value"]))13seed = int(d["seed"]); n = int(d["n"])1415data_issues = []16if set(props["id"]) != {"A", "B"}:17    data_issues.append({"issue": "unexpected proposition ids", "handling": "reported"})1819# Verdicts rest on the mathematical argument in out/argument.md, not on simulation.20statement_A_true = False   # counterexample: Y = S*X, S Rademacher independent of X21statement_B_true = True    # independent normals: characteristic functions multiply2223rng = np.random.default_rng(seed)24x = rng.standard_normal(n)25s = rng.choice(np.array([-1.0, 1.0]), size=n)   # independent Rademacher sign26y = s * x27z = x + y28pd.DataFrame({"x": x, "y": y}).to_csv("out/counterexample.csv", index=False)2930def ks_vs_fitted(v):31    return float(stats.kstest(v, "norm", args=(v.mean(), v.std(ddof=1))).statistic)3233cv = {34    "construction": "X ~ N(0,1); S independent of X with P(S=1)=P(S=-1)=1/2; Y = S*X. "35                    "Then Y ~ N(0,1) by symmetry of N(0,1), but X+Y = (1+S)X equals 0 with prob. 1/2 "36                    "and 2X (N(0,4)) with prob. 1/2: a non-degenerate law with an atom at 0, hence not normal.",37    "n": int(n), "seed": seed,38    "mean_x": float(x.mean()), "sd_x": float(x.std(ddof=1)),39    "mean_y": float(y.mean()), "sd_y": float(y.std(ddof=1)),40    "mean_sum": float(z.mean()), "sd_sum": float(z.std(ddof=1)),41    "ks_sum_vs_normal": ks_vs_fitted(z),42}4344# Supplementary diagnostics (illustration only)45diag = {46    "frac_sum_exactly_zero": float(np.mean(z == 0.0)),47    "ks_x_vs_std_normal": float(stats.kstest(x, "norm").statistic),48    "ks_y_vs_std_normal": float(stats.kstest(y, "norm").statistic),49    "ks_x_vs_fitted_normal": ks_vs_fitted(x),50    "ks_y_vs_fitted_normal": ks_vs_fitted(y),51    "corr_xy": float(np.corrcoef(x, y)[0, 1]),52}53# Population sup distance between law of X+Y (0.5*delta_0 + 0.5*N(0,4)) and N(0,2)54# (normal with the same mean 0 and variance 2), on a fine grid incl. both sides of the jump at 0.55grid = np.linspace(-10, 10, 200001)56F_mix = 0.5 * (grid >= 0) + 0.5 * stats.norm.cdf(grid, scale=2.0)57F_mix_left = 0.5 * (grid > 0) + 0.5 * stats.norm.cdf(grid, scale=2.0)58G = stats.norm.cdf(grid, scale=np.sqrt(2.0))59diag["population_ks_sum_vs_N02"] = float(max(np.abs(F_mix - G).max(), np.abs(F_mix_left - G).max()))60diag["ks_95pct_critical_value_approx"] = float(1.358 / np.sqrt(n))6162# Baseline for B (independent case), same seed stream continued, same KS rule63xb = rng.standard_normal(n); yb = rng.standard_normal(n)64baseline = {"baseline_b_ks_sum_vs_normal": ks_vs_fitted(xb + yb),65            "baseline_b_sd_sum": float((xb + yb).std(ddof=1))}6667results = {68    "task_id": "F5-conf-03",69    "statement_true": statement_A_true,70    "counterexample_provided": True,71    "counterexample_values": cv,72    "statement_b_true": statement_B_true,73    "feasibility": "complete",74    "feasibility_reason": None,75    "data_issues": data_issues,76    "n_input_rows": {"propositions.csv": int(len(props)), "design.csv": int(len(design))},77    "n_analysed": int(n),78    "random_seed": seed,79    "counterexample_diagnostics": diag,80    **baseline,81}82with open("out/results.json", "w") as f:83    json.dump(results, f, indent=2)84print(json.dumps({k: results[k] for k in ("statement_true", "statement_b_true")}),85      "KS(sum)=%.4f" % cv["ks_sum_vs_normal"], "baseline KS(B)=%.4f" % baseline["baseline_b_ks_sum_vs_normal"])86
Files · main
Menu

Theme