"""tower.py -- the sill's 2-power tower: with Q(zeta_(2^k)) in K, K_ab = Q(zeta_(2^k)), 2 totally ramified (type (1, 0)), does the F2 place lose, and from which degree; and, beside it, Q(i) in K at d = 12 with the law's algebras fixed to Y = 10^8. QUESTION. At k = 3 (Q(zeta_8) in K, d = 0 mod 4), where is the bound positive (no field loses), and from which d does a field that loses exist? Is there one formula in k? At k = 2, d = 12: does a field lose? THE DERIVATION (by hand, before this code). Let C_k = Q(zeta_(2^k)), of degree D = 2^(k-1), k >= 2, inside K, of degree d = D m', K_ab = C_k. (1) The class. f(K_ab) = 2^k, N = lcm(4, 2^k) = 2^k, G_N = {1}, m(1) = 2^k: L* = L(2^k) (sillclass's class minimum). (2) The odd places. Every odd residue field holds zeta_(2^k), so every odd norm is 1 mod 2^k. An odd R counts in L(2^k) iff N(R) - 1 | 2^k, so N(R) = 2^k + 1 =: n_c, which must be a prime power: a Fermat prime (k = 2, 4, 8, 16; none known past) or 9 (k = 3, Mihailescu); not at k = 5 (33). Depth 1: lambda(R^2) = (n_c - 1) p, p odd, does not divide 2^k. The F2 column holds the odd places with N - 1 a power of 2 once (the losses section's proof): here the Fermat norms n_c and above. (3) The place over 2, e = d, residue F2. For v(z) = j >= 1, (1 + z)^2 - 1 = 2z + z^2 has valuation 2j while 2j < e + j, i.e. j < e: the valuations of (1 + pi)^(2^s) - 1 run 1, 2, 4, ..., 2^s while 2^(s-1) < e. Every 1-unit u has v(u^(2^s) - 1) >= min(2^s, ...) >= 2^s by the same step. So lambda(P^j) = 2^ceil(log2 j) for j <= 2^k when 2^(k-1) < e, and lambda(P^(2^k + 1)) = 2^(k+1): the place over 2 is held to depth exactly 2^k. e = d > 2^(k-1) = D excludes K = C_k only (d = D m', m' >= 2). (4) So L(2^k) = P_k S_c, P_k = 1 + x + ... + x^(2^k) = (1 - x^(2^k+1))/(1 - x), S_c over the places of norm n_c; sigma_F2 = S_c W_k, W_k over the Fermat norms above n_c; log(1 + margin) = M = l - l_c - w_k, l_c = log(1/(1 - x^(2^k + 1))). (At k = 2: l5, W_2 the norms 9, 17, 257, 65537: sillclass's QiLaw.) The places of norm n_c cancel in M. (5) The bound. (1 - x)M' = 1 - (2^k + 1)x^(2^k)/P_k - the W_k terms; x^(2^k)/P_k increases on (0, 1) (the k = 2 algebra: x^(q-1) P_k' < (q - 1) x^(q-2) P_k termwise), the W_k terms increase on (0, 1/2] (D(x, a) > 0 at a >= log2 9), so M rises, then falls once, on [0, x_c], x_c <= 1/2 the root of l + w + log x = 0, w = w_c + w_k. At x_c, M = h_c(x_c) + n_c-count log(1 + n_c^-b), h_c = 2 l - l_c + log x, increasing ((2^k + 1) x^(2^k) <= P_k). At a fixed count of n_c both terms rise with x_c, which falls with the other counts, so the bound takes those maximal (d each: a Fermat prime above n_c is 1 mod 2^k, split completely in C_k) and scans the count of n_c from 0 to its cap: d, but d/2 at k = 3 (3 has two primes of norm 9 in Z[zeta_8], each with at most m' places of degree 1 over it). (6) The certificate's law (arm Z, the TRANSPLANT from Q(i), where the bound's argmin had no place of the cancelling norm): over the primes of Z[zeta_(2^k)] below Y = 10^5, the Fermat norms above n_c split completely; every other prime of Z[zeta_(2^k)] of residue degree m' over each prime above it (a rational p of order f mod 2^k gives D/f places of norm p^(f m')), n_c among them; at 2, Q_2(zeta_(2^k))(pi^ (1/m')), e = d; three primes of C_k above Y for S_(m') at m' >= 3, and at m' = 2 one prime split and a conjugate inert, so K is not Galois over Q; either way K_ab = C_k (an abelian subfield F gives F C_k between C_k and K, abelian over Q, so C_k). Its certificate is splitsharp's: M at x_low, the root of the increasing bound g_up on the point's equation, with M' < 0 there and x_c < 1/2. (7) Hand sizes. h_c(x) = 0 near x = (3 - sqrt 5)/2 = 0.382 (2 l + log x = 0 at (1 - x)^2 = x, l_c ~ x^9 a shift of 3e-5). At the count 0, x_c >= 0.382 iff w_k(0.382) <= l(0.382) = 0.48121: per unit of d, w_3(0.382) = 0.019832 (17: 0.01938; 257: 4.5e-4), so d <= 24.26 at k = 3; w_4(0.382) = 4.513e-4 (257, 65537), d <= 1066 at k = 4. PREDICTIONS (frozen before the engine). P1 at k = 3 the bound's argmin over the count of 9 is 0 at every d scanned (d = 8..200, d = 0 mod 4). P2 at k = 3 the bound is positive at every d = 0 mod 4 from 8 to 24 and at most 0 at every one from 28 to 200. P3 at k = 3 the arm-Z certificate (C < 0, M' < 0, x_c < 1/2) holds at every d = 0 mod 4 from a least D3 in {28, 32, 36} to 1000, and at no d where the bound is positive. P4 at k = 4 (d = 0 mod 8, from 16) the bound at count 0 is positive at every d to 1064 and at most 0 from 1072 to 1200; the arm-Z certificate holds from a least D4 in [1072, 1200] to 1600. P5 at k = 2, d = 12, arm B with its algebras fixed to Y = 10^8 (the places between 10^5 and Y of norm p^6 or p^12, bounded): the certificate is in [-0.009, -0.006], M' < 0, x_c < 1/2, so a field containing Q(i) loses at d = 12. (A rough probe that dropped those places printed -0.0073 at 10^8, +0.0020 at 10^7.) KILL of the tower reading: P2's band missed by more than one step of 4 at either end, or P3 failing (a d past D3 to 1000 uncertified). CONTROLS (frozen). C1 POSITIVE: the engine at k = 2 reproduces sillclass.bound_i(d) at d = 4, 12, 20, 100 and QiLaw(qi_law(d, no5=True)).cert() at d = 12, 14, 100, 1000, each to 1e-12. C2 the chain over 2 by brute force (U^1/U^j generated by 1 + t^i, i < j, its exponent the largest of their orders) in Z_2[t]/(t^e - 2): at e = 8 and 12, lambda(P^j) | 8 exactly for j <= 8 (1, 2, 4, 4, 8, 8, 8, 8, then 16); at e = 16, | 16 exactly for j <= 16. At K = C_3 itself (e = 4, pi = 1 - zeta_8) the chain is printed, an observation. C3 the new M against its products at k = 3, d = 24, x = 0.3 (to 1e-12), its derivative against a central difference (1e-6), and the bound at counts 0 and d/2 against M(x_c) on the law of exactly those counts (1e-12). C4 (P5's own control; its first half by construction, BigLaw.mid being 0 at Y = 10^5, so it reads the wiring) the Y = 10^8 law at Y = 10^5 reproduces arm B's certificate +0.041683 at d = 12 (1e-12), and its bound on the places between 10^5 and 10^6 is at least their brute sum at x_low. C5 (added after the run with BigLaw's D, ARM Y's own control; its first half by construction, as C4's) the Y law at k = 3, D = 4: at Y = 10^5 it is arm Z to 1e-12, and at d = 28 its bound on the places between 10^5 and 10^6 is at least their brute sum at x_low. FINDINGS (entered after the run, from its printed output). CONTROLS. C1: difference 0.0 on the bound and the certificate. C2: e = 8 and 12 read 1, 2, 4, 4, 8, 8, 8, 8, 16; e = 16 reads 2^ceil(log2 j) through 32 at j = 17; Z_2 reads 1, 2, 2, 4, 8, 16. At K = Q(zeta_8) itself (e = 4, outside the derivation's e > 4) the chain reads 1, 2, 4, 4, 8 at j = 5..14, then 16: 8 held to depth 14, an observation. C3: 0.0, 1.7e-11, 6.7e-16. C4: 0.0; 3.053e-39 >= 1.289e-40. C5: 0.0; 5.686e-46 >= 1.174e-47. P1 HOLDS: the bound's argmin over the count of 9 is 0 at every d = 8.. 200 at k = 3. P2 HOLDS: positive at 8..24 (+0.299509 at 8, +0.003126 at 24), at most 0 from 28 (-0.043153) to 1000 (-1.164273, count 0 past 200). P3 HOLDS: the arm-Z certificate at Y = 10^5 is negative with M' < 0, x_c < 1/2 at every d = 0 mod 4 from D3 = 36 (-0.013356) to 1000 (-1.156163), positive at 28 (+0.061523) and 32 (+0.022713), and nowhere the bound is positive. P4 FAILS as frozen. Its bound half holds: at count 0 the bound is positive at every d = 0 mod 8 to 1064 (+0.000656) and at most 0 from 1072 (-0.000818) to 1200; with the full scan (run to 1080, past the first run's 200), positive at 16..1064, its argmin n = d at every printed d to 200 and 0 at every printed d from 400 to 1080. The certificate half fails: at Y = 10^5 no certificate is negative to 1600 (+0.286780 at 1072, +0.259753 at 1600, x_low near 0.30 against x_c near 0.38): the tail allowance past Y prints 0.3024 at d = 1600 (x_low 0.29368, b 1.768), the hand sizes having priced w_k and not the tail. P5 HOLDS: at Y = 10^8 the d = 12 certificate is -0.007295 (M' -2.970, x_c 0.37817); +0.041683, +0.017877, +0.002006 at 10^5, 10^6, 10^7, -0.012014 at 10^9. So a field containing Q(i), type (1, 0), loses at d = 12. KILL MISSED. ARM Y (added after the run, the P4 failure's design variable): the arm-Z algebras fixed to Y = 10^30, the places between 10^5 and Y bounded (C5), the certificate negative with M' < 0 and x_c < 1/2 at every degree read from the bound's first degree at most 0 (at k = 2 sillclass's bound_i, -0.029970 at 12, +0.027465 at 10; x_c < 1/2 holds by the bracket, brentq raising otherwise): k = 2, every even d from 12 (-0.015555) to 1000 (-1.537829); k = 3, every d = 0 mod 4 from 28 (-0.033743) to 1000 (-1.156851), +0.011781 at 24; k = 4, every d = 0 mod 8 from 1072 (-0.000483) to 2000 (-0.123796), +0.000991 at 1064. So at each k read the losing degrees are exactly those where the bound is at most 0: with Q(zeta_(2^k)) in K, K_ab = Q(zeta_(2^k)), type (1, 0), excluding K = Q(zeta_(2^k)) itself (e = 2^(k - 1), outside the depth step), no field loses at d < D(k) and one loses at each d from D(k) to the read's end, D(2) = 12 (to 1000, and every even d past 928 by sillclass's lemma), D(3) = 28 (to 1000), D(4) = 1072 (to 2000). D(k) is the first d = 0 mod D past d* = l(x0)/u_k(x0), x0 = (3 - sqrt 5)/2, u_k the W_k terms of w per unit of d (9 at weight 1/2 at k = 2): d* = 11.20, 24.27, 1067.55 (arm_y's print, added after the run; (7) gave 24.26 and 1066 from rounded terms), read at three k, a pattern. The bound at count 0 turns where x_c crosses h_c's root, x0 shifted by l_c, and x_c = x0 where d u_k(x0) = l(x0): the pattern's content is that neither the shift nor the scan over the count of n_c moves the turn across an admissible degree, and that the certificate turns there too. RUN RECORD. `python tower.py` under a 2048 MB cap: 6 of 6 checks, 6.7 s, peak commit 62.4 MB. The first run (5 of 5 checks, 2.1 s, 61.9 MB) had k = 4's full scan to 200 and no ARM Y; P1-P5 and the kill read the same in both. At review: the tail print added, ARM Y's k = 2 start computed from bound_i (it was 12 by hand), dead names cut; every other line printed as before, 6 of 6 checks, 6.9 s, 62.9 MB. The engine's first draft set t = 0 in the e = 1 brute (fixed before any control read, the Z_2 row added as its check). Moved in from the lab with two references rewritten and the d* print added (dstar, read in arm_y); every other line printed as before, 6 of 6 checks, 6.9 s. """ import math import os import sys import time HERE = os.path.dirname(os.path.abspath(__file__)) sys.path.insert(0, os.path.join(HERE, "..", "code")) os.environ.setdefault("OPENBLAS_NUM_THREADS", "1") import numpy as np # noqa: E402 from scipy.optimize import brentq # noqa: E402 import sillclass as sc # noqa: E402 import splitend as se # noqa: E402 import splitloss as sl # noqa: E402 import splitsharp as ss # noqa: E402 import typeloss as tl # noqa: E402 CHECKS = [] Y = ss.Y YBIG = 10 ** 30 PR_Y = [int(p) for p in ss.PR_Y.tolist() if p > 2] def check(name, ok, detail=""): CHECKS.append(bool(ok)) print(f" [{'PASS' if ok else 'FAIL'}] {name}" + (f" ({detail})" if detail else "")) def guard(): if not all(CHECKS): print("a control failed: no verdict") sys.exit(1) # ------------------------------------------------------------- the tower def nc(k): return 2 ** k + 1 def wk(k): """The F2 column's norms above n_c, 1 mod 2^k (Fermat numbers counted as prime, a bound, as splitend's NORMS).""" return [n for n in se.NORMS if n > nc(k) and (n - 1) % 2 ** k == 0] def caps(k, d): """The worst counts: the norms of W_k and the cap on n_c's.""" w = [(n, d // 2 if n == 9 else d) for n in wk(k)] return w, (d // 2 if k == 3 else d) def lc(k, x): return -math.log1p(-x ** nc(k)) def hc(k, x): return 2 * se.lf(x) - lc(k, x) + math.log(x) def bound_at(k, d, n): """(M(x_c), n, x_c) at n places of norm n_c, the others maximal.""" w, _ = caps(k, d) pairs = [(math.log2(m), c) for m, c in w] + [(math.log2(nc(k)), n)] def g(x): lx = math.log(x) return (se.lf(x) + lx + sum(c * math.log1p(math.exp(a * lx)) for a, c in pairs if c)) xc = brentq(g, 1e-14, 0.5, xtol=1e-18, rtol=1e-15, maxiter=500) return hc(k, xc) + n * math.log1p(xc ** math.log2(nc(k))), n, xc def bound(k, d, full=True): if not full: return bound_at(k, d, 0) return min((bound_at(k, d, n) for n in range(caps(k, d)[1] + 1)), key=lambda r: r[0]) def order_mod(p, q): f, r = 1, p % q while r != 1: r = r * p % q f += 1 return f def law(k, d): """Arm Z: over the primes of Z[zeta_(2^k)] below Y, those of norm in W_k split completely, every other of residue degree m' = d/D.""" D = 2 ** (k - 1) mp = d // D W = set(wk(k)) out = [] for p in PR_Y: f = order_mod(p, 2 ** k) q = p ** f if q in W: out.append((math.log2(q), d // f, 1)) else: out.append((f * mp * math.log2(p), D // f, 0)) return ss.Law(d, out) class TowerLaw(tl.TypeLaw): """Type (1, 0), M = l - l_c - (w - w_c).""" def __init__(self, k, base): super().__init__(1, 0, [], base) self.k = k self.ac = math.log2(nc(k)) def wc(self, x): B = self.base sel = (B.k == 1) & (np.abs(B.a - self.ac) < 1e-12) return float((B.c[sel] * np.log1p(x ** B.a[sel])).sum()) def m(self, x): return se.lf(x) - lc(self.k, x) - (self.w(x) - self.wc(x)) def dm(self, x): B = self.base sel = (B.k == 1) & (np.abs(B.a - self.ac) > 1e-12) aa = B.a[sel] dw = float((B.c[sel] * aa * x ** (aa - 1) / (1 + x ** aa)).sum()) q = nc(self.k) return 1 / (1 - x) - q * x ** (q - 1) / (1 - x ** q) - dw def certify(k, d): C, dm, xl, xc = TowerLaw(k, law(k, d)).cert() return C, dm, xl, xc, (C < 0 and dm < 0 and xc < 0.5) # ------------------------------------------------------- the chain over 2 def chain(E, jmax): """lambda(P^j), j = 1..jmax, in Z_2[t]/(E), E Eisenstein given by its lower coefficients (t^e = -sum E_i t^i): the exponent of U^1/U^j, generated by 1 + t^i, i < j.""" e = len(E) def mul(a, b, mod): r = [0] * (2 * e) for i, ai in enumerate(a): if ai: for j, bj in enumerate(b): r[i + j] += ai * bj for i in range(2 * e - 1, e - 1, -1): c = r[i] if c: r[i] = 0 for j, Ej in enumerate(E): r[i - e + j] -= c * Ej return [c % mod for c in r[:e]] def val(a, mod): v = math.inf for i, c in enumerate(a): if c % mod: v = min(v, e * ((c & -c).bit_length() - 1) + i) return v out = [] for j in range(1, jmax + 1): mod = 2 ** (-(-j // e) + 2) lam = 1 for i in range(1, j): u = [0] * e u[0] = 1 ti = [0] * e ti[0] = 1 for _ in range(i): ti = mul(ti, [0, 1] + [0] * (e - 2) if e > 1 else [-E[0] % mod], mod) u = [(a + b) % mod for a, b in zip(u, ti)] o = 1 while True: z = list(u) z[0] -= 1 if val(z, mod) >= j: break u = mul(u, u, mod) o *= 2 lam = max(lam, o) out.append(lam) return out # ----------------------------------------------------- Q(i) at d = 12, Y class BigLaw(ss.Law): """A law's places below 10^5 (base); those between 10^5 and Yc bounded: residue degree m' = d/D over each prime of C_k there gives at most D places per prime, each of norm at least p^(m'); d places per prime past Yc (the tail). At k = 2 (D = 2): arm B's algebras fixed to Yc.""" def __init__(self, base, Yc, D=2): self.d, self.Yc, self.tail, self.D = base.d, Yc, True, D self.a, self.c, self.k = base.a, base.c, base.k def mid(self, x): if self.Yc <= Y: return 0.0 s = -math.log2(x) * (self.d // self.D) N = Y return self.D * (N ** -s + N ** (1 - s) / (s - 1)) / (1 - N ** -s) def parts(self, x): lz, sw, w, lt = super().parts(x) return lz, sw, w, lt + self.mid(x) # ------------------------------------------------------------------ main def controls(): print("=== CONTROLS") e1 = max(abs(bound(2, d)[0] - sc.bound_i(d)[0]) for d in (4, 12, 20, 100)) e2 = 0.0 for d in (12, 14, 100, 1000): a = TowerLaw(2, law(2, d)).cert() b = sc.QiLaw(sc.qi_law(d, no5=True)).cert() e2 = max(e2, max(abs(u - v) for u, v in zip(a, b))) check("C1 POSITIVE: k = 2 is sillclass's bound_i and arm B", e1 < 1e-12 and e2 < 1e-12, f"{e1:.1e}, {e2:.1e}") want8 = [1, 2, 4, 4, 8, 8, 8, 8, 16] c8, c12 = chain([-2] + [0] * 7, 9), chain([-2] + [0] * 11, 9) c16 = chain([-2] + [0] * 15, 17) z2 = chain([-2], 6) ok16 = all(c16[j - 1] == 2 ** math.ceil(math.log2(j)) for j in range(1, 18)) check("C2 the brute chain: e = 8, 12 read 1, 2, 4, 4, 8, 8, 8, 8, 16; " "e = 16 reads 2^ceil(log2 j) to j = 17", c8 == want8 and c12 == want8 and ok16, f"e = 8 {c8}; e = 16 {c16}") check("C2 the brute at Z_2 reads (Z/2^j)^*'s exponent", z2 == [1, 2, 2, 4, 8, 16], f"{z2}") print(f" K = Q(zeta_8) itself (e = 4, pi = 1 - zeta_8): " f"{chain([2, -4, 6, -4], 17)}") d, x = 24, 0.3 base = law(3, d) base = ss.Law(d, list(zip(base.a, base.c, base.k)) + [(math.log2(9), 5, 1)]) q = TowerLaw(3, base) b = -math.log2(x) lnum = (math.log(sum(x ** i for i in range(9))) + 5 * math.log1p(9 ** -b)) lden = sum(c * math.log1p(2 ** (-b * a)) for a, c, kk in zip(base.a, base.c, base.k) if kk == 1) e1 = abs(q.m(x) - (lnum - lden)) hh = 1e-6 e2 = abs(q.dm(x) - (q.m(x + hh) - q.m(x - hh)) / (2 * hh)) e3 = 0.0 for n in (0, d // 2): v, _, xc = bound_at(3, d, n) w, _ = caps(3, d) W = [(math.log2(m), c, 1) for m, c in w] + [(math.log2(9), n, 1)] e3 = max(e3, abs(v - TowerLaw(3, ss.Law(d, W, tail=False)).m(xc))) check("C3 k = 3: M = log(L(8)/sigma_F2), M' its derivative, the bound " "= M(x_c)", e1 < 1e-12 and e2 < 1e-6 and e3 < 1e-12, f"{e1:.1e}, {e2:.1e}, {e3:.1e}") base = sc.qi_law(12, no5=True) a = sc.QiLaw(BigLaw(base, Y)).cert() b = sc.QiLaw(base).cert() e4 = max(abs(u - v) for u, v in zip(a, b)) xl = sc.QiLaw(BigLaw(base, 10 ** 8)).cert()[2] pr = sl.primes_to(10 ** 6) pr = pr[pr > Y].tolist() bb = -math.log2(xl) brute = sum(2 * -math.log1p(-float(p) ** (-6 * bb)) if p % 4 == 1 else -math.log1p(-float(p) ** (-12 * bb)) for p in pr) mid = BigLaw(base, 10 ** 8).mid(xl) check("C4 the Y law at Y = 10^5 is arm B; its mid bound >= the places " "10^5..10^6 at x_low", e4 < 1e-12 and mid >= brute, f"{e4:.1e}; {mid:.3e} >= {brute:.3e}") d = 28 q = TowerLaw(3, BigLaw(law(3, d), YBIG, 4)) xl = q.cert()[2] bb = -math.log2(xl) brute = 0.0 for p in pr: f = order_mod(p, 8) brute += (4 // f) * -math.log1p(-float(p) ** (-f * (d // 4) * bb)) mid = q.base.mid(xl) e5 = max(abs(u - v) for u, v in zip( TowerLaw(3, BigLaw(law(3, d), Y, 4)).cert(), TowerLaw(3, law(3, d)).cert())) check("C5 (added after the run) the Y law at k = 3: at Y = 10^5 it is " "arm Z; its mid bound >= the places 10^5..10^6 at x_low, d = 28", e5 < 1e-12 and mid >= brute, f"{e5:.1e}; {mid:.3e} >= {brute:.3e}") guard() def section_tower(k, dmax, dfull, step): print(f"\n=== k = {k}: Q(zeta_{2 ** k}) in K, d = 0 mod {step}") d0 = 2 * step rows = {} for d in range(d0, dmax + 1, step): full = d <= dfull bd = bound(k, d, full) rows[d] = [bd, full, None] pos = [d for d in rows if rows[d][0][0] > 0] neg = [d for d in rows if rows[d][0][0] <= 0] print(f" bound (full scan to {dfull}, count 0 past it): positive at " f"{min(pos) if pos else None}..{max(pos) if pos else None}, " f"at most 0 from {min(neg) if neg else None}; " f"monotone: {not neg or not pos or max(pos) < min(neg)}") nz = [(d, rows[d][0][1]) for d in rows if rows[d][1] and rows[d][0][1] != 0] print(f" argmin count of n_c = {nc(k)}: 0 at every fully scanned d: " f"{not nz}" + ("" if not nz else f"; else at {nz[:8]}")) return rows, pos, neg def certs(k, rows, dmax, step): out = [] for d in range(2 * step, dmax + 1, step): C, dm, xl, xc, ok = certify(k, d) if d in rows: rows[d][2] = (C, dm, xl, xc, ok) out.append((d, C, dm, xl, xc, ok)) return out def main(): t0 = time.time() controls() out = {} for k, dmax, dfull, cmax, step in ((3, 1000, 200, 1000, 4), (4, 1200, 1080, 1600, 8)): rows, pos, neg = section_tower(k, dmax, dfull, step) cs = certs(k, rows, cmax, step) good = [d for d, C, dm, xl, xc, ok in cs if ok] dh = min(good) if good else None tail = dh is not None and all(ok for d, C, dm, xl, xc, ok in cs if d >= dh) clash = [d for d in pos if d in good] for d, C, dm, xl, xc, ok in cs: if (d <= 64 or d % 200 == 0 or (dh and abs(d - dh) <= 2 * step) or (pos and abs(d - max(pos)) <= 2 * step)): bd = rows.get(d, [None])[0] bs = (f" bound {bd[0]:+.6f} (n {bd[1]}, x_c {bd[2]:.5f})" if bd else "") print(f" d={d:5d}: certificate {C:+.6f} (M' {dm:+.3f}, " f"x_low {xl:.5f}, x_c {xc:.5f}){bs}") print(f" least certified d {dh}; every d from it to {cmax} " f"certified: {tail}; a certificate where the bound is " f"positive: {clash}") out[k] = (pos, neg, dh, tail, clash, rows) d, C, dm, xl, xc, ok = cs[-1] b = -math.log2(xl) lt = d * (Y ** -b + Y ** (1 - b) / (b - 1)) / (1 - Y ** -b) print(f" the tail past Y = 10^5 at d = {d}, x_low {xl:.5f} (b " f"{b:.3f}): d (Y^-b + Y^(1-b)/(b - 1))/(1 - Y^-b) = {lt:.4f}") print("\n=== Q(i), d = 12, arm B's algebras fixed to Y") base = sc.qi_law(12, no5=True) c12 = {} for e in (5, 6, 7, 8, 9): C, dm, xl, xc = sc.QiLaw(BigLaw(base, 10 ** e)).cert() c12[e] = (C, dm, xl, xc) print(f" Y = 10^{e}: certificate {C:+.6f} (M' {dm:+.3f}, x_low " f"{xl:.5f}, x_c {xc:.5f})") pos3, neg3, dh3, tail3, clash3, rows3 = out[3] p1 = all(rows3[d][0][1] == 0 for d in rows3 if rows3[d][1]) p2 = (pos3 == [d for d in range(8, 25, 4)] and all(d in neg3 for d in range(28, 201, 4))) p3 = dh3 in (28, 32, 36) and tail3 and not clash3 pos4, neg4, dh4, tail4, clash4, rows4 = out[4] b0 = {d: bound_at(4, d, 0)[0] for d in range(16, 1201, 8)} p4 = (all(b0[d] > 0 for d in b0 if d <= 1064) and all(b0[d] <= 0 for d in b0 if d >= 1072) and dh4 is not None and 1072 <= dh4 <= 1200 and tail4) lo = max([d for d in b0 if b0[d] > 0], default=None) print(f"\n k = 4, count 0 alone: positive to {lo}") C, dm, xl, xc = c12[8] p5 = -0.009 <= C <= -0.006 and dm < 0 and xc < 0.5 for name, ok in (("P1", p1), ("P2", p2), ("P3", p3), ("P4", p4), ("P5", p5)): print(f" {name} {'holds' if ok else 'FAILS'}") kill = not p2_band(pos3, neg3) or not (dh3 and tail3) print(f" KILL {'fires' if kill else 'missed'}") arm_y(out) print(f"\n{sum(CHECKS)} of {len(CHECKS)} checks, " f"{time.time() - t0:.1f} s") return 0 if all(CHECKS) else 1 def arm_y(out): """ARM Y (added after the run): the arm-Z algebras fixed to Y = 10^30, the certificate read from the bound's first degree at most 0.""" print(f"\n=== ARM Y: the algebras fixed to Y = 10^30") for k, step, dmax in ((2, 2, 1000), (3, 4, 1000), (4, 8, 2000)): if k == 2: first = min(d for d in range(4, 201, 2) if sc.bound_i(d)[0] <= 0) else: first = min(out[k][1]) D = 2 ** (k - 1) good, bad = [], [] for d in range(first, dmax + 1, step): base = sc.qi_law(d, no5=True) if k == 2 else law(k, d) C, dm, xl, xc = TowerLaw(k, BigLaw(base, YBIG, D)).cert() ok = C < 0 and dm < 0 and xc < 0.5 (good if ok else bad).append(d) if d - first <= 2 * step or d % 200 == 0: print(f" k = {k}, d={d:5d}: certificate {C:+.6f} (M' " f"{dm:+.3f}, x_low {xl:.5f}, x_c {xc:.5f})") print(f" k = {k}: certified at every d = 0 mod {step} from {first} " f"to {dmax}: {not bad}" + ("" if not bad else f" (not at " f"{bad[:6]})")) if k > 2: pre = TowerLaw(k, BigLaw(law(k, first - step), YBIG, D)).cert() print(f" k = {k}, d = {first - step} (bound positive): " f"certificate {pre[0]:+.6f}") ds = dstar(k) fa = step * math.ceil(ds / step) print(f" k = {k}: d* = l(x0)/u_k(x0) = {ds:.2f}; the first d = 0 " f"mod {step} past it {fa}, the bound's first at most 0 " f"{first}: equal {fa == first}") def dstar(k): """d* = l(x0)/u_k(x0), x0 = (3 - sqrt 5)/2 (2 l + log x = 0), u_k the W_k terms of w per unit of d (9 at weight 1/2).""" x0 = (3 - math.sqrt(5)) / 2 u = sum((0.5 if n == 9 else 1.0) * math.log1p(x0 ** math.log2(n)) for n in wk(k)) return se.lf(x0) / u def p2_band(pos, neg): """P2's band within one step of 4 at either end.""" return (pos and min(pos) == 8 and 20 <= max(pos) <= 28 and neg and 24 <= min(neg) <= 32) if __name__ == "__main__": sys.exit(main())