File size: 4,491 Bytes
515b676 | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 | """Aggregate the sweeps into slopes, ratios and the numbers quoted in pages/."""
import glob
import json
import os
import numpy as np
import rdpg
R = 5
def load(tag):
with open(f"outputs/main_{tag}.json") as f:
return json.load(f)
def agg(tag):
d = load(tag)
runs = d["runs"]
ns = sorted({r["n"] for r in runs})
by = {n: [r for r in runs if r["n"] == n] for n in ns}
out = {"tag": tag, "ngrid": ns, "reps": [len(by[n]) for n in ns], "dims": d["dims"]}
def col(f):
return [float(np.mean([f(r) for r in by[n]])) for n in ns]
def colmed(f):
return [float(np.median([f(r) for r in by[n]])) for n in ns]
out["err_mean"] = {str(dd): col(lambda r, dd=dd: r["err"][str(dd)]) for dd in d["dims"]}
out["err_se"] = {str(dd): [float(np.std([r["err"][str(dd)] for r in by[n]], ddof=1)
/ np.sqrt(len(by[n]))) for n in ns] for dd in d["dims"]}
out["base_mean"] = col(lambda r: r["base_2inf"])
out["trail_mean"] = {str(dd): col(lambda r, dd=dd: r["trail_2inf"][str(dd)])
for dd in d["dims"] if dd > R}
out["deloc_all_mean"] = col(lambda r: r["deloc_max_all"])
out["deloc_all_med"] = colmed(lambda r: r["deloc_max_all"])
out["deloc_rp1_mean"] = col(lambda r: r["deloc_max_rp1"])
out["deloc_rp1_med"] = colmed(lambda r: r["deloc_max_rp1"])
out["signal_2inf_mean"] = col(lambda r: r["signal_2inf"])
out["min_decomp_slack"] = float(min(min(r["decomp_slack"].values()) for r in runs))
out["s_hat_mean"] = [float(np.mean([r["s_hat"][i] for r in by[ns[-1]]])) for i in range(8)]
lg = np.log(np.array(ns, float))
out["slopes"] = {k: rdpg.loglog_slope(ns, v) for k, v in out["err_mean"].items()}
out["slopes_trail"] = {k: rdpg.loglog_slope(ns, v) for k, v in out["trail_mean"].items()}
out["slope_base"] = rdpg.loglog_slope(ns, out["base_mean"])
out["slope_deloc_all"] = rdpg.loglog_slope(ns, out["deloc_all_mean"])
out["slope_deloc_rp1"] = rdpg.loglog_slope(ns, out["deloc_rp1_mean"])
# remove the sqrt(log n) factor that delocalised max-entry statistics carry
out["slope_deloc_rp1_delogged"] = rdpg.loglog_slope(
ns, np.array(out["deloc_rp1_mean"]) / np.sqrt(lg))
out["deloc_rp1_over_sqrt2logn"] = [
float(v / np.sqrt(2 * np.log(n) / n)) for v, n in zip(out["deloc_rp1_mean"], ns)]
out["deloc_all_over_sqrt4logn"] = [
float(v / np.sqrt(4 * np.log(n) / n)) for v, n in zip(out["deloc_all_mean"], ns)]
out["theorem31_bound_gamma0"] = [float(R ** 2 * np.log(n) ** 4 / np.sqrt(n)) for n in ns]
out["theorem31_bound_holds"] = bool(all(
v <= b for v, b in zip(out["deloc_all_mean"], out["theorem31_bound_gamma0"])))
# over-specification: strip the predicted sqrt(log n)
out["slopes_delogged"] = {k: rdpg.loglog_slope(ns, np.array(v) / np.sqrt(lg))
for k, v in out["err_mean"].items()}
out["slopes_trail_delogged"] = {k: rdpg.loglog_slope(ns, np.array(v) / np.sqrt(lg))
for k, v in out["trail_mean"].items()}
# predicted trailing-term constant sqrt(4 sigma k log n) n^{-1/4} check
return out
if __name__ == "__main__":
tags = sorted(os.path.basename(p)[5:-5] for p in glob.glob("outputs/main_*.json"))
A = {t: agg(t) for t in tags}
with open("outputs/analysis.json", "w") as f:
json.dump(A, f, indent=1)
for t in tags:
a = A[t]
print(f"\n===== {t} n={a['ngrid']} reps={a['reps']}")
print(" d : slope R2 | delogged slope | err(n_max)")
for dd in a["dims"]:
s = a["slopes"][str(dd)]
sd = a["slopes_delogged"][str(dd)]
print(f" {dd:2d}: {s[0]:+.3f} {s[2]:.3f} | {sd[0]:+.3f} {sd[2]:.3f} |"
f" {a['err_mean'][str(dd)][-1]:.4f}")
print(f" base slope {a['slope_base'][0]:+.3f} (R2 {a['slope_base'][2]:.3f})"
f" min decomposition slack {a['min_decomp_slack']:.3e}")
print(f" deloc(all>r) slope {a['slope_deloc_all'][0]:+.3f}"
f" ratio to sqrt(4 log n/n): {[round(x,3) for x in a['deloc_all_over_sqrt4logn']]}")
print(f" deloc(r+1) slope {a['slope_deloc_rp1'][0]:+.3f}"
f" delogged {a['slope_deloc_rp1_delogged'][0]:+.3f}"
f" ratio to sqrt(2 log n/n): {[round(x,3) for x in a['deloc_rp1_over_sqrt2logn']]}")
print(f" s_hat(n_max)[:8] {[round(x,1) for x in a['s_hat_mean']]}")
|