danger.py
Checks: FLATTEN: The takeover depth grows at least as r^(3/2) theorem; rule; pattern.
Cited on: FLATTEN.
To run it: save danger.py, with band.py, bandend.py, bandfamily.py, circlemean.py, compbound.py, exacttest.py, flatten.py, prunerr.py, takeph.py beside it; needs mpmath, numpy, sympy.
"""danger.py -- at the takeover theorem's own e(r), does the exact centred
test put every single-odd-part shape above F_e's circle mean?
QUESTION. J* = (4e - 1) l - 1, l = r - 2, e = floor(sqrt(l/2)) at odd r,
floor(sqrt(l)/2) at even r, e = 3..11 (odd r = 21..289, even r =
38..576). The shapes k=0 2^(r-g) g, g odd >= 5: is the exact centred
test, best over p, above F_e's mean at every one?
BY HAND (re-derived before the code). al = (r - g + 1 + q)/2, be =
(J + p)/2, q = (r - g) mod 2, a = l/2, b = (J + 1)/2:
X/mean = B1 |E cos gu| / A, B1 = 2^(p+q+3-g)/|w|_1 B(al, be)/B(a, b),
u drawn as cos^(2be-1) sin^(2al-1) on [0, pi/2], A = E|1 - 4eU|,
U ~ Beta(a, b). The hand form H replaces E cos gu by cos(g ubar)
exp(-g^2 Var u/2), ubar and Var u read off the shape's own Beta(al, be)
with Jensen's correction (partfive.py's C5h at general g). The class
read off u0 = arcsin(1/(2 sqrt e)) dies past the first crossing: the
shape's own mean moves g u by O(1) once g ~ sqrt(l) (e = 5, r = 53,
g = 21: g u0 = 4.736, g ubar = 3.834). Scale: X/mean ~ 0.63 l
|cos g ubar| near the first crossing, the per-rank least O(1) with no
e-trend; p rescues at most ~0.33 g/sqrt(8e).
PREDICTIONS (frozen before the code). P1 H/exact in [0.95, 1.05] at
every shape with g <= r/2 and |cos g ubar| >= 0.2, at its exact best p.
P2 per rank the least exact X/mean sits at a part of the first or second
crossing, in [1, 4] at most ranks, with no rising trend in e. P3 at
e = 5 the binding shape is the part-7 shape, least in [1.2, 2.2]. P4
somewhere in e = 3..11 a shape falls below the mean.
KILL. Printed per rank: the least exact X/mean over the family, its g
and p, and H at the same (g, p). H/exact outside [0.9, 1.1] at a rank's
binding shape fires: the hand form cannot carry a uniform margin.
CONTROLS, read first. C1 at e = 3, odd r = 21..33: the part-5 shape's
exact X/mean equals partfive's printed 2.6738 .. 2.7100 (4 digits). C2
at e = 4, odd r = 39..51: the part-7 shape reads exacttest's 9.8599 ..
14.0320. PLANT: H with cos((g - 2) ubar) leaves [0.9, 1.1] of exact at
the part-5 shape at every r of C1. C3 psi1 equals
exacttest.psi at r = 53, every g; at r = 53, 54, 101, 102, 289 the
pipeline's least and below-list equal the full read's (best_x at every
shape; the below-lists are empty at all five).
The pipeline (changed after the first run, which read exact only the
shapes whose hand best fell below 6 and each rank's three least by
hand): every shape is read exact at its hand-best p; exacttest.best_x,
a scan over p that stops 40 steps past its best (not the maximum: at
r = 258, g = 251 the hand-best p reads 6.3 times its value), is read
where that read is below the running least or the mean. Every shape
then has some p whose exact X/mean is at least the printed least, and
none skipped is below the mean; that the least equals the full read's
is C3's, at its five ranks. "Least" is the least best_x read, a lower
bound on the least maximum over p.
FINDINGS (copied from the printed output).
(1) The controls hold. C1: the part-5 shape reads 2.6738 .. 2.7100 at
r = 21..33, H/exact 0.9981 .. 0.9991, the cos 3u plant 3.4751 ..
4.1417 (caught at every r). C2: 9.8599 (r = 39), 14.0320 (r = 51).
C3: psi1 differs at 0 of 25 shapes; the pipeline's least equals the
full read at r = 53 (11.1125, g = 7), 54 (2.3361, g = 5), 101
(38.5160, g = 5), 102 (5.5378, g = 7), 289 (124.0961, g = 5).
(2) The KILL misses: at all 405 ranks H/exact at the binding shape
lies in 0.9981 .. 1.0002. P1 at its frozen p, best_x's, is
read only at the binding shapes (the KILL's H/exact); read at each
shape's hand-best p it fails at 33 shapes, all at even r =
192..572 with g >= 0.46 r, H/exact 0.942 .. 1.067.
(3) All 51165 shapes are read exact at their hand-best p, 405 (one a
rank) by best_x: no shape falls below the mean at any rank (P4
fails). The least per (e, parity), at r and g:
e odd r even r
3 2.6617 (25, 5) 2.1747 (38, 5)
4 7.8844 (35, 5) 7.8243 (66, 5)
5 8.5955 (73, 7) 4.1169 (144, 7)
6 25.8052 (75, 5) 27.3201 (146, 5)
7 38.5160 (101, 5) 41.1192 (198, 5)
8 32.1444 (163, 9) 57.5718 (258, 9)
9 71.4459 (165, 5) 76.8094 (326, 5)
10 91.6668 (203, 5) 98.6990 (402, 5)
11 114.3926 (245, 5) 123.2842 (486, 5)
The binding part is 5 at 358 ranks, 7 at 33 (all of e = 5), 9 at
14 (of e = 8: odd r = 139..163 and r = 258). P2 fails: the
least rises with e, with dips at e = 5 and 8. P3 fails: e = 5 binds at the part-7 shape as
predicted, but at 4.1169 (even) and 8.5955 (odd), above 2.2.
(4) Within e = 5 the part-7 shape falls in r: 11.1125 (r = 53) to
8.5955 (r = 73), 5.5378 (r = 102) to 4.1169 (r = 144).
READS. The dips sit where the first-crossing part's g u0 is just above
pi/2: 7u0 = 1.579 at e = 5 (0.008 above), 9u0 = 1.599 at e = 8. The
shape's own downward shift, about g(g - 3)/(4 sqrt(e) l) (its mean
alone, odd r, p = 0; Jensen adds a further g/(8 sqrt(e) l) downward,
and p moves it further at even r), holds g ubar below the zero, and it
shrinks as l grows, so the margin falls in r at fixed e (at e = 5 the
mean alone would close it near l ~ 400, with Jensen near l ~ 450,
argued, not printed; e = 5's window ends at l = 142). Away from a dip the binding shape is
the part 5, where 5 ubar falls toward 0 as e grows: X/mean over l reads
0.47 (r = 245) to 0.43 (r = 289) at e = 11's odd ranks, 0.25 to 0.23
at its even ones. BY HAND's scale 0.63 l |cos g ubar| held the part
5's prefactor; B1 grows with g, and the part 7 stands above that
scale at e = 5. A dip is an accident
of e: one window of l moves the shift by O(e^-2.5), so the margin at e
is set by how near g u0, read mod pi, sits to pi/2 + shift: a
Diophantine condition on pi/(2 arcsin(1/(2 sqrt e))) against the odd
integers, which the centred test alone cannot bound uniformly. The
design variable is e itself: J_hi >= c r^(3/2) needs only some e of
order sqrt(l) per rank, not the theorem's.
RUN RECORD. 15.7 s, peak commit 29.0 MB. The full read
(best_x at every shape) costs 20.4 s at r = 576 alone, about 25 min
over the range (a separate timing run).
"""
import math
import os
import sys
import time
os.environ.setdefault("OPENBLAS_NUM_THREADS", "1")
import circlemean # noqa: E402
import compbound # noqa: E402
import exacttest # noqa: E402
import takeph # noqa: E402
LN2 = math.log(2)
def setup(r):
e, J = takeph.theorem_e(r), takeph.theorem_J(r)
l = r - 2
lm = circlemean.log_mean(r, J, e)
logA = float(circlemean.mp.log(circlemean.mad(
circlemean.mp.mpf(l) / 2, circlemean.mp.mpf(J + 1) / 2, 4 * e)))
return e, l, J, lm, logA
def lbeta(x, y):
return math.lgamma(x) + math.lgamma(y) - math.lgamma(x + y)
def hand(r, J, logA, g, p, shift=0):
"""log H and cos(g ubar) at (g, p); shift: the plant's g - 2."""
l = r - 2
q = (r - g) % 2
a, b = l / 2, (J + 1) / 2
al, be = (r - g + 1 + q) / 2, (J + p) / 2
lB1 = ((p + q + 3 - g) * LN2 - compbound.log_w1(p, q)
+ lbeta(al, be) - lbeta(a, b))
U = al / (al + be)
VU = al * be / ((al + be) ** 2 * (al + be + 1))
upp = -(1 - 2 * U) / (4 * (U * (1 - U)) ** 1.5)
ub = math.asin(math.sqrt(U)) + upp * VU / 2
Vu = VU / (4 * U * (1 - U))
c = math.cos((g - shift) * ub)
if c == 0:
return -math.inf, c
return lB1 + math.log(abs(c)) - g * g * Vu / 2 - logA, c
def hand_best(r, J, logA, g, patience=40):
p = J % 2
best, since = (-math.inf, p), 0
while since < patience:
v = hand(r, J, logA, g, p)[0]
if v > best[0]:
best, since = (v, p), 0
else:
since += 1
p += 2
return best
def exact(r, J, lm, g):
v, p = exacttest.best_x(J, 0, (g,) + (2,) * (r - g))
return v - lm, p
def psi1(r, g):
"""exacttest.psi of the shape k=0 2^(r-g) g: 2^(r-g) T_g, built
without r - g list products (C3 reads it against psi)."""
return [v << (r - g) for v in exacttest._cheb(exacttest._T, g)]
def controls():
ok = True
want1 = {21: 2.6738, 23: 2.6630, 25: 2.6617, 27: 2.6673, 29: 2.6780,
31: 2.6925, 33: 2.7100}
for r, w in want1.items():
e, l, J, lm, logA = setup(r)
v, p = exact(r, J, lm, 5)
x = math.exp(v)
h = math.exp(hand(r, J, logA, 5, p)[0] - v)
pl = math.exp(hand(r, J, logA, 5, p, shift=2)[0] - v)
good = e == 3 and abs(x - w) < 5e-5 and not 0.9 <= pl <= 1.1
ok &= good
print("C1 r = %d e = %d: part 5 X/mean %.4f (want %.4f) p = %d,"
" H/exact %.4f, plant %.4f %s %s"
% (r, e, x, w, p, h, pl, "caught" if not 0.9 <= pl <= 1.1
else "MISSED", "holds" if good else "FAILS"), flush=True)
want2 = {39: 9.8599, 51: 14.0320}
for r, w in want2.items():
e, l, J, lm, logA = setup(r)
x = math.exp(exact(r, J, lm, 7)[0])
good = e == 4 and abs(x - w) < 5e-5
ok &= good
print("C2 r = %d e = %d: part 7 X/mean %.4f (want %.4f) %s"
% (r, e, x, w, "holds" if good else "FAILS"), flush=True)
return ok
def rank(r, full=False):
"""(e, (least exact X/mean, g, p, H/exact at it), shapes read at every
p, shapes below the mean, P1 misses, shapes). Every shape is read
exact at its hand-best p; best_x is read where that read is below the
running least or the mean (every shape when full)."""
e, l, J, lm, logA = setup(r)
rows = []
for g in range(5, r + 1, 2):
hp = hand_best(r, J, logA, g)[1]
lo = exacttest.log_x(J, 0, r - g, 1, psi1(r, g), hp) - lm
rows.append((lo, g, hp))
rows.sort()
least, below, p1, n = (math.inf, 0, 0, 0.0), [], [], 0
for lo, g, hp in rows:
hv, c = hand(r, J, logA, g, hp)
ratio = math.exp(hv - lo)
if g <= r / 2 and abs(c) >= 0.2 and not 0.95 <= ratio <= 1.05:
p1.append((g, round(ratio, 3)))
if not (full or lo < max(least[0], 0.0)):
continue
v, p = exact(r, J, lm, g)
n += 1
if v < 0:
below.append((g, p, round(math.exp(v), 4)))
if v < least[0]:
least = (v, g, p, math.exp(hand(r, J, logA, g, p)[0] - v))
return e, least, n, below, p1, len(rows)
def main():
t0 = time.time()
ok = controls()
bad = sum(psi1(53, g) != exacttest.psi((g,) + (2,) * (53 - g))
for g in range(5, 54, 2))
ok &= bad == 0
print("C3 r = 53: psi1 against exacttest.psi, %d of 25 shapes differ %s"
% (bad, "holds" if bad == 0 else "FAILS"), flush=True)
for r in (53, 54, 101, 102, 289):
a, b = rank(r), rank(r, full=True)
good = (a[1][1] == b[1][1] and abs(a[1][0] - b[1][0]) < 1e-12
and a[3] == b[3])
ok &= good
print("C3 r = %d: pipeline least %.4f at g = %d (%d of %d read at"
" by best_x), full %.4f at g = %d %s"
% (r, math.exp(a[1][0]), a[1][1], a[2], a[5],
math.exp(b[1][0]), b[1][1],
"holds" if good else "FAILS"), flush=True)
print("controls %s [%.1f s]" % ("hold" if ok else "FAIL",
time.time() - t0))
if not ok:
return False
print()
print(" r e least g p H/exact read of below / P1 misses")
kill, per_e, tot = [], {}, [0, 0]
rs = [r for r in range(21, 290, 2)] + [r for r in range(38, 577, 2)]
for r in rs:
e, (v, g, p, ratio), n, below, p1, m = rank(r)
tot[0] += n
tot[1] += m
x = math.exp(v)
if not 0.9 <= ratio <= 1.1:
kill.append(r)
cur = per_e.setdefault((e, r % 2), [math.inf, 0, 0, 0, 0])
if x < cur[0]:
cur[:3] = [x, r, g]
cur[3] += len(below)
cur[4] += len(p1)
print("%3d %2d %.4f %3d %4d %.4f %4d %3d %s %s"
% (r, e, x, g, p, ratio, n, m, below or "", p1 or ""),
flush=True)
print()
print(" e parity least at r g shapes below P1 misses")
for (e, par), (x, r, g, nb, np1) in sorted(per_e.items()):
print("%2d %s %.4f %4d %3d %d %d"
% (e, "odd " if par else "even", x, r, g, nb, np1))
print("%d shapes over %d ranks, each read exact at its hand-best p;"
" %d read by best_x" % (tot[1], len(rs), tot[0]))
print("KILL %s" % ("fires at r = %s" % kill if kill else "misses"))
print("%.1f s" % (time.time() - t0))
return ok
if __name__ == "__main__":
sys.exit(0 if main() else 1)