files / problems / hilbert16-limit-cycles / compute / q2 / o-iterated-squaring / verify.py
#!/usr/bin/env python3
"""Iterated complex-squaring pullback does not beat the quadratic ceiling.
Φ(u,v) = (u² − v², 2uv) is z ↦ z² on R² ≅ C. The Remark 4 pullback
of arXiv:2604.12883v1 is Y = adj(DΦ)(X ∘ Φ), i.e.
Yu = q_v P(Φ) − p_v Q(Φ),
Yv = −q_u P(Φ) + p_u Q(Φ),
so DΦ · Y = (det DΦ)(X ∘ Φ). One degree-m step has
deg Y ≤ n m + (m−1) and at most m² regular real sheets (Bézout).
This program certifies, for the radial cubic of §6 (ρ² = 1/4) and
for the linear centre (y, −x):
* the adj identity and det DΦ = 4(u²+v²);
* one-step degree exactly 7 (n=3, m=2) and two-step degree 15;
* regular real preimages of a generic point: 2, not 4;
* the k = 1..6 arithmetic: N = (n+1)2^k − 1, Bézout ceiling 4^k,
actual complex sheets 2^k = (N+1)/(n+1), Chebyshev one-step
of degree m = 2^k attains m² = 4^k at the same N.
The super-quadratic claim is dropped. Iteration of this map is
linear in N, not quadratic, and does not attain m² per step.
It does not beat Theorem 2. Do not cite 252/1080/1380/2012 here.
Replay: python3 verify.py
"""
from __future__ import annotations
import argparse
import json
import math
from fractions import Fraction
from pathlib import Path
from typing import Any
import sympy as sp
HERE = Path(__file__).resolve().parent
CERTS = HERE / "certs"
U, V, X, Ys = sp.symbols("u v x y")
def fail(msg: str) -> None:
raise SystemExit(f"verify.py FAIL: {msg}")
def total_deg(expr, gens) -> int:
expr = sp.expand(expr)
if expr == 0:
return -1
return int(sp.Poly(expr, gens).total_degree())
def monomials_qq(expr, gens=(U, V)) -> list[dict[str, int]]:
poly = sp.Poly(sp.expand(expr), *gens, domain=sp.QQ)
out = []
for exp, coeff in poly.as_dict().items():
frac = Fraction(int(coeff.p), int(coeff.q))
out.append(
{
"u": int(exp[0]),
"v": int(exp[1]),
"num": frac.numerator,
"den": frac.denominator,
}
)
out.sort(key=lambda m: (m["u"] + m["v"], m["u"], m["v"]))
return out
def dump_monomials(prefix: str, expr) -> list[str]:
return [
f"{prefix} {m['u']} {m['v']} {m['num']} {m['den']}" for m in monomials_qq(expr)
]
def phi_components():
return U**2 - V**2, 2 * U * V
def adj_pullback(p, q, P, Q):
"""Y = adj(DΦ)(X ∘ Φ). Returns Yu, Yv, det, Du, Dv."""
pu, pv = sp.diff(p, U), sp.diff(p, V)
qu, qv = sp.diff(q, U), sp.diff(q, V)
det = sp.expand(pu * qv - pv * qu)
Pc = sp.expand(P.subs({X: p, Ys: q}))
Qc = sp.expand(Q.subs({X: p, Ys: q}))
Yu = sp.expand(qv * Pc - pv * Qc)
Yv = sp.expand(-qu * Pc + pu * Qc)
Du = sp.expand(pu * Yu + pv * Yv - det * Pc)
Dv = sp.expand(qu * Yu + qv * Yv - det * Qc)
return Yu, Yv, det, Du, Dv
def radial_cubic(rho2=sp.Rational(1, 4)):
P = Ys - X * (X**2 + Ys**2 - rho2)
Q = -X - Ys * (X**2 + Ys**2 - rho2)
return P, Q
def linear_center():
return Ys, -X
def chebyshev_T2():
return 2 * U**2 - 1, 2 * V**2 - 1
def check_identity_and_degree() -> dict[str, Any]:
p, q = phi_components()
pu, pv = sp.diff(p, U), sp.diff(p, V)
qu, qv = sp.diff(q, U), sp.diff(q, V)
det = sp.expand(pu * qv - pv * qu)
expect_det = sp.expand(4 * (U**2 + V**2))
if det != expect_det:
fail(f"det DΦ = {det} != 4(u^2+v^2)")
if pu != qv or pv != -qu:
fail("Cauchy–Riemann failed: Φ is not holomorphic as written")
if pu != 2 * U or qv != 2 * U or pv != -2 * V or qu != 2 * V:
fail("DΦ entries")
P, Q = radial_cubic()
Yu, Yv, det_r, Du, Dv = adj_pullback(p, q, P, Q)
if Du != 0 or Dv != 0:
fail("radial adj identity failed")
deg_r = max(total_deg(Yu, (U, V)), total_deg(Yv, (U, V)))
bound_one = 3 * 2 + (2 - 1)
if deg_r != 7 or bound_one != 7:
fail(f"radial one-step deg {deg_r} bound {bound_one}")
P1, Q1 = linear_center()
Yu1, Yv1, _, Du1, Dv1 = adj_pullback(p, q, P1, Q1)
if Du1 != 0 or Dv1 != 0:
fail("linear adj identity failed")
deg_1 = max(total_deg(Yu1, (U, V)), total_deg(Yv1, (U, V)))
bound_lin = 1 * 2 + (2 - 1)
if deg_1 != 3 or bound_lin != 3:
fail(f"linear one-step deg {deg_1}")
if sp.expand(Yu1 - 2 * V * (U**2 + V**2)) != 0:
fail("linear Yu != 2v(u^2+v^2)")
if sp.expand(Yv1 + 2 * U * (U**2 + V**2)) != 0:
fail("linear Yv != -2u(u^2+v^2)")
# Two-step: pull the degree-7 field back by the same Φ.
Y2u, Y2v, _, D2u, D2v = adj_pullback(
p, q, Yu.subs({U: X, V: Ys}), Yv.subs({U: X, V: Ys})
)
if D2u != 0 or D2v != 0:
fail("two-step adj identity failed")
deg_2 = max(total_deg(Y2u, (U, V)), total_deg(Y2v, (U, V)))
bound_two = 7 * 2 + (2 - 1)
if deg_2 != 15 or bound_two != 15:
fail(f"two-step deg {deg_2} bound {bound_two}")
t2u, t2v = chebyshev_T2()
Ytu, Ytv, _, Dtu, Dtv = adj_pullback(t2u, t2v, P, Q)
if Dtu != 0 or Dtv != 0:
fail("T2 adj identity failed")
deg_t2 = max(total_deg(Ytu, (U, V)), total_deg(Ytv, (U, V)))
if deg_t2 != 7:
fail(f"T2 one-step deg {deg_t2} != 7")
return {
"paper": "arXiv:2604.12883v1 Remark 4 / Theorem 2 / §6",
"Phi": "u^2-v^2, 2uv",
"det": "4(u^2+v^2)",
"cauchy_riemann": True,
"identity": "DPhi · Y = (det DPhi) (X o Phi)",
"radial": {
"rho2": [1, 4],
"identity_ok": True,
"deg_Y": deg_r,
"bound": bound_one,
"exact": True,
"Yu": dump_monomials("Yu", Yu),
"Yv": dump_monomials("Yv", Yv),
"Yu_monomials": monomials_qq(Yu),
"Yv_monomials": monomials_qq(Yv),
},
"linear": {
"P": "y",
"Q": "-x",
"identity_ok": True,
"deg_Y": deg_1,
"bound": bound_lin,
"Yu_closed": "2v(u^2+v^2)",
"Yv_closed": "-2u(u^2+v^2)",
"Yu_monomials": monomials_qq(Yu1),
"Yv_monomials": monomials_qq(Yv1),
},
"two_step_radial": {
"deg_Y": deg_2,
"bound": bound_two,
"identity_ok": True,
"N_formula": "(n+1) 2^k - 1",
},
"chebyshev_T2_one_step": {
"deg_Y": deg_t2,
"bound": 7,
"identity_ok": True,
},
"Yu": Yu,
"Yv": Yv,
"Yu1": Yu1,
"Yv1": Yv1,
}
def real_regular_preimages(p, q, a, b, gens=(U, V)):
"""Exact algebraic real regular preimages of (a, b)."""
sols = sp.solve([sp.expand(p - a), sp.expand(q - b)], list(gens), dict=True)
det = sp.expand(sp.diff(p, gens[0]) * sp.diff(q, gens[1]) - sp.diff(p, gens[1]) * sp.diff(q, gens[0]))
regular = []
complex_all = 0
for s in sols:
uu, vv = sp.simplify(s[gens[0]]), sp.simplify(s[gens[1]])
complex_all += 1
if not (uu.is_real and vv.is_real):
continue
d = sp.simplify(det.subs({gens[0]: uu, gens[1]: vv}))
if d == 0:
continue
regular.append((uu, vv, d))
return regular, complex_all
def count_square_half_zero() -> int:
"""Φ(u,v)=(1/2,0): 2uv=0 and u²−v²=1/2. Two real regular points."""
# 2uv=0 ⇒ u=0 or v=0.
# u=0 ⇒ −v²=1/2, no real. v=0 ⇒ u²=1/2, two reals. det=4u²=2≠0.
# v = 0, u^2 = 1/2 > 0: two reals. u = 0: -v^2 = 1/2, none.
return 2
def count_square_quarter_quarter() -> int:
"""Φ(u,v)=(1/4,1/4): one positive t=u² from 64t²−16t−1=0, two reals."""
t = sp.symbols("t")
poly = sp.Poly(64 * t**2 - 16 * t - 1, t, domain=sp.QQ)
disc = 16**2 + 4 * 64 * 1
if disc != 512:
fail(f"discriminant {disc}")
roots = sp.solve(poly.as_expr(), t)
pos = [r for r in roots if r.is_real and r > 0]
neg = [r for r in roots if r.is_real and r < 0]
if len(pos) != 1 or len(neg) != 1:
fail(f"u^2 roots pos={pos} neg={neg}")
# product of roots = −1/64 < 0, so opposite signs: already checked.
# v = 1/(8u) for each real u = ±sqrt(t+). Two points, origin excluded.
return 2
def count_phi2_half_zero() -> int:
"""Φ²(u,v)=(1/2,0): 4uv(u²−v²)=0 and Re(z^4)=1/2. Four real regular."""
# q2 = 4uv(u²−v²)=0 ⇒ u=0 or v=0 or u²=v².
# u=0: v^4=1/2, two reals. v=0: u^4=1/2, two reals.
# u²=v² and uv≠0: −4u^4=1/2, no real.
return 4
def count_chebyshev_t2(a: Fraction, b: Fraction) -> int:
"""T2(t)=2t^2-1. Each of a,b in (-1,1) has two real preimages; 4 sheets."""
if abs(a) >= 1 or abs(b) >= 1:
fail("T2 target not in (-1,1)^2")
rhs_u = (a + 1) / 2
rhs_v = (b + 1) / 2
if not (0 < rhs_u < 1 and 0 < rhs_v < 1):
fail("T2 preimages not in (-1,1)")
# T2' = 4t vanishes only at 0; t^2 = (c+1)/2 != 0.
return 4
def polar_count(k: int, target=(0.5, 0.0)) -> int:
"""z ↦ z^{2^k} preimages of a nonzero point: the 2^k roots, all regular."""
a, b = target
w_mod = math.hypot(a, b)
if w_mod == 0:
fail("polar target is 0")
w_arg = math.atan2(b, a)
n = 1 << k
r = w_mod ** (1.0 / n)
pts = []
for j in range(n):
th = (w_arg + 2 * math.pi * j) / n
pts.append((r * math.cos(th), r * math.sin(th)))
# Iterate Φ, k times, and land on the target.
for u0, v0 in pts:
u, v = u0, v0
for _ in range(k):
u, v = u * u - v * v, 2 * u * v
if abs(u - a) + abs(v - b) > 1e-9:
fail(f"polar iterate k={k} missed target from {(u0, v0)}")
if u0 * u0 + v0 * v0 < 1e-18:
fail("polar preimage at origin")
# Distinct.
for i, (x1, y1) in enumerate(pts):
for x2, y2 in pts[i + 1 :]:
if abs(x1 - x2) + abs(y1 - y2) < 1e-9:
fail(f"polar k={k} collision")
return len(pts)
def check_preimages() -> dict[str, Any]:
p, q = phi_components()
n_half = count_square_half_zero()
n_qq = count_square_quarter_quarter()
n_phi2 = count_phi2_half_zero()
n_t2 = count_chebyshev_t2(Fraction(1, 2), Fraction(1, 2))
half_pts, half_c = real_regular_preimages(p, q, sp.Rational(1, 2), 0)
qq_pts, qq_c = real_regular_preimages(p, q, sp.Rational(1, 4), sp.Rational(1, 4))
if len(half_pts) != 2 or n_half != 2:
fail(f"(1/2,0) real regular {len(half_pts)}")
if len(qq_pts) != 2 or n_qq != 2:
fail(f"(1/4,1/4) real regular {len(qq_pts)}")
if half_c != 4 or qq_c != 4:
fail("complex Bézout count for degree 2 is not 4")
p0, q0 = p, q
p2 = sp.expand(p0.xreplace({U: p0, V: q0}))
q2 = sp.expand(q0.xreplace({U: p0, V: q0}))
expect_p2 = sp.expand(U**4 - 6 * U**2 * V**2 + V**4)
expect_q2 = sp.expand(4 * U**3 * V - 4 * U * V**3)
if p2 != expect_p2 or q2 != expect_q2:
fail(f"Phi^2 components {p2}, {q2}")
phi2_pts, phi2_c = real_regular_preimages(p2, q2, sp.Rational(1, 2), 0)
if len(phi2_pts) != 4 or n_phi2 != 4:
fail(f"Phi^2 (1/2,0) real regular {len(phi2_pts)}")
# Complexified (u,v) in C^2: Bézout allows 16. The holomorphic
# count z^4 = 1/2 in C ≅ R^2 is 4, and those 4 are the real ones.
if phi2_c > 16:
fail(f"Phi^2 complex count {phi2_c} above Bézout 16")
t2u, t2v = chebyshev_T2()
t2_pts, t2_c = real_regular_preimages(t2u, t2v, sp.Rational(1, 2), sp.Rational(1, 2))
if len(t2_pts) != 4 or n_t2 != 4:
fail(f"T2 (1/2,1/2) real regular {len(t2_pts)}")
polar = []
for k in range(1, 7):
c = polar_count(k)
if c != 1 << k:
fail(f"polar k={k} count {c}")
polar.append({"k": k, "count": c, "expected": 1 << k})
return {
"square_half_0": {
"target": [1, 2, 0, 1],
"real_regular": 2,
"complex_affine": 4,
"bezout_m2": 4,
"attains_m2": False,
"points": [
{"u": str(uu), "v": str(vv), "det": str(d)} for uu, vv, d in half_pts
],
},
"square_quarter_quarter": {
"target": [1, 4, 1, 4],
"real_regular": 2,
"complex_affine": 4,
"bezout_m2": 4,
"attains_m2": False,
"u2_quadratic": "64t^2 - 16t - 1",
"disc": 512,
},
"phi2_half_0": {
"target": [1, 2, 0, 1],
"real_regular": 4,
"complexified_uv_at_most": 16,
"holomorphic_in_C": 4,
"note": "z^4 = 1/2 has 4 points in R^2 ≅ C, not 16",
},
"chebyshev_T2_half_half": {
"target": [1, 2, 1, 2],
"real_regular": 4,
"attains_m2": True,
"note": "T2 x T2 is 4-to-1 on (-1,1)^2; components independent",
},
"polar_z_to_z_2k_of_half": polar,
"honesty": {
"real_plane_z_squared_is_2_to_1": True,
"separable_T2_is_4_to_1_on_minus1_1_square": True,
"CR_couples_the_components": True,
},
}
def reduced_ratio(num: int, den: int) -> tuple[int, int]:
g = math.gcd(num, den)
return num // g, den // g
def check_arithmetic(n: int = 3) -> dict[str, Any]:
rows = []
for k in range(1, 7):
N = (n + 1) * (1 << k) - 1
bezout = 1 << (2 * k) # 4^k
complex_sheets = 1 << k # 2^k
cheb_m = 1 << k
cheb_sheets = cheb_m * cheb_m
if N != (n + 1) * cheb_m - 1:
fail("N mismatch vs one-step Chebyshev of degree 2^k")
if complex_sheets * (n + 1) != N + 1:
fail("2^k != (N+1)/(n+1)")
if bezout != cheb_sheets:
fail("4^k != m^2")
b_n, b_d = reduced_ratio(bezout, N * N)
c_n, c_d = reduced_ratio(complex_sheets, N * N)
rows.append(
{
"k": k,
"N": N,
"sheet_ceiling_bezout": bezout,
"actual_complex": complex_sheets,
"chebyshev_m": cheb_m,
"chebyshev_sheets": cheb_sheets,
"bezout_over_N2": [b_n, b_d],
"complex_over_N2": [c_n, c_d],
"complex_eq_(N+1)/(n+1)": True,
}
)
return {
"n": n,
"N_formula": "(n+1) 2^k - 1",
"rows": rows,
"conclusion": {
"beats_theorem2": False,
"attains_m2_per_step": False,
"actual_complex_growth": "linear",
"complex_sheets_formula": "(N+1)/(n+1)",
"bezout_ceiling_growth": "quadratic",
"answers_remark4": "negative_for_complex_squaring",
"do_not_claim_252_1080_1380_2012": True,
},
}
def dump_lines(ident: dict[str, Any], pre: dict[str, Any], arith: dict[str, Any]) -> list[str]:
lines = [
"det 4(u^2+v^2)",
"cr p_u=q_v=2u p_v=-q_u=-2v",
"identity_radial 1",
"identity_linear 1",
f"deg_radial {ident['radial']['deg_Y']} bound {ident['radial']['bound']}",
f"deg_linear {ident['linear']['deg_Y']} bound {ident['linear']['bound']}",
f"deg_two_step_radial {ident['two_step_radial']['deg_Y']} bound {ident['two_step_radial']['bound']}",
f"deg_chebyshev_T2 {ident['chebyshev_T2_one_step']['deg_Y']} bound 7",
]
lines.extend(dump_monomials("Yu", ident["Yu"]))
lines.extend(dump_monomials("Yv", ident["Yv"]))
lines.extend(dump_monomials("Yu_linear", ident["Yu1"]))
lines.extend(dump_monomials("Yv_linear", ident["Yv1"]))
lines.append("preimages_square 1/2 0 2")
lines.append("preimages_square 1/4 1/4 2")
lines.append("preimages_square2 1/2 0 4")
lines.append("preimages_chebyshev_T2 1/2 1/2 4")
for row in pre["polar_z_to_z_2k_of_half"]:
lines.append(f"polar_count {row['k']} {row['count']}")
for row in arith["rows"]:
lines.append(
f"k {row['k']} N {row['N']} bezout {row['sheet_ceiling_bezout']} "
f"complex {row['actual_complex']} chebyshev {row['chebyshev_sheets']}"
)
bn, bd = row["bezout_over_N2"]
cn, cd = row["complex_over_N2"]
lines.append(f"ratio_bezout {row['k']} {bn}/{bd}")
lines.append(f"ratio_complex {row['k']} {cn}/{cd}")
lines.append("complex_sheets_eq_(N+1)/(n+1) 1")
lines.append("beats_theorem2 0")
lines.append("attains_m2_per_step 0")
lines.append("growth_complex linear")
lines.append("growth_bezout_ceiling quadratic")
lines.append("do_not_claim_252_1080_1380_2012 1")
return lines
def write_json(name: str, payload: dict[str, Any]) -> None:
CERTS.mkdir(parents=True, exist_ok=True)
path = CERTS / name
path.write_text(json.dumps(payload, indent=2) + "\n")
def main() -> None:
ap = argparse.ArgumentParser()
ap.add_argument("--dump", type=Path, default=None)
args = ap.parse_args()
ident = check_identity_and_degree()
pre = check_preimages()
arith = check_arithmetic(3)
ident_out = {k: v for k, v in ident.items() if k not in {"Yu", "Yv", "Yu1", "Yv1"}}
# monomials already stored as lists of dicts; drop the dump-string copies
ident_out["radial"] = {
k: v for k, v in ident["radial"].items() if k not in {"Yu", "Yv"}
}
write_json("identity.json", ident_out)
write_json(
"degree.json",
{
"one_step_formula": "deg Y <= n m + (m-1) = (n+1)m - 1",
"n": 3,
"m": 2,
"radial_deg": ident["radial"]["deg_Y"],
"radial_bound": 7,
"linear_deg": ident["linear"]["deg_Y"],
"linear_bound": 3,
"two_step_deg": ident["two_step_radial"]["deg_Y"],
"two_step_bound": 15,
"chebyshev_T2_deg": ident["chebyshev_T2_one_step"]["deg_Y"],
"k_step_bound": "(n+1) 2^k - 1",
},
)
write_json("preimages.json", pre)
write_json("arithmetic.json", arith)
core = {
"det": "4(u^2+v^2)",
"identity_radial": True,
"identity_linear": True,
"deg_radial": 7,
"deg_linear": 3,
"deg_two_step_radial": 15,
"preimages_half_0": 2,
"preimages_quarter_quarter": 2,
"preimages_phi2_half_0": 4,
"preimages_chebyshev_T2": 4,
"beats_theorem2": False,
"attains_m2_per_step": False,
"growth_complex": "linear",
"Yu_monomials": ident["radial"]["Yu_monomials"],
"Yv_monomials": ident["radial"]["Yv_monomials"],
"rows": [
{
"k": r["k"],
"N": r["N"],
"bezout": r["sheet_ceiling_bezout"],
"complex": r["actual_complex"],
"chebyshev": r["chebyshev_sheets"],
}
for r in arith["rows"]
],
}
write_json("core.json", core)
lines = dump_lines(ident, pre, arith)
text = "\n".join(lines) + "\n"
if args.dump:
args.dump.write_text(text)
print(text, end="")
print("verify.py: ok")
print(f" deg radial Y = {ident['radial']['deg_Y']}")
print(f" sheets Φ = 2, T2 = 4, Φ^2 = 4")
print(" beats Theorem 2 = 0")
if __name__ == "__main__":
main()