The validation package of Riemann Hypothesis over Finite Holographic Substrate: one script, rh.py, 3 blocks, Python with numpy, matplotlib, one check per predicate of the paper's predicate ledger — 107 of 107 checks passing. The script is rendered below with an anchor per line; its markers (# 20:B4 (p20011): the predicate and its key) are the checks the ledger predicates cite, and the block index opens each block at its definition. The notebook frc-20-rh.ipynb runs one cell per predicate on Google Colab. Installed from this site as a named requirement: pip install frc-20-rh --find-links https://finitering.space/pkg/ (the sdist frc-20-rh-20261021.tar.gz).
Blocks: A (21) · B (1) · C — the predicates each decides in parentheses.
1"""2rh.py — the validation package of "Riemann Hypothesis over Finite Holographic Substrate" (Akhtman & Voether, 2026; Preprints3doi 10.20944/preprints202606.0768.v1), the paper 20-rh of the FRC corpus (finite-ring-space/src/20-rh). One script since424 September 2026; rewritten with the paper on 17 October 2026 (reports/blueprint-20261017.md): the chart-side blocks of the5earlier versions (the de-framing dictionary's density and residue, the prime-side spectrum, the GUE statistic, the χ-twist,6Turing's count and certificate, the resonance) are gone with the rows they witnessed, and the exact checks of the shell carry7the paper.8========================================================================================================================910Three blocks, 107 checks — 91 EXACT (integer-pinned: a pass is a proof on the tested instances), 5 [approx] (a floating-point11reading of the chart's characters to a stated tolerance), 11 [chart] (a continuum reading of a finite object; notation.tex12convention 6) — Python with numpy and matplotlib (the paper's two drawn figures are redrawn into figures/paper/ as the blocks run; Figure 1 is the dimensions paper's).13Each check names the predicate(s) of the paper's ledger it witnesses (LEDGER; predicates cited as 20:XN), and the deciding14check's `# 20:XN (<key>)` marker is what the ledger's source column links (PREDICATES; finitering.space/py/rh.html#<key>).15Master-ledger predicates reached through the paper's rows: 00:A2 (Finitude, 20:A2), 00:A3 (Completeness, 20:A3) and 00:A416(Observation, 20:A4).1718Block A the shell, in exact arithmetic (EXACT, one [approx]; 20:A2, A3, A4, B1, B2, B4–B6, B8–B10, B12–B14, E12–E15, F7, F10, O9):19 the zero-slot, slot complementarity, the Hermitian phase calculus, the critical line, the two agreement loci among all20 affine lines, the Subject constants, the shell theorem's five clauses on random vectors, the Parseval identity, the21 critical line as the energy domain, frame coincidence below the horizon and on the line, no zero off the line, the22 closure, completeness, the generators that do not order the window, the drive theorem and the circle23Block B the chart ([chart]; 20:B8, F9, O9): the de-framing limit, the exhibit on the windows of depth 13, 39 and 173, the24 pair agreement on (173, 30089) and (1549, 2408561), and the labels read in the cycle's own scale coordinate25Block C the chart at depth ([chart]; 20:F9): the window of depth 10⁶ and the first ten heights; the figure fig_primespec2627 python3 rh.py every block in order, results.json written; exit 1 if a check fails (≈ 100 s on one core:28 block A 75 s, block C 20 s)29 python3 rh.py A B the blocks named (A, B, C); no results.json30 from frc_20_rh import predicate; predicate("20:B12") one predicate: the blocks of the checks citing it run once per session31"""32import os, json, sys, math, cmath, time, random33from fractions import Fraction34import numpy as np35import matplotlib36matplotlib.use("Agg")37import matplotlib.pyplot as plt38from matplotlib.patches import FancyArrowPatch3940SCRIPT = os.path.splitext(os.path.basename(__file__))[0] # "rh": the one script, the name results.json and the site pages carry41FIGDIR = os.environ.get("RH_FIGDIR", "figures")42os.makedirs(f"{FIGDIR}/paper", exist_ok=True)4344# ----------------------------------------------------------------------------- registry45RESULTS = []4647# The paper's predicate ledger (20-rh Appendix A, predicates cited as 20:XN): the predicate(s) each check witnesses. The48# ledger's source column cites these check ids in return. The check ids A8 and A9 are retired with their rows (the Lanczos49# matrix, the Ramanujan sum; 17 October 2026) and are not reused.50LEDGER = {51 "A1": "20:B4", "A2": "20:B5", "A3": "20:B6", "A4": "20:B8", "A5": "20:B9", "A6": "20:B10", "A6b": "20:B10",52 "A7": "20:E12, 20:E14", "A7b": "20:E13", "A10": "20:B1", "A11": "20:B2", "A12": "20:A2, 20:A4, 20:F7", "A13": "20:A3",53 "A14": "20:E13", "A15": "20:B12", "A16": "20:B13", "A17": "20:O9", "A18": "20:F10, 20:B9, 20:B13", "A19": "20:E15", "A20": "20:B14",54 "B3": "20:B8", "B5": "20:F9", "B6": "20:F9", "B8": "20:O9",55 "C1": "20:F9",56}5758BLOCK = {"A": "the shell, in exact arithmetic: the zero-slot, the critical line, the agreement loci, the shell theorem, the Parseval identity, the energy domain, frame coincidence, the closure, completeness, the window's order, the drive theorem, the circle",59 "B": "the chart: the de-framing limit, the exhibit on the windows 13, 39, 173, the pair agreement, the cycle's own scale coordinate",60 "C": "the chart at depth: the window of depth 10⁶ and the first ten heights; the figure fig_primespec"}6162# the deciding check of each python-witnessed predicate: the check the ledger's source column names (the other checks that63# cite it are corroboration, listed by predicate() from the records)64PREDICATES = {65 "20:B1": "A10", "20:B2": "A11", "20:B4": "A1", "20:B5": "A2", "20:B6": "A3", "20:B8": "A4", "20:B9": "A5", "20:B10": "A6",66 "20:B12": "A15", "20:B13": "A16", "20:A2": "A12", "20:A3": "A13", "20:A4": "A12", "20:F7": "A12",67 "20:E12": "A7", "20:E13": "A14", "20:E14": "A7", "20:F9": "B5", "20:O9": "A17", "20:F10": "A18", "20:E15": "A19", "20:B14": "A20",68}69_RAN = set() # blocks already run in this session (predicate() runs each once)7071def check(pid, label, ok, detail="", kind="EXACT"):72 """Record one predicate check. pid = package check id (A1, B5, ...); LEDGER[pid] = the paper's ledger predicate(s)."""73 ok = bool(ok)74 rows = LEDGER[pid]75 RESULTS.append({"id": pid, "rows": rows, "block": pid[0], "script": SCRIPT, "label": label, "ok": ok, "detail": detail, "kind": kind})76 print(f" [{'PASS' if ok else 'FAIL'}] {pid:4s} {kind:7s} [{rows}] {label}" + (f" -- {detail}" if detail else ""))77 return ok7879def summary(write=True):80 n_ok = sum(r["ok"] for r in RESULTS)81 print(f"\nSUMMARY: {n_ok}/{len(RESULTS)} checks passed" + ("" if n_ok == len(RESULTS) else " <-- FAILURES"))82 if write:83 with open("results.json", "w") as f:84 json.dump(RESULTS, f, indent=1)85 return n_ok == len(RESULTS)8687def markers():88 """predicate label -> (script file, line) of its marker `# <paper>:<label> (<key>)`: the line of the check that decides it."""89 import re90 out = {}91 for i, line in enumerate(open(os.path.abspath(__file__), encoding="utf-8"), 1):92 m = re.match(r"\s*# ((?:\d+:[A-Z]+\d+[a-z]?(?: \(p\d{5}\))?)(?:, \d+:[A-Z]+\d+[a-z]?(?: \(p\d{5}\))?)*)\s*$", line)93 if m:94 for lab in re.findall(r"\d+:[A-Z]+\d+[a-z]?", m.group(1)): out.setdefault(lab, (SCRIPT + ".py", i))95 return out9697def _run_block(letter):98 if letter not in _RAN:99 globals()[f"block_{letter}"](); _RAN.add(letter)100101def predicate(label, lines=14):102 """Verify one ledger predicate: run the blocks of the checks that cite it (each once per session), print the deciding check's103 source (from its marker) and every record that cites the predicate, and return True iff all pass."""104 pid = PREDICATES.get(label)105 if pid is None:106 print(f"{label}: no python witness (see the predicate's Lean witness or its source)"); return None107 citing = {i[0] for i, rows in LEDGER.items() if label in [t.strip() for t in rows.split(",")]}108 for b in sorted({pid[0]} | citing): _run_block(b) # the deciding block and every block whose checks cite the predicate109 mk = markers().get(label)110 if mk:111 src = open(os.path.abspath(__file__), encoding="utf-8").read().split("\n")112 print(f"— {mk[0]}:{mk[1]} (the check that decides {label}: {pid})")113 for j in range(mk[1] - 1, min(mk[1] - 1 + lines, len(src))): print(f"{j + 1:5d} {src[j]}")114 recs = [r for r in RESULTS if label in [t.strip() for t in r["rows"].split(",")]]115 ok = all(r["ok"] for r in recs)116 for r in recs:117 role = "(deciding)" if r["id"] == pid else "(corroborating)"118 print(f" [{'PASS' if r['ok'] else 'FAIL'}] {r['id']:4s} {role:16s} {r['detail'][:150]}")119 print(f"{label}: {'VERIFIED' if ok and recs else 'FAILED'} — {len(recs)} record(s)")120 return ok121122def verify_all():123 """Run every block (those already run in this session are not re-run) and print the summary; True iff every check passed."""124 for b in sorted(BLOCK): _run_block(b)125 return summary(write=False)126127# ----------------------------------------------------------------------------- the arithmetic of the shell (standard library)128SHELLS = [13, 17, 29, 37, 41] # in full129BIG = 173 # the laboratory Subject of (173, 30089): A1, A4, A6, A7, A14, A15130PAIRS = ((13, 233), (173, 30089), (1549, 2408561)) # the laboratory pairs (p, Ω), Ω the Carrier of the Subject p (Def. shells)131HEIGHTS = [14.134725, 21.022040, 25.010858, 30.424876, 32.935062, 37.586178, 40.918719, 43.327073, 48.005151, 49.773832]132# the first ten classical heights (Odlyzko's tables), validation markers of the chart blocks: never an input133134def is_prime(n):135 if n < 2: return False136 d = 2137 while d * d <= n:138 if n % d == 0: return False139 d += 1140 return True141142def next_prime(n):143 n += 1144 while not is_prime(n): n += 1145 return n146147def prime_factors(n):148 f, d = set(), 2149 while d * d <= n:150 while n % d == 0:151 f.add(d); n //= d152 d += 1153 if n > 1: f.add(n)154 return f155156def generator(p):157 """The least primitive root of F_p: the Subject's generator g, as the paper takes it."""158 for g in range(2, p):159 if all(pow(g, (p - 1) // q, p) != 1 for q in prime_factors(p - 1)):160 return g161162def nonresidue(p):163 sq = {(x * x) % p for x in range(1, p)}164 return next(v for v in range(2, p) if v not in sq)165166def dlog_table(p, g):167 """The discrete logarithm λ_p to the generator g on F_p^×, as a list indexed by the residue (λ[g^m] = m)."""168 lam, x = [0] * p, 1169 for m in range(p - 1):170 lam[x] = m; x = x * g % p171 return lam172173# F_{p^2} = F_p(η), η² = ν: elements (a, b) = a + bη; the conjugation φ, the half-turn ρ, the trace and the norm174def mul(z, w, nu, p):175 return ((z[0] * w[0] + nu * z[1] * w[1]) % p, (z[0] * w[1] + z[1] * w[0]) % p)176def frob(z, p): # z ↦ z^p : a + bη ↦ a − bη177 return (z[0], (-z[1]) % p)178def half_turn(z, p): # z ↦ 1 − z179 return ((1 - z[0]) % p, (-z[1]) % p)180def trace(z, p): return (2 * z[0]) % p181def norm(z, nu, p): return (z[0] * z[0] - nu * z[1] * z[1]) % p182def zpow(z, k, nu, p):183 r, b = (1, 0), z184 while k:185 if k & 1: r = mul(r, b, nu, p)186 b = mul(b, b, nu, p); k >>= 1187 return r188189def affine_lines(p):190 """The p(p+1) affine lines of the plane F_p² = {(a, b)}: the p lines H_b = {im = b} and the p² lines S_{c,a} = {re = a + c·im},191 each as (name, frozenset of its p points)."""192 out = [(("H", b), frozenset((a, b) for a in range(p))) for b in range(p)]193 out += [(("S", c, a), frozenset(((a + c * b) % p, b) for b in range(p))) for c in range(p) for a in range(p)]194 return out195196def dual(v, p):197 """The dual of a vector v on F_p^× (v[x] for x = 1..p−1): v̂(k) = Σ_x v(x) x^k for k = 0..p−2, in F_p."""198 return [sum(v[x] * pow(x, k, p) for x in range(1, p)) % p for k in range(p - 1)]199200def random_vectors(p, count, seed):201 rng = random.Random(seed)202 return [[0] + [rng.randrange(p) for _ in range(p - 1)] for _ in range(count)]203204# ----------------------------------------------------------------------------- the chart (numpy): the window's labels along the chart's scale205def mangoldt(N):206 """The prime-power labels n ≤ N with the chart's weight Λ(n) = log ℓ, as arrays (n, Λ(n))."""207 sieve = np.ones(N + 1, dtype=bool); sieve[:2] = False208 for i in range(2, int(N ** 0.5) + 1):209 if sieve[i]: sieve[i * i::i] = False210 ns, ls = [], []211 for q in np.nonzero(sieve)[0]:212 m = int(q)213 while m <= N:214 ns.append(m); ls.append(math.log(int(q))); m *= int(q)215 return np.array(ns, dtype=float), np.array(ls)216217def energy(H, gammas):218 """The exhibit's modulus |Σ_{n≤H} Λ(n)(1 − log n/log H) n^{−1/2−iγ}|, the square root of the intensity, along the chart's height γ [chart]."""219 n, lam = mangoldt(H)220 w = lam * (1 - np.log(n) / np.log(H)) * n ** -0.5221 ln = np.log(n)222 out = np.empty(len(gammas))223 for i, g in enumerate(gammas):224 out[i] = abs(np.sum(w * np.exp(-1j * g * ln)))225 return out226227def peaks(H, lo, hi, step=0.02):228 """The local maxima of the window's intensity on [lo, hi] at the grid step, as (γ, intensity), tallest first."""229 gam = np.arange(lo, hi + step / 2, step)230 e = energy(H, gam)231 pk = [(float(gam[i]), float(e[i])) for i in range(1, len(gam) - 1) if e[i] > e[i - 1] and e[i] > e[i + 1]]232 return sorted(pk, key=lambda t: -t[1])233234def five_peaks(H):235 """The window's five peaks: the five tallest peaks on the range 10 to 36 of the chart's height, by height."""236 return sorted(g for g, _ in peaks(H, 10, 36)[:5])237238def resolution(H): return 2 * math.pi / math.log(H)239240# ----------------------------------------------------------------------------- the paper's figures241# Drawn at the text width of the manuscript (452.97 pt = 6.29 in; a4, 1 in margins, 11 pt), so that \includegraphics scales242# nothing and the 8–9 pt type prints as drawn; no titles (the captions carry them), panel letters above the axes.243PURPLE, GREY, BLUE, GREEN, RED, INK = "#8e44ad", "#8a8f98", "#2b6fd6", "#2f9e44", "#d33b3b", "#1b1f24"244TEXTWIDTH_IN = 452.97 / 72.27245PAPER_RC = {"font.size": 8.5, "axes.labelsize": 9, "axes.titlesize": 9, "xtick.labelsize": 8, "ytick.labelsize": 8,246 "legend.fontsize": 7.8, "legend.frameon": True, "legend.framealpha": 0.92, "legend.edgecolor": "0.8",247 "axes.linewidth": 0.7, "xtick.major.width": 0.6, "ytick.major.width": 0.6, "lines.linewidth": 1.1,248 "axes.grid": False, "pdf.fonttype": 42, "mathtext.fontset": "cm", "font.family": "DejaVu Sans"}249250def panel_letter(ax, s, x=-0.02, y=1.03):251 """The panel letter above the axes' top-left corner, as the captions cite it."""252 ax.text(x, y, s, transform=ax.transAxes, ha="right", va="bottom", fontsize=9)253254def _save(fig, name):255 fig.savefig(f"{FIGDIR}/paper/{name}.pdf", bbox_inches="tight", pad_inches=0.02)256 fig.savefig(f"{FIGDIR}/paper/{name}.png", dpi=220, bbox_inches="tight", pad_inches=0.02)257 plt.close(fig)258 print(f" wrote {FIGDIR}/paper/{name}.pdf")259260def figure_primespec():261 """fig_primespec: (a) the intensity of the windows 13, 39, 173 along the chart's scale; (b) depth 10⁶ (Obs. exhibit) [chart]."""262 gam = np.arange(10, 52, 0.02)263 with plt.rc_context(PAPER_RC):264 fig, axes = plt.subplots(2, 1, figsize=(TEXTWIDTH_IN, 4.2), gridspec_kw={"height_ratios": [1.2, 1]})265 ax = axes[0]266 for H, color, label in ((13, GREEN, r"$H=13$ (the window of $\mathbb{F}_{173}$)"), (39, BLUE, r"$H=39$ ($\mathbb{F}_{1549}$)"), (173, PURPLE, r"$H=173$ ($\mathbb{F}_{30089}$)")):267 e = energy(H, gam)268 ax.plot(gam, e / e.max(), color=color, lw=1.1, label=label)269 ax.axvspan(10, 36, color="#eef2f8", zorder=0) # the range of the Observation's claims270 for z in HEIGHTS:271 ax.axvline(z, color=GREY, lw=0.6, ls="--", alpha=0.7)272 ax.set_xlim(10, 52); ax.set_ylim(0, 1.32)273 ax.set_ylabel("modulus (normalised)")274 ax.legend(loc="upper left", ncol=3, columnspacing=1.0, handlelength=1.6)275 panel_letter(ax, "(a)")276 ax = axes[1]277 e = energy(10 ** 6, gam)278 ax.plot(gam, e / e.max(), color=PURPLE, lw=0.9)279 for i, z in enumerate(HEIGHTS):280 ax.axvline(z, color=GREY, lw=0.6, ls="--", alpha=0.7)281 ax.annotate(f"{z:.2f}", (z, 1.0), xytext=(0, 3 + 7 * (i % 2)), textcoords="offset points", ha="center", fontsize=6, color=GREY)282 ax.set_xlim(10, 52); ax.set_ylim(0, 1.3)283 ax.set_xlabel(r"$\gamma$ (the chart's height)"); ax.set_ylabel("modulus (normalised)")284 panel_letter(ax, "(b)")285 fig.tight_layout(h_pad=1.0)286 _save(fig, "fig_primespec")287288def figure_plane():289 """fig_plane: the critical line is the energy domain, on F_13 (κ = 3, g = 2, η² = 2; Prop. line, Thm. drive). (a) The framed290 plane K as the 13×13 lattice a + bη with the real line and the critical line, the modes at their labels θ_k = −2^k, one291 conjugation pair, the first steps of the drive about the centre, a point off both lines with its two images; (b) the time292 domain as a cycle, the residues by scale, coloured by phase; (c) the critical line in the drive's order with the same293 residues in the same colours, θ_k = L_1(k + π)."""294 p, kap, g, nu = 13, 3, 2, 2295 n, pi_, half = p - 1, 6, 7296 theta = [(-pow(g, k, p)) % p for k in range(n)] # the readout of the mode k: minus its eigenvalue297 scales = [pow(g, m, p) for m in range(n)] # the time domain in the drive's order: 1, 2, 4, 8, 3, 6, 12, ...298 assert all(theta[k] == scales[(k + pi_) % n] for k in range(n))299 with plt.rc_context(PAPER_RC):300 _draw_plane(p, g, nu, n, pi_, half, theta, scales)301302def _draw_plane(p, g, nu, n, pi_, half, theta, scales):303 from matplotlib import cm304 col = lambda m: cm.twilight(((m % n) + 0.5) / n) # one colour per phase m on the time domain305 dark = lambda m: 3 <= (m % n) <= 8306 fig = plt.figure(figsize=(TEXTWIDTH_IN, 4.0)) # (a) square at 0.6 text width, (b) and (c) stacked at its right307 gs = fig.add_gridspec(2, 2, width_ratios=[1.55, 1], wspace=0.02, hspace=0.04, left=0.005, right=0.995, top=0.985, bottom=0.015)308 axa, axb, axc = fig.add_subplot(gs[:, 0]), fig.add_subplot(gs[0, 1]), fig.add_subplot(gs[1, 1])309 F = {"big": 8.5, "mid": 7.5, "small": 7, "tiny": 6.5}310 box = dict(boxstyle="round,pad=0.15", fc="white", ec="none", alpha=0.88) # the annotations of (a) sit on the lattice311 # (a) the framed plane K = F_13(η): the lattice, the real line with the window, the critical line with the modes312 for a in range(p):313 for b in range(p): axa.plot(a, b, "o", ms=2.0, color="#cfd4dc", zorder=1)314 axa.plot([0, 0], [-0.3, p - 0.7], ls=(0, (2, 2)), color=GREY, lw=0.7, zorder=2)315 axa.plot([-0.3, p - 0.7], [0, 0], color=BLUE, lw=1.6, zorder=3)316 axa.plot([half, half], [-0.3, p - 0.7], color=PURPLE, lw=1.6, zorder=3)317 for a in range(p): axa.plot(a, 0, "o", ms=3.6, color=BLUE, zorder=4)318 axa.add_patch(plt.Rectangle((0.6, -0.42), 2.8, 0.84, color="#dbe7fb", zorder=0))319 for q in (2, 3): axa.plot(q, 0, "o", ms=6, mfc="none", mec=BLUE, mew=1.1, zorder=5)320 axa.text(2.0, -0.95, r"window $n\leq\sqrt{13}$: the primes 2, 3", color=BLUE, ha="center", fontsize=F["small"])321 for k in range(n):322 axa.plot(half, theta[k], "o", ms=4.8, color=PURPLE, zorder=5)323 axa.text(half + 0.3, theta[k] - 0.1, f"$k={k}$", color=PURPLE, fontsize=F["small"], va="center")324 axa.plot(half, 0, "o", ms=5.2, color=INK, zorder=6)325 axa.text(half + 0.3, -0.85, r"$2^{-1}=7$, the centre", color=INK, fontsize=F["small"])326 axa.text(half - 0.35, p - 0.45, r"$L_{1/2}=\{z: z+z^{13}=1\}$", color=PURPLE, ha="right", va="top", fontsize=F["small"], bbox=box, zorder=7)327 axa.text(p - 0.6, 0.45, r"$\mathbb{F}_{13}$, the real line", color=BLUE, ha="right", fontsize=F["small"])328 axa.text(-0.75, p - 0.6, r"$\eta\,\mathbb{F}_{13}$", color=GREY, fontsize=F["tiny"])329 axa.add_patch(FancyArrowPatch((half - 0.2, theta[0]), (half - 0.2, theta[pi_]), connectionstyle="arc3,rad=0.14", arrowstyle="<->", mutation_scale=7, color=PURPLE, lw=0.8, zorder=6))330 axa.text(3.0, 3.6, "the conjugation $z\\mapsto z^{13}$\nand the half-turn $z\\mapsto 1-z$:\n$k\\mapsto k+6$ on the line", color=PURPLE, fontsize=F["tiny"], ha="center", va="top", bbox=box, zorder=7)331 for k in range(3):332 axa.add_patch(FancyArrowPatch((half - 0.1, theta[k]), (half - 0.1, theta[k + 1]), connectionstyle="arc3,rad=0.22", arrowstyle="->", mutation_scale=6, color=PURPLE, lw=0.7, zorder=4))333 axa.text(half + 2.1, 12.3, "the drive about the centre,\n$\\theta\\mapsto 2\\theta$: $k\\mapsto k+1$", color=PURPLE, fontsize=F["tiny"], va="top", bbox=box, zorder=7)334 za = (1, 4); zc = (za[0], (-za[1]) % p); zh = ((1 - za[0]) % p, (-za[1]) % p) # a point off both lines, its conjugate and its half-turn image335 assert zc == (1, 9) and zh == (0, 9)336 axa.plot(*za, "s", ms=4, color=GREY, zorder=5); axa.plot(*zc, "s", ms=4, mfc="none", mec=GREY, zorder=5); axa.plot(*zh, "s", ms=4, mfc="none", mec=GREY, zorder=5)337 axa.add_patch(FancyArrowPatch((za[0], za[1] + 0.3), (zc[0], zc[1] - 0.3), arrowstyle="->", mutation_scale=6, color=GREY, lw=0.7, zorder=4))338 axa.add_patch(FancyArrowPatch((za[0] - 0.15, za[1] + 0.25), (zh[0] + 0.1, zh[1] - 0.3), connectionstyle="arc3,rad=0.25", arrowstyle="->", mutation_scale=6, color=GREY, lw=0.7, zorder=4))339 axa.text(0.3, 11.6, "a point off both lines,\nwith its conjugate and its\nhalf-turn image: on no\nline kept by both", color=GREY, fontsize=F["tiny"], va="top", bbox=box, zorder=7)340 axa.set_xlim(-1.2, p + 0.2); axa.set_ylim(-1.4, p - 0.2); axa.set_aspect("equal"); axa.axis("off")341 panel_letter(axa, "(a)", x=0.01, y=0.99)342 # (b) the time domain as a cycle: the residues by scale, each with the colour of its phase m343 ang = lambda m: np.pi / 2 - 2 * np.pi * m / n344 axb.add_patch(plt.Circle((0, 0), 1, fill=False, color=GREEN, lw=1.3, zorder=2))345 for m, x in enumerate(scales):346 axb.plot(np.cos(ang(m)), np.sin(ang(m)), "o", ms=11, color=col(m), mec=INK, mew=0.5, zorder=5)347 axb.text(np.cos(ang(m)), np.sin(ang(m)), str(x), ha="center", va="center", fontsize=F["small"], color="white" if dark(m) else INK, zorder=6)348 axb.text(1.4 * np.cos(ang(m)), 1.4 * np.sin(ang(m)), f"$m={m}$", ha="center", va="center", fontsize=F["tiny"], color=GREY)349 axb.plot(0, 0, "o", ms=3.5, color=INK, zorder=5); axb.text(0.1, 0.04, "0", fontsize=F["small"])350 axb.annotate("", xy=(np.cos(ang(1)), np.sin(ang(1))), xytext=(np.cos(ang(0.4)), np.sin(ang(0.4))), arrowprops=dict(arrowstyle="->", color=GREEN, lw=1.2))351 axb.text(0, 1.62, "the time domain $L_1=\\{2^m\\}$", color=GREEN, fontsize=F["tiny"], ha="center")352 axb.set_xlim(-1.85, 1.85); axb.set_ylim(-1.7, 1.85); axb.set_aspect("equal"); axb.axis("off")353 panel_letter(axb, "(b)", x=0.02, y=1.0)354 # (c) the critical line in the drive's order: the same residues as labels, in the same colours, θ_k = L_1(k + π)355 axc.add_patch(plt.Circle((0, 0), 1, fill=False, color=PURPLE, lw=1.3, zorder=2))356 for k in range(n):357 m = (k + pi_) % n358 axc.plot(np.cos(ang(k)), np.sin(ang(k)), "o", ms=11, color=col(m), mec=INK, mew=0.5, zorder=5)359 axc.text(np.cos(ang(k)), np.sin(ang(k)), str(theta[k]), ha="center", va="center", fontsize=F["small"], color="white" if dark(m) else INK, zorder=6)360 axc.text(1.4 * np.cos(ang(k)), 1.4 * np.sin(ang(k)), f"$k={k}$", ha="center", va="center", fontsize=F["tiny"], color=PURPLE)361 axc.plot(0, 0, "o", ms=3.5, color=INK, zorder=5); axc.text(0.1, 0.04, "$2^{-1}$", fontsize=F["small"])362 axc.annotate("", xy=(np.cos(ang(1)), np.sin(ang(1))), xytext=(np.cos(ang(0.4)), np.sin(ang(0.4))), arrowprops=dict(arrowstyle="->", color=PURPLE, lw=1.2))363 axc.text(0, 1.62, "the labels $\\theta_k=-2^k=L_1(k+6)$", color=PURPLE, fontsize=F["tiny"], ha="center")364 axc.set_xlim(-1.85, 1.85); axc.set_ylim(-1.7, 1.85); axc.set_aspect("equal"); axc.axis("off")365 panel_letter(axc, "(c)", x=0.02, y=1.0)366 _save(fig, "fig_plane")367368# ======================================================================================================================369# block A — the shell, in exact arithmetic370# The shells p = 13, 17, 29, 37, 41 in full; 173 for the checks that do not enumerate the plane; the laboratory pairs371# (13, 233), (173, 30089), (1549, 2408561) for frame coincidence, the closure and completeness. The generator g is the least372# primitive root, η² = ν the least nonresidue, as in the paper.373def block_A():374 """Block A — the shell, in exact arithmetic: 96 checks, 91 EXACT and 5 [approx] readings of the chart's characters (A7b, one per shell)."""375 print("\n== block A: the shell ==")376 for p in SHELLS + [BIG]:377 g, nu = generator(p), nonresidue(p)378 kappa = (p - 1) // 4; assert 4 * kappa + 1 == p379 # A1 zero-slot380 ok = all(sum(pow(x, k, p) for x in range(1, p)) % p == 0 for k in range(1, p - 1)) \381 and sum(pow(x, p - 1, p) for x in range(1, p)) % p == p - 1382 # 20:B4 (p20011)383 check("A1", f"zero-slot on F_{p}", ok, f"Σx^k=0 for k=1..{p-2}; = -1 at k={p-1}")384 # A6 the Subject constants, capacity-first385 pi_ = 2 * kappa386 i_ = pow(g, p - 1 - kappa, p) # g^{-κ}387 assert i_ == (-pow(g, kappa, p)) % p388 i_odd = i_ if i_ % 2 == 1 else i_ + p # the odd integer lift of i (Remark frame)389 e_ = pow(g, i_odd, p)390 ok = ((2 * pi_) % p == p - 1 and (i_ * i_) % p == p - 1 and pow(g, pi_, p) == p - 1391 and pow(e_, i_odd * pi_, p) == p - 1 and (2 * (2 * kappa + 1)) % p == 1392 and (2 * kappa + 1) % p == (-pi_) % p)393 # 20:B10 (p20017)394 check("A6", f"Subject constants on F_{p}: π=2κ, i=g^-κ, e=g^i (odd lift)", ok,395 f"g={g} κ={kappa} π={pi_} i={i_} e={e_}: 2π≡-1, i²≡-1, g^π≡-1, e^(iπ)≡-1, 2⁻¹=2κ+1=-π")396 # A4 the finite critical line397 inv2 = (2 * kappa + 1) % p398 line = [(inv2, b) for b in range(p)]399 quarter = pow(4, p - 2, p)400 ok = all(trace(z, p) == 1 for z in line) and len(set(line)) == p \401 and all(norm(z, nu, p) == (quarter - nu * z[1] * z[1]) % p for z in line)402 if p != BIG: # the converse on the full plane: Tr z = 1 only on the line403 ok = ok and all(((2 * a) % p == 1) == (a == inv2) for a in range(p))404 # 20:B8 (p20015)405 check("A4", f"finite critical line on F_{p}: Tr z = 1 ⟺ z = 2⁻¹ + bη, |L| = p, N = ¼ − νb²", ok,406 f"ν={nu}, 2⁻¹={inv2}")407 # A7 the shell theorem (Thm. hp) on F_p, every clause in F_p: (i) the dual inverts, the constant mode the mean term;408 # (iii) D x^k = g^k x^k on the power characters (the drive D : x ↦ g x), Tr D^r = (p−1)[(p−1)|r]; (iv) W² = −J, F² = J, F⁴ = 1 for W_mk = g^mk,409 # F = iW; (v) the explicit formula along the meridian, Σ_{y≤x} v(y) = −Σ_k v̂(k) S_k(x), S_0(x) = x; three random vectors410 vecs = random_vectors(p, 3, seed=20 * p)411 ok_i = ok_v = True412 for v in vecs:413 vh = dual(v, p)414 ok_i &= all((-sum(vh[k] * pow(y, (p - 1 - k) % (p - 1), p) for k in range(p - 1))) % p == v[y] for y in range(1, p)) \415 and vh[0] == sum(v) % p416 S = lambda k, x: sum(pow(y, (p - 1 - k) % (p - 1), p) for y in range(1, x + 1)) % p417 ok_v &= all((-sum(vh[k] * S(k, x) for k in range(p - 1))) % p == sum(v[1:x + 1]) % p for x in range(1, p)) \418 and all(S(0, x) == x % p for x in range(1, p))419 ok_fp = all(pow((g * x) % p, k, p) == (pow(g, k, p) * pow(x, k, p)) % p for k in range(p - 1) for x in range(1, p))420 tr = [sum(1 for x in range(1, p) if (pow(g, r, p) * x) % p == x) for r in range(1, p)]421 ok_tr = all(tr[r - 1] == ((p - 1) if r % (p - 1) == 0 else 0) for r in range(1, p))422 n_ = p - 1423 W = np.array([[pow(g, (m * k) % n_, p) for k in range(n_)] for m in range(n_)], dtype=np.int64)424 J = np.array([[1 if (m + l) % n_ == 0 else 0 for l in range(n_)] for m in range(n_)], dtype=np.int64)425 W2 = (W @ W) % p426 F2 = (i_ * i_ * W2) % p # F = iW: F² = i² W²427 ok_iv = np.array_equal(W2, (-J) % p) and np.array_equal(F2, J) and np.array_equal((F2 @ F2) % p, np.eye(n_, dtype=np.int64))428 # 20:E12 (p20043), 20:E14 (p20092)429 check("A7", f"the shell theorem on F_{p}: (i) the dual inverts, v(y) = −Σ v̂(k) y^−k, v̂(0) the mean term; (iii) D x^k = g^k x^k, Tr D^r = (p−1)[(p−1)|r]; (iv) W² = −J, F² = J, F⁴ = 1; (v) the explicit formula along the meridian, S_0(x) = x",430 ok_i and ok_fp and ok_tr and ok_iv and ok_v, f"three random vectors; W of order {n_}")431 # A14 the Parseval identity (Thm. hp (ii)): Σ_k v̂(k) v̂(−k) = −Σ_x v(x)² in F_p, on random vectors and on the prime-power432 # indicator of the whole shell (the window's prime vector of Def. vector is its restriction below √p; the identity holds for every vector)433 prime_vec = [0] + [1 if is_prime(x) or (len(prime_factors(x)) == 1 and x > 1) else 0 for x in range(1, p)]434 ok = True435 for v in vecs + [prime_vec]:436 vh = dual(v, p)437 ok &= sum(vh[k] * vh[(-k) % (p - 1)] for k in range(p - 1)) % p == (-sum(x * x for x in v)) % p438 # 20:E13 (p20044)439 check("A14", f"the Parseval identity on F_{p}: Σ_k v̂(k) v̂(−k) = −Σ_x v(x)² for three random vectors and the prime-power indicator of the shell", ok,440 f"prime-power indicator: {sum(prime_vec)} labels")441 if p == BIG:442 continue443 # A2 slot complementarity444 image = {(-pow(g, k, p)) % p for k in range(1, p - 1)}445 # 20:B5 (p20012)446 check("A2", f"Φ(k) = −g^k bijects the nonterminal slots onto F_{p}^× \\ {{−1}}", image == set(range(1, p - 1)),447 f"|image| = {len(image)} = p−2")448 # A3 Hermitian phase calculus449 K = [(a, b) for a in range(p) for b in range(p)]450 U = [z for z in K if norm(z, nu, p) == 1]451 inv_ok = all(frob(z, p) == zpow(z, p, nu, p) and mul(z, frob(z, p), nu, p) == (1, 0) for z in U)452 i2 = [(a, 0) for a in range(p) if (a * a) % p == p - 1]453 ok = len(U) == p + 1 and inv_ok and len(i2) == 2 and all(frob(z, p) == z and norm(z, nu, p) == p - 1 for z in i2)454 # 20:B6 (p20013)455 check("A3", f"F_{p}²: |U_(p+1)| = p+1, Frobenius = inversion on it, i Frobenius-fixed with N(i) = −1", ok)456 # A5 the two agreement loci (Thm. agree): among the p(p+1) affine lines of K exactly two are invariant as sets under both457 # the conjugation φ and the half-turn ρ — the prime meridian F_p and the critical line; φ keeps p+1 lines, ρ keeps the458 # p+1 lines through 2⁻¹; and the corollary, the Klein four-group with its fixed loci459 phi = lambda z: frob(z, p)460 rho = lambda z: half_turn(z, p)461 sig = lambda z: rho(phi(z))462 lines = affine_lines(p)463 kept_phi = [name for name, L in lines if all(phi(z) in L for z in L)]464 kept_rho = [name for name, L in lines if all(rho(z) in L for z in L)]465 both = [name for name, L in lines if all(phi(z) in L and rho(z) in L for z in L)]466 ok_lines = (len(lines) == p * (p + 1) and len(kept_phi) == p + 1 and len(kept_rho) == p + 1467 and sorted(both) == sorted([("H", 0), ("S", 0, inv2)])468 and all(("S", c, inv2) in kept_rho for c in range(p)) and ("H", 0) in kept_rho469 and all(("H", b) not in kept_rho for b in range(1, p)))470 fix_phi = {z for z in K if phi(z) == z}; fix_rho = {z for z in K if rho(z) == z}; fix_sig = {z for z in K if sig(z) == z}471 ok_klein = (all(phi(phi(z)) == z and rho(rho(z)) == z and phi(rho(z)) == rho(phi(z)) for z in K)472 and fix_phi == {(a, 0) for a in range(p)} and fix_sig == set(line) and fix_rho == {(inv2, 0)}473 and fix_phi & fix_sig == {(inv2, 0)})474 # 20:B9 (p20016)475 check("A5", f"the two agreement loci on F_{p}²: of the {p * (p + 1)} affine lines, φ keeps {p + 1}, ρ keeps {p + 1}, both keep exactly F_p and L_1/2; Klein four-group: Fix φ = F_p, Fix σ = L_1/2, Fix ρ = {{2⁻¹}}",476 ok_lines and ok_klein, f"both: {both}")477 # A7b the chart's reading of the Parseval identity (Rem. parseval) [approx]: the complex characters χ_j(n) = ω^{jλ(n)} on478 # ℓ²(F_p^×) are orthogonal with ‖χ_j‖² = p−1, the dual inverts, and Σ_j |v̂_C(j)|² = (p−1) Σ |v|²; D χ_j = ω^j χ_j, the479 # drive's chart a unitary permutation matrix whose eigenvalues are the (p−1)-th roots of unity (Rem. chart-operator)480 lam = {}481 for n in range(1, p):482 base = prime_factors(n)483 lam[n] = math.log(min(base)) if len(base) == 1 else 0.0484 v = np.array([lam[n] for n in range(1, p)])485 dlog = dlog_table(p, g)486 w = cmath.exp(2j * math.pi / (p - 1))487 chi = np.array([[w ** (j * dlog[n]) for n in range(1, p)] for j in range(p - 1)])488 gram = chi.conj() @ chi.T489 vc = chi @ v490 ok_orth = np.allclose(gram, (p - 1) * np.eye(p - 1), atol=1e-9)491 ok_par = abs(np.sum(np.abs(vc) ** 2) - (p - 1) * np.sum(v ** 2)) < 1e-9492 ok_inv = np.allclose((chi.conj().T @ vc).real / (p - 1), v, atol=1e-10)493 shifted = lambda j: np.array([w ** (j * dlog[(g * n) % p]) for n in range(1, p)]) # (S χ_j)(n) = χ_j(g n)494 ok_c = all(np.allclose(shifted(j), w ** j * chi[j]) for j in range(p - 1))495 Dm = np.zeros((p - 1, p - 1)); dl = dlog_table(p, g)496 for n in range(1, p): Dm[n - 1, (g * n) % p - 1] = 1.0 # (Dv)(n) = v(gn): a permutation matrix497 ok_u = np.allclose(Dm @ Dm.T, np.eye(p - 1)) and np.allclose(sorted(np.angle(np.linalg.eigvals(Dm)) % (2 * np.pi)), sorted(2 * np.pi * np.arange(p - 1) / (p - 1)), atol=1e-9)498 check("A7b", f"the chart's characters on ℓ²(F_{p}^×): χ_j orthogonal with ‖χ_j‖² = p−1, Σ_j|v̂(j)|² = (p−1)Σ|v|² for v = Λ, the dual inverts; Dχ_j = ω^j χ_j, the drive a unitary permutation with the (p−1)-th roots of unity as its eigenvalues",499 ok_orth and ok_par and ok_inv and ok_c and ok_u, f"Σ|v̂|²/(p−1) = {np.sum(np.abs(vc) ** 2) / (p - 1):.6f}", kind="[approx]")500 # A10 the shared quarter-turn core; no cycle projection onto (13, 233)501 Om = 233502 q4 = {pow(i_, a, p) for a in range(4)}503 ok = q4 == {1, i_, p - 1, (-i_) % p} and (p - 1) % 4 == 0 and (Om - 1) % 4 == 0504 if p == 13:505 ok = ok and (Om - 1) % (p - 1) != 0506 # 20:B1 (p20008)507 check("A10", "Q₄ ⊂ both cycles; C_232 ↠ C_12 does not exist (12 ∤ 232) on the pair (13, 233)", ok, "the shells share the core, not a clock")508 else:509 check("A10", f"Q₄ = {{1, i, −1, −i}} ⊂ F_{p}^×, 4 | p−1", ok)510 # A11 frame coincidence below the horizon (Prop. coincide): the Carrier chart Ω is the least prime ≡ 1 (mod 4) above p²511 for p in SHELLS + [1009, 10009]:512 Om = next_prime(p * p)513 while Om % 4 != 1:514 Om = next_prime(Om)515 H = math.isqrt(p)516 same = all(n % p == n % Om == n for n in range(1, H + 1))517 prods = all((a * b) % p == (a * b) % Om == a * b for a in range(1, H + 1) for b in range(1, H + 1))518 irreducible = {n for n in range(2, H + 1) if all(n % d for d in range(2, math.isqrt(n) + 1))} # trial division inside the window519 primes = {n for n in range(2, H + 1) if is_prime(n)}520 # 20:B2 (p20009)521 check("A11", f"frame coincidence below √{p} = {H} on the pair ({p}, {Om}): residues, window products and primality agree", same and prods and irreducible == primes,522 f"Π_p = {sorted(primes)}")523 # A6b the odd-lift rule (Remark frame) on every admissible frame below 3000, least primitive root524 frames = [q for q in range(5, 3000) if q % 4 == 1 and is_prime(q)]525 bad = []526 for q in frames:527 gq = generator(q); kq = (q - 1) // 4; piq = 2 * kq528 r = pow(gq, q - 1 - kq, q) # the least residue of i = g^{-κ}529 odd, even = (r, r + q) if r % 2 == 1 else (r + q, r)530 e_odd = pow(gq, odd, q)531 if not (pow(e_odd, odd * piq, q) == q - 1 and pow(e_odd, even * piq, q) == 1 and (r * r) % q == q - 1):532 bad.append(q)533 f17 = (pow(3, 16 - 4, 17), pow(3, 21, 17)) # F_17 with g = 3: i = 3^{-4} = 4 (even), lift 21, e = 3^21 = 5534 ok = not bad and f17 == (4, 5)535 check("A6b", f"the odd-lift rule on all {len(frames)} frames p ≡ 1 (mod 4) below 3000: e^{{iπ}} ≡ −1 on the odd lift, ≡ +1 on the even member; F_17: g=3, i=4, lift 21, e=5", ok,536 f"frames {len(frames)}, failures {bad}; F_17 (i, e) = {f17}")537538 # A15 the critical line is the energy domain (Prop. line; row B12): z_k = 2⁻¹ − ηg^k. (i) k ↦ z_k bijects Z_{p−1} onto the539 # line without its centre, z_k the readout of the mode k at θ = −g^k, k = 0 at θ = −1 and k = π at θ = 1; (ii) the dilation540 # about the centre, z ↦ 2⁻¹ + g(z − 2⁻¹), carries z_k to z_{k+1}; (iii) the half-turn and the conjugation both carry z_k to541 # z_{k+π} and fix the centre alone; (iv) N(z_k) = ¼ − νg^{2k}, even under k ↦ k + π; (v) the labels along the drive are the542 # latitude L_a = {a g^m} shifted by π − log_g a for every base point a, by 0 for a = −1: θ_k = −g^k = L_{−1}(k)543 for p in SHELLS + [53, BIG]:544 g, nu = generator(p), nonresidue(p)545 kappa = (p - 1) // 4; pi_ = 2 * kappa; inv2 = (2 * kappa + 1) % p; n_ = p - 1546 quarter = pow(4, p - 2, p)547 zk = [(inv2, (-pow(g, k, p)) % p) for k in range(n_)]548 centre = (inv2, 0)549 ok_i = len(set(zk)) == n_ and set(zk) == {(inv2, b) for b in range(1, p)} and all(trace(z, p) == 1 for z in zk) \550 and zk[0] == (inv2, p - 1) and zk[pi_] == (inv2, 1)551 dil = lambda z: (inv2, (g * z[1]) % p) # 2⁻¹ + g(z − 2⁻¹) on the line552 ok_ii = all(dil(zk[k]) == zk[(k + 1) % n_] for k in range(n_)) and dil(centre) == centre553 ok_iii = all(half_turn(zk[k], p) == zk[(k + pi_) % n_] == frob(zk[k], p) for k in range(n_)) \554 and all(zk[(k + pi_) % n_] != zk[k] for k in range(n_)) and half_turn(centre, p) == centre == frob(centre, p)555 ok_iv = all(norm(zk[k], nu, p) == (quarter - nu * pow(g, 2 * k, p)) % p == norm(zk[(k + pi_) % n_], nu, p) for k in range(n_))556 # 20:B12 (p20085)557 lam = dlog_table(p, g)558 ok_v = all(zk[k][1] == (a * pow(g, (k + pi_ - lam[a]) % n_, p)) % p for a in range(1, p) for k in range(n_)) \559 and all(zk[k][1] == ((p - 1) * pow(g, k, p)) % p for k in range(n_)) # (v): θ_k = L_a(k + π − log_g a); the shift 0 at a = −1560 check("A15", f"the critical line is the energy domain on F_{p}: k ↦ z_k = 2⁻¹ − ηg^k bijects Z_{n_} onto L_1/2 \\ {{2⁻¹}}; the drive z_k ↦ z_{{k+1}}; half-turn and conjugation z_k ↦ z_{{k+π}}, the centre their only fixed point; N(z_k) even under k ↦ k+π; the labels along the drive are the latitude L_a shifted by π − log_g a, for every base point a, by 0 for a = −1",561 ok_i and ok_ii and ok_iii and ok_iv and ok_v, f"g={g}, ν={nu}, π={pi_}: z_0 = 2⁻¹+η, z_π = 2⁻¹−η")562563 # A16 frame coincidence on the critical line (Prop. coincideline; row B13), on the laboratory pairs: for every nonzero label564 # θ < p of the Subject, θ is the same integer in F_p and F_Ω (the Subject's residues are the Carrier's below p; B1); 2⁻¹ + ηθ565 # has trace 1 in both frames with real part 2κ+1 and 2κ'+1 (the line's centre is the half-turn of each frame); the line566 # {Tr = 1} is carried to itself by the half-turn and by the conjugation in both frames (B9, D11); the point is a mode in567 # both — θ = −g^k in F_p and θ = −g'^{k'} in F_Ω — nontrivial in both for 1 ≤ θ ≤ p−2 (B12; the Subject's constant mode568 # sits at θ = p−1 ≡ −1, where the Carrier has a zero), and the mode's slot is a zero-slot (B4), checked at the first prime569 # labels; the Carrier's labels from p on are no residue of the Subject; the primes need the horizon and the zeros do not:570 # at the first label above the horizon the products of the two frames disagree571 for p, Om in PAIRS:572 gp, gO = generator(p), generator(Om)573 kp, kO = (p - 1) // 4, (Om - 1) // 4574 H = math.isqrt(p)575 same = all(t % p == t % Om == t for t in range(p))576 tr = all(trace((2 * kp + 1, t), p) == 1 and trace((2 * kO + 1, t), Om) == 1 for t in range(p))577 line_p = [((2 * kp + 1) % p, b) for b in range(p)]578 inv_p = all(half_turn(z, p) in set(line_p) and frob(z, p) in set(line_p) for z in line_p)579 line_O = set(((2 * kO + 1) % Om, b) for b in range(Om))580 inv_O = all(half_turn(z, Om) in line_O and frob(z, Om) in line_O for z in line_O)581 lam_p, lam_O = dlog_table(p, gp), dlog_table(Om, gO)582 modes = {t: (lam_p[(-t) % p], lam_O[(-t) % Om]) for t in range(1, p)}583 mode_ok = all(pow(gp, modes[t][0], p) == (-t) % p and pow(gO, modes[t][1], Om) == (-t) % Om for t in modes)584 mode_ok &= all(1 <= modes[t][0] <= p - 2 and 1 <= modes[t][1] <= Om - 2 for t in range(1, p - 1))585 mode_ok &= modes[p - 1][0] == 0 and 1 <= modes[p - 1][1] <= Om - 2 # the constant mode's point: a Carrier zero586 mode_ok &= len({modes[t][0] for t in modes}) == p - 1 and len({modes[t][1] for t in modes}) == p - 1587 firsts = [t for t in range(2, H + 1) if is_prime(t)][:2]588 slot_ok = all(sum(pow(x, modes[t][0], p) for x in range(1, p)) % p == 0 for t in firsts)589 slot_ok &= sum(pow(x, modes[firsts[0]][1], Om) for x in range(1, Om)) % Om == 0590 beyond = all(t % p != t for t in range(p, min(Om, p + 50))) and Om - 1 >= p591 above = ((H + 1) * (H + 1)) % p != (H + 1) * (H + 1) and ((H + 1) * (H + 1)) % Om == (H + 1) * (H + 1)592 eig = all(pow(gp, modes[t][0], p) == (-t) % p and pow(gO, modes[t][1], Om) == (-t) % Om for t in range(1, p - 1)) # the eigenvalue −θ in both frames (Thm. drive (vi))593 N_ = Om - 1; (k1, kp1), (k2, kp2) = modes[1], modes[2]594 affine = [(a, (kp1 - a * k1) % N_) for a in range(N_) if (a * k2 + kp1 - a * k1) % N_ == kp2] # the maps fitting the labels 1 and 2595 affine = [(a, b) for a, b in affine if all((a * modes[t][0] + b) % N_ == modes[t][1] for t in range(1, p - 1))] # no affine k ↦ k' fits every label596 # 20:B13 (p20086)597 check("A16", f"frame coincidence on the line, pair ({p}, {Om}): every label θ < {p} the same integer in both; Tr(2⁻¹+ηθ) = 1 in both, centres {2 * kp + 1} and {2 * kO + 1}; the line kept by half-turn and conjugation in both; every 1 ≤ θ ≤ {p - 2} a nontrivial mode in both, the slot a zero-slot, θ = {p - 1} the Subject's constant mode and a Carrier zero; the labels from {p} on no Subject residue; at {H + 1} the products disagree; at every label the eigenvalue −θ under each frame's own drive, the indices k, k' each frame's own",598 same and tr and inv_p and inv_O and mode_ok and slot_ok and beyond and above and eig and affine == [],599 "modes (k, k'): " + ", ".join(f"θ={t}: {modes[t]}" for t in firsts) + f"; θ={p - 1}: {modes[p - 1]}; affine maps k ↦ k' fitting the labels: {len(affine)}")600601 # A12 the closure of the zeros (Thm. closure; rows A2, A4, F7), on the four laboratory Carriers Ω = 13, 233, 30089,602 # 2408561: the largest embedded Subject p* with p*² < Ω < p'² (p' the next prime); the residues of a cycle are its labels603 # 0..q−1 and a Subject of cardinality p reads the residues y < p, its own residues, so an embedded Subject's cycle is shorter604 # than the Carrier's and the Carrier's top residue is read from labels up to √Ω, beyond every embedded window √p*; the605 # wrap of the height reading, (T + Ω) ≡ T; the pigeonhole of 00:A2/00:A4 on the residues — a reading of the Ω residues into606 # o < Ω records identifies two residues (found by search for o = p* and o = Ω − 1), and an injective reading needs o ≥ Ω607 def largest_subject(Om):608 """The largest admissible Subject of Ω: the largest prime p = 4κ+1 with κ > 1 and p² < Ω (Remark holographic), or None."""609 q = math.isqrt(Om - 1)610 while q >= 13 and not (is_prime(q) and q % 4 == 1): q -= 1611 return q if q >= 13 else None612 assert largest_subject(13) is None and largest_subject(401) == 17 and is_prime(19) and 19 * 19 < 401 # the empty case; the control613 for Om in (233, 30089, 2408561):614 ps = largest_subject(Om)615 ok = is_prime(Om) and Om % 4 == 1 and is_prime(ps) and ps % 4 == 1 and ps > 5 and ps * ps < Om616 ok &= all(not (is_prime(q) and q % 4 == 1) for q in range(ps + 1, math.isqrt(Om - 1) + 1)) # no admissible Subject between p* and √Ω617 ok &= ps < Om and math.isqrt(ps) < math.isqrt(Om) # the embedded cycle shorter; the top window's labels beyond √p*618 ok &= all((T + Om) % Om == T % Om for T in (0, 1, ps, Om - 1, Om, 7 * Om + 3)) # the wrap of the height reading619 collisions = {}620 for o in (ps, Om - 1):621 seen = {}622 for y in range(Om): # the residues of the Carrier's cycle, read into o records623 r = y % o624 if r in seen:625 collisions[o] = (seen[r], y); break626 seen[r] = y627 ok &= o in collisions and collisions[o][0] != collisions[o][1] and collisions[o][0] % o == collisions[o][1] % o628 ok &= len({y for y in range(Om)}) == Om # the identity reading into Ω records is injective: Ω ≤ Ω629 # 20:A2 (p00004), 20:A4 (p00197), 20:F7 (p20079)630 check("A12", f"closure of the zeros on Ω = {Om}: the largest admissible Subject p* = {ps} ({ps}² < Ω, none between p* and √Ω = {math.isqrt(Om)}), the cycle's {Om} residues, an embedded Subject reads {ps} of them; readings into {ps} and {Om - 1} records collide", ok,631 f"collisions {collisions}; √Ω = {math.isqrt(Om)}, √p* = {math.isqrt(ps)}")632633 # A13 Completeness (row A3; 00:A3), on the laboratory pairs (p, Ω): the registration of a totality is onto its registered634 # Universe — the registered Universe is the set of residues at which some member registers, read back as a member for every635 # residue of it (the Carrier's residues registered whole, ρ(y) = y, and the Subject's reading of them, ρ_p(y) = y mod p: Ω and p636 # residues, each with a member); and two totalities each registered whole within the other have one count — the identity637 # registers the Subject's cycle within the Carrier's, every reading of the Carrier's Ω residues into the Subject's p records638 # identifies two residues (y mod p, an affine reading, the square; the pigeonhole of 00:A2 both ways is639 # FRC.Foundation.mutual_registration_count), and only cycles of one count embed both ways640 for p, Om in PAIRS:641 members = {}642 for y in range(Om): # the Carrier's cycle registered whole643 members.setdefault(y % Om, y)644 ok = len(members) == Om and all(members[r] % Om == r for r in members) # onto: every residue has a member645 membersp = {}646 for y in range(Om): # the Subject's reading of the Carrier's residues647 membersp.setdefault(y % p, y)648 ok &= len(membersp) == p and all(membersp[r] % p == r for r in membersp)649 ok &= len({x % Om for x in range(p)}) == p # the identity registers Shell p within Shell Ω650 readings = {"y mod p": lambda y: y % p, "3y+5 mod p": lambda y: (3 * y + 5) % p, "y² mod p": lambda y: (y * y) % p}651 collisions = {}652 for name, f in readings.items(): # no reading of Shell Ω within Shell p is injective653 seen = {}654 for y in range(Om):655 r = f(y)656 if r in seen:657 collisions[name] = (seen[r], y); break658 seen[r] = y659 ok &= name in collisions and collisions[name][0] != collisions[name][1] and f(collisions[name][0]) == f(collisions[name][1])660 ok &= p < Om and len({x % p for x in range(p)}) == p # one count: the identity both ways on Shell p661 # 20:A3 (p00003)662 check("A13", f"completeness on the pair ({p}, {Om}): the registration of the cycle is onto its registered Universe ({Om} residues; {p} under the Subject's reading); F_{p} registers within F_{Om}, every reading of the {Om} residues into {p} records collides, one count only both ways", ok,663 "collisions " + ", ".join(f"{k}: {v}" for k, v in collisions.items()))664665 # A17 the open target's data (row O9; Section order): the cycle's scale coordinate is the discrete logarithm up to the choice666 # of generator, and no generator of F_173, F_1549 or F_30089 orders the primes of the window (λ(2) < λ(3) < λ(5) < …); the667 # longest ordered run of the window's primes is 5 of 6, 6 of 12 and 7 of 40. F_13, whose window holds the primes 2 and 3, is668 # ordered by two of its four generators. Every generator is g₀^e with e a unit of Z_{p−1}, and λ_g = e·λ_{g₀}669 stated = {13: (4, 2, 2, 2), 173: (84, 0, 5, 6), 1549: (504, 0, 6, 12), 30089: (15040, 0, 7, 40)}670 for p in stated:671 n_ = p - 1; H = math.isqrt(p); P = [n for n in range(2, H + 1) if is_prime(n)]672 lam0 = dlog_table(p, generator(p))673 units = [e for e in range(1, n_) if math.gcd(e, n_) == 1]674 ordering, best = 0, 0675 for e in units:676 seq = [(e * lam0[n]) % n_ for n in P]677 ordering += all(a < b for a, b in zip(seq, seq[1:]))678 k = 0679 while k + 1 < len(seq) and seq[k] < seq[k + 1]: k += 1680 best = max(best, k + 1)681 got = (len(units), ordering, best, len(P))682 # 20:O9 (p20090)683 check("A17", f"F_{p}: of its {len(units)} generators, {stated[p][1]} order the {len(P)} primes of the window 2..{H} by the discrete logarithm; the longest ordered run of primes is {stated[p][2]} of {len(P)}",684 got == stated[p], f"(generators, ordering, longest run, primes) = {got}")685686 # A18 no zero off the line (Thm. noline; row F10), on the pairs (13, 233) and (173, 30089): (i) the lines kept by both the687 # conjugation and the half-turn are exactly the meridian and the critical line — every one of the p(p+1) affine lines of the688 # Subject's plane tested, and of the Carrier's on 233; on 30089 the two lines tested and 2000 other lines sampled (the689 # exhaustive statement is the Lean theorem invariant_lines, for every shell); (ii) every label 1 ≤ θ ≤ p−2 of the Subject is690 # a nontrivial mode on the critical line in both frames, the Subject's p−2 zeros (A16); (iii) a point off both lines lies on no line kept by both — every line691 # through it fails — for every such point of the Subject's plane on 13 and for 200 sampled points on 173692 rng = random.Random(2026)693 for p, Om in PAIRS[:2]:694 gp, gO = generator(p), generator(Om)695 kp, kO = (p - 1) // 4, (Om - 1) // 4696 inv2p, inv2O = (2 * kp + 1) % p, (2 * kO + 1) % Om697 both_p = [name for name, L in affine_lines(p) if all(frob(z, p) in L and half_turn(z, p) in L for z in L)]698 ok_i = sorted(both_p) == sorted([("H", 0), ("S", 0, inv2p)])699 kept = lambda name, q: (lambda L: all(frob(z, q) in L and half_turn(z, q) in L for z in L))(700 frozenset((a, name[1]) for a in range(q)) if name[0] == "H" else frozenset(((name[2] + name[1] * b) % q, b) for b in range(q)))701 if Om < 1000:702 both_O = [name for name, L in affine_lines(Om) if all(frob(z, Om) in L and half_turn(z, Om) in L for z in L)]703 ok_i &= sorted(both_O) == sorted([("H", 0), ("S", 0, inv2O)]); carrier = f"every line of F_{Om}²"704 else:705 others = set()706 while len(others) < 2000:707 nm = ("H", rng.randrange(1, Om)) if rng.random() < 0.1 else ("S", rng.randrange(Om), rng.randrange(Om))708 if nm not in (("H", 0), ("S", 0, inv2O)): others.add(nm)709 ok_i &= kept(("H", 0), Om) and kept(("S", 0, inv2O), Om) and not any(kept(nm, Om) for nm in others); carrier = f"the two lines kept and 2000 sampled others not, on F_{Om}²"710 lam_p, lam_O = dlog_table(p, gp), dlog_table(Om, gO)711 ok_ii = all(pow(gp, lam_p[(-t) % p], p) == (-t) % p and pow(gO, lam_O[(-t) % Om], Om) == (-t) % Om712 and 1 <= lam_p[(-t) % p] <= p - 2 and 1 <= lam_O[(-t) % Om] <= Om - 2 for t in range(1, p - 1))713 off = [(a, b) for a in range(p) for b in range(p) if b != 0 and a != inv2p]714 if p > 20: off = rng.sample(off, 200)715 def lines_through(z, q):716 yield frozenset((a, z[1]) for a in range(q))717 for c in range(q):718 a0 = (z[0] - c * z[1]) % q719 yield frozenset(((a0 + c * b) % q, b) for b in range(q))720 ok_iii = all(not any(all(frob(w, p) in L and half_turn(w, p) in L for w in L) for L in lines_through(z, p)) for z in off)721 # 20:F10 (p20093)722 check("A18", f"no zero off the line, pair ({p}, {Om}): the lines kept by both involutions are F_p and L_1/2 and no other tested line (every line of F_{p}², {carrier}); every label 1 ≤ θ ≤ {p - 2} of F_{p} a nontrivial mode on the line in both frames, the Subject's {p - 2} zeros; {'every' if p <= 20 else '200 sampled'} point(s) off both lines on no line kept by both",723 ok_i and ok_ii and ok_iii, f"both-invariant lines of F_{p}²: {both_p}")724725 # A19 the drive theorem (Thm. drive; row E15), on every shell: the drive acts on vectors over F_p^× by (Dv)(x) = v(gx), one726 # chronon. (ii) D x^k = g^k x^k for every mode k (the eigenvector identity, FRC.Rh.shift_power_character) and the eigenvalues727 # g^k are the p−1 nonzero residues, each once: the spectrum is F_p^×, simple; (i) D is orthogonal for the pairing728 # ⟨v, w⟩ = Σ_x v(x) w(x), ⟨Dv, w⟩ = ⟨v, D⁻¹w⟩ on three random pairs, not symmetric, while D + D⁻¹ is symmetric; (iii) the729 # spectrum is real — every eigenvalue a residue of F_p, Frobenius-fixed — and the modes are isotropic, ⟨x^k, x^k⟩ = Z(2k) = 0730 # for k ≠ 0, π and −1 there; (iv) the readout θ_k = −g^k of A15 is minus the eigenvalue; (v) the half-turn negates the731 # eigenvalue, g^{k+π} = −g^k732 for p in SHELLS + [BIG]:733 g = generator(p); n_ = p - 1; pi_ = n_ // 2; ginv = pow(g, p - 2, p); xs = range(1, p)734 D = lambda v: {x: v[(g * x) % p] for x in xs}735 Dinv = lambda v: {x: v[(ginv * x) % p] for x in xs}736 pair = lambda v, w: sum(v[x] * w[x] for x in xs) % p737 modes = {k: {x: pow(x, k, p) for x in xs} for k in range(n_)}738 spec = [pow(g, k, p) for k in range(n_)]739 ok_ii = all(D(modes[k]) == {x: spec[k] * modes[k][x] % p for x in xs} for k in range(n_)) and sorted(spec) == list(range(1, p))740 rng = random.Random(2026 + p)741 vs = [{x: rng.randrange(p) for x in xs} for _ in range(6)]742 pairs3 = ((vs[0], vs[1]), (vs[2], vs[3]), (vs[4], vs[5]))743 ok_i = all(pair(D(v), w) == pair(v, Dinv(w)) for v, w in pairs3)744 symmetric = lambda T: all(pair(T(v), w) == pair(v, T(w)) for v, w in pairs3)745 ok_sym = (not symmetric(D)) and symmetric(lambda v: {x: (D(v)[x] + Dinv(v)[x]) % p for x in xs})746 ok_iii = all(0 < s < p for s in spec) and all(pair(modes[k], modes[k]) == (p - 1 if k in (0, pi_) else 0) for k in range(n_))747 ok_iv = all(((-pow(g, k, p)) % p) == (-spec[k]) % p for k in range(n_)) and (-spec[0]) % p == p - 1748 ok_v = all(pow(g, k + pi_, p) == (-spec[k]) % p for k in range(n_))749 # 20:E15 (p20094)750 check("A19", f"the drive theorem on F_{p}: D x^k = g^k x^k for every mode, the spectrum F_{p}^× simple; ⟨Dv, w⟩ = ⟨v, D⁻¹w⟩ on three random pairs, D not symmetric, D + D⁻¹ symmetric; the spectrum real and the modes isotropic (⟨x^k, x^k⟩ = 0 for k ≠ 0, π, −1 there); the readout minus the eigenvalue; the half-turn negates it",751 ok_i and ok_ii and ok_sym and ok_iii and ok_iv and ok_v, f"g={g}, π={pi_}: eigenvalues g^k = {spec[:6]}…, labels −g^k = {[(-s) % p for s in spec[:6]]}…")752753 # A20 the energy domain is a circle (Rem. cayley; row B14), on the shells in full: w = z/(1 − z) carries the critical line754 # {Tr z = 1} into the unit circle U_{p+1} = {N(w) = 1}, the centre 2⁻¹ to 1, injectively, missing −1 alone (the line's755 # point at infinity); the conjugation becomes the inversion, w(z^p) = w(z)^{−1}; the drive about the centre, read on the756 # circle, fixes 1 and is no rotation: its orbit through the modes has p−1 points, while a rotation w ↦ uw by a point u of757 # U_{p+1} agrees with it on no mode set; the exponents a_k of the modes on a generator of U_{p+1} negate under k ↦ k + π758 # (the conjugation is the inversion), so no affine function of k fits them (an affine a_k would take at most two values)759 for p in SHELLS:760 g, nu = generator(p), nonresidue(p); n_ = p - 1; inv2 = (p + 1) // 2; pi_ = n_ // 2761 one, mone = (1, 0), (p - 1, 0)762 inv = lambda z: zpow(z, p * p - 2, nu, p) # z^{−1} in F_{p²}763 cayley = lambda z: mul(z, inv(((1 - z[0]) % p, (-z[1]) % p)), nu, p) # w = z · (1 − z)^{−1}764 line = [(inv2, b) for b in range(p)]765 ws = [cayley(z) for z in line]766 circle = {z for z in ((a, b) for a in range(p) for b in range(p)) if norm(z, nu, p) == 1}767 ok_circle = len(circle) == p + 1 and all(w in circle for w in ws) and len(set(ws)) == p and cayley((inv2, 0)) == one and mone not in ws768 ok_conj = all(cayley(frob(z, p)) == inv(cayley(z)) == frob(cayley(z), p) for z in line)769 dil = lambda z: (inv2, (g * z[1]) % p) # 2⁻¹ + g(z − 2⁻¹) on the line770 orbit = {cayley(z) for z in line if z[1] != 0}771 ok_fix = cayley(dil((inv2, 0))) == one and len(orbit) == n_ and orbit == set(ws) - {one}772 rotations = [u for u in circle if all(cayley(dil(z)) == mul(u, cayley(z), nu, p) for z in line if z[1] != 0)]773 ok_rot = rotations == []774 u = next(w for w in sorted(circle) if all(zpow(w, j, nu, p) != one for j in range(1, p + 1))) # a generator of U_{p+1}775 log_u = {zpow(u, j, nu, p): j for j in range(p + 1)}776 a = [log_u[ws[(-pow(g, k, p)) % p]] for k in range(n_)] # the mode k sits at b = −g^k777 ok_neg = all((a[(k + pi_) % n_] + a[k]) % (p + 1) == 0 for k in range(n_))778 alpha, beta = (a[1] - a[0]) % (p + 1), a[0] # the one affine candidate, from k = 0, 1779 affine_fails = [k for k in range(n_) if a[k] != (alpha * k + beta) % (p + 1)]780 ok_aff = len(set(a)) == n_ and affine_fails != []781 # 20:B14 (p20095)782 check("A20", f"the energy domain is a circle on F_{p}: z/(1 − z) carries the {p} points of the critical line injectively into U_{p + 1} ({p + 1} points), the centre to 1, −1 not hit; the conjugation becomes the inversion; the drive fixes 1 and is no rotation of the circle; the modes' exponents on a generator of U_{p + 1} negate under k ↦ k + π and fit no affine function of k",783 ok_circle and ok_conj and ok_fix and ok_rot and ok_neg and ok_aff, f"ν={nu}: the modes at the circle points {[ws[b] for b in range(1, 4)]}…; rotations matching the drive: {len(rotations)}; exponents {a[:6]}…, the affine fit from k = 0, 1 fails at k = {affine_fails[:3]}…")784 figure_plane()785786# ======================================================================================================================787# block B — the chart [chart]: the de-framing limit of the half-turn, the exhibit (Obs. exhibit; row F9) on the windows of the788# laboratory Subjects, the pair agreement, and the labels read in the cycle's own scale coordinate (Section order; row O9).789# Nothing here is a shell operation: the window's prime-power labels n ≤ H are read with the chart's weight Λ(n), the taper790# 1 − log n/log H, the scale n^{−1/2} and the height γ, and the intensity is |Σ Λ(n)(1 − log n/log H) n^{−1/2−iγ}|² on a grid of791# step 0.02. A window's five peaks are the five tallest peaks on the range 10 to 36 of the height; its resolution is 2π/log H.792def block_B():793 """Block B — the chart: 10 checks, all [chart]."""794 print("\n== block B: the chart ==")795 # B3 the de-framing limit of the half-turn (Prop. critical; row B8): 2⁻¹/p = (2κ+1)/p → ½ from above, in rationals796 vals = [(p, Fraction(2 * ((p - 1) // 4) + 1, p)) for p in [13, 53, 101, 409, 1009, 10009]]797 ok = all(v > Fraction(1, 2) for _, v in vals) and all(vals[i][1] > vals[i + 1][1] for i in range(len(vals) - 1)) \798 and abs(vals[-1][1] - Fraction(1, 2)) < Fraction(1, 1000)799 check("B3", "de-framing limit (2κ+1)/p → ½ from above", ok, " ".join(f"{p}: {float(v):.5f}" for p, v in vals), kind="[chart]")800 # B5 the exhibit (Obs. exhibit; row F9): the windows of depth 13, 39 and 173 — the windows of F_173, F_1549 and F_30089 —801 # put their five peaks at the first five classical heights within the window's resolution; the peaks to one decimal802 stated = {13: [14.5, 20.5, 25.7, 29.0, 34.9], 39: [14.2, 20.8, 25.4, 30.0, 33.5], 173: [14.2, 20.9, 25.1, 30.2, 33.2]}803 labels = {13: 9, 39: 19, 173: 54}804 got = {}805 for H in stated:806 n, _ = mangoldt(H)807 pk = five_peaks(H)808 got[H] = [round(x, 1) for x in pk]809 ok = (len(n) == labels[H] and got[H] == stated[H] and all(abs(x - z) < resolution(H) for x, z in zip(pk, HEIGHTS[:5]))810 and all(abs(x - z) <= 0.05 + 1e-9 for x, z in zip(got[H], stated[H])))811 # 20:F9 (p20089)812 check("B5", f"the exhibit, window of depth {H} ({labels[H]} prime-power labels): its five peaks {stated[H]} at the first five heights {[round(z, 1) for z in HEIGHTS[:5]]} within the resolution 2π/log {H} = {resolution(H):.1f}",813 ok, f"peaks {got[H]}", kind="[chart]")814 # B6 the pair agreement (row F9): the heights read from a Subject's window and from its Carrier's window agree within the815 # Subject's resolution — on (173, 30089) the Carrier's five peaks lie 0.3, 0.4, 0.5, 1.1, 1.7 from the Subject's, against816 # 2.4; on (1549, 2408561) they lie 0.0, 0.2, 0.3, 0.4, 0.4 apart, against 1.7; the Subject window of (13, 233), of depth 3,817 # holds two prime-power labels, the taper leaves one, and the intensity has no peak818 stated = {(173, 30089): [0.3, 0.4, 0.5, 1.1, 1.7], (1549, 2408561): [0.0, 0.2, 0.3, 0.4, 0.4]}819 for (p, Om), d in stated.items():820 Hp, HO = math.isqrt(p), math.isqrt(Om)821 sub, car = five_peaks(Hp), five_peaks(HO)822 dist = [round(abs(a - b), 1) for a, b in zip(sub, car)]823 ok = dist == d and all(x < resolution(Hp) for x in dist)824 check("B6", f"pair agreement on ({p}, {Om}): the Carrier's window {HO} reads its five peaks {d} from the Subject's window {Hp}, within the Subject's resolution {resolution(Hp):.1f}",825 ok, f"Subject {[round(x, 1) for x in sub]}, Carrier {[round(x, 1) for x in car]}, distances {dist}", kind="[chart]")826 n13, _ = mangoldt(math.isqrt(13))827 e3 = energy(3, np.arange(10, 36, 0.02))828 check("B6", "the pair (13, 233): the Subject's window, of depth 3, holds two prime-power labels, the taper leaves one, and the intensity is flat: no height", len(n13) == 2 and e3.max() - e3.min() < 1e-9,829 f"labels {[int(x) for x in n13]}; the intensity on [10, 36] varies by {e3.max() - e3.min():.1e}", kind="[chart]")830 # B8 the cycle's own scale coordinate (Section order; row O9): read in the discrete logarithm λ_p, the window's prime-power831 # labels load the nontrivial modes like a random sum — on F_1549 the largest loading |Σ_{n∈P} e^{2πi k λ(n)/(p−1)}|² is 108832 # against a mean of 19 (exactly |P| − |P|(|P|−1)/(p−2)) and a random-sum maximum of about |P| log(p−1) = 140 — and no mode833 # stands out834 stated = {173: (30, 9, 46), 1549: (108, 19, 140), 30089: (431, 54, 557)}835 for p in stated:836 n_ = p - 1; H = math.isqrt(p); P = [int(n) for n in mangoldt(H)[0]]837 lam = dlog_table(p, generator(p))838 ph = np.array([lam[n] for n in P])839 ks = np.arange(1, n_)840 load = np.abs(np.exp(2j * np.pi * np.outer(ks, ph) / n_).sum(axis=1)) ** 2841 mx, mean, rnd = load.max(), load.mean(), len(P) * math.log(n_)842 got = (round(mx), round(mean), round(rnd))843 ok = got == stated[p] and mx < rnd and abs(mean - (len(P) - len(P) * (len(P) - 1) / (p - 2))) < 1e-6844 check("B8", f"F_{p}: the {len(P)} prime-power labels of the window read in the discrete logarithm load the {n_ - 1} nontrivial modes at most {stated[p][0]}, mean {stated[p][1]}, a random-sum maximum about {stated[p][2]}: no mode stands out",845 ok, f"(max, mean, random max) = ({mx:.1f}, {mean:.1f}, {rnd:.0f})", kind="[chart]")846847# ======================================================================================================================848# block C — the chart at depth [chart]: the window of depth 10⁶ (the window of a shell with p > 10¹²) and the first849# ten heights; the figure fig_primespec from the same arrays (about 20 s).850def block_C():851 """Block C — the chart at depth: 1 check [chart]; the figure fig_primespec."""852 print("\n== block C: the chart at depth ==")853 # C1 the depth 10⁶ (row F9): the ten tallest peaks on the range 10 to 52 are the first ten heights, each within 0.05854 t = time.time()855 pk = sorted(g for g, _ in peaks(10 ** 6, 10, 52, step=0.01)[:10])856 dev = [abs(x - z) for x, z in zip(pk, HEIGHTS)]857 check("C1", f"the window of depth 10⁶: its ten tallest peaks on the range 10 to 52 are the first ten heights, each within 0.05",858 len(pk) == 10 and max(dev) < 0.05, f"peaks {[round(x, 2) for x in pk]}; max deviation {max(dev):.3f}; {time.time() - t:.0f} s", kind="[chart]")859 figure_primespec()860861if __name__ == "__main__":862 want = [a.upper() for a in sys.argv[1:]] or sorted(BLOCK)863 bad = [b for b in want if b not in BLOCK]864 if bad: sys.exit(f"no block {', '.join(bad)}: the blocks are {', '.join(sorted(BLOCK))}")865 t0 = time.time()866 for b in want:867 t = time.time(); _run_block(b); print(f" [block {b}: {time.time() - t:.0f} s]")868 ok = summary(write=(want == sorted(BLOCK)))869 kinds = {}870 for r in RESULTS: kinds[r["kind"]] = kinds.get(r["kind"], 0) + 1871 print("by kind: " + ", ".join(f"{k} {v}" for k, v in sorted(kinds.items())) + f"; {len(RESULTS)} checks in {time.time() - t0:.0f} s" + ("; results.json written" if want == sorted(BLOCK) else ""))872 sys.exit(0 if ok else 1)873