#!/usr/bin/env python3 """ test_344 -- FOUR STATEMENTS MADE EXPLICIT AFTER A SECOND INDEPENDENT READ OF MA: THE CHART'S ROTATION IN THE SWEPT-SPHERE CONSTRUCTION, THE SHELL VARIATION IN COORDINATE COMPONENTS, THE POINTWISE SILENCE OF THE POLYNOMIAL FORMS WHERE rank M <= 1, AND THE UNIVERSAL BOUNDS ON THE FLAG RESTRICTIONS For MA ยงยง4, 7 and 8 (the paper this script is deposited with). A second machine-assisted read of the draft asked for these to be stated explicitly. Two of its objections were checked and found to be in error (the curvature variation of Theorem E(2), and the basis of the components in the proof of Theorem F); P2 records the second. One of its formulas (the chart's rotation) had the wrong sign; P1 records the correct one. PRE-REGISTERED: P1 (Proposition 7.4(2), the chart's rotation) For the Moebius chart n = ((p - u1)/E, (q - u2)/E, 1 - u3/E), E = (|z - (u1 + i u2)|^2 + u3^2)/(2 u3), with u1, u2, u3 arbitrary functions of r, d_r n |_(p,q) = -W + (W.n) n + rho_c x n, W = (u1', u2', u3')/u3, rho_c = (-u2', u1', 0)/u3, symbolically. Hence the orthogonal-trajectory condition d_r n = -W + (W.n) n - rho x n of the proof holds iff rho = -rho_c = (u2', -u1', 0)/u3. Control: rho = +rho_c fails it. P2 (Theorem F, the components of M_1 = delta M) For g = A(r)^2 (1 + eps Y(theta))^2 dr^2 + Phi(r)^2 (dtheta^2 + sin^2 theta dphi^2), the O(eps) part of the endomorphism M^a_b = -g^{ac} G_cb has, in COORDINATE components, M_1^r_r = 2 Y Phi'^2/(A^2 Phi^2), M_1^r_theta = -Phi' Y_theta/(A^2 Phi), M_1^theta_r = -Phi' Y_theta/Phi^3, M_1^theta_theta = -cot(theta) Y_theta/Phi^2 - 2 Y P, M_1^phi_phi = -Y_thetatheta/Phi^2 - 2 Y P, P = (A' Phi' - A Phi'')/(A^3 Phi), every other component zero, and the lowered (M_1)_ab is symmetric, with (M_1)_{r theta} = -Phi' Y_theta/Phi. (These are the values printed in the paper.) P3 (Proposition 8.2(2), pointwise) At the origin of polynomial metrics with M(0) of rank 1 and of rank 0, and a random cubic part (so that adj M has nonzero first derivative there, and rank M >= 2 at nearby points), P(0) = 0, d(det M)(0) = 0, T(0) = 0 and R(0) = 0, exactly. Control: with M(0) of rank 2, T(0) and R(0) are nonzero. P4 (Theorem C(3), the flag bounds) For K = diag(1, 2, 3), diag(2, 3, -3), the identity, and diag(1, 1, -2), the map (omega, phi) -> d(.)omega + phi K, on 1-forms omega homogeneous of degree 4 and functions phi homogeneous of degree 3, restricted to polynomials in the last two coordinates, has rank 19 = 3*5 + 4; restricted to the last coordinate, rank 4 = 3*1 + 1. Exact. """ import sys import random import sympy as sp FAILURES = [] def check(name, ok, detail=""): print(f" [{'PASS' if ok else 'FAIL'}] {name}" + (f" -- {detail}" if detail else "")) if not ok: FAILURES.append(name) # ------------------------------------------------------------------------------------------------------------- P1 print("P1 the chart's rotation") r, p, q = sp.symbols("r p q", real=True) u1, u2, u3 = [sp.Function(f"u{i}")(r) for i in (1, 2, 3)] E = ((p - u1)**2 + (q - u2)**2 + u3**2) / (2 * u3) n = sp.Matrix([(p - u1) / E, (q - u2) / E, 1 - u3 / E]) W = sp.Matrix([u1.diff(r), u2.diff(r), u3.diff(r)]) / u3 rho_c = sp.Matrix([-u2.diff(r), u1.diff(r), 0]) / u3 dn = n.diff(r) unit = sp.simplify(n.dot(n) - 1) == 0 flow = all(sp.simplify(x) == 0 for x in dn - (-W + W.dot(n) * n + rho_c.cross(n))) rho = -rho_c trajectory = all(sp.simplify(x) == 0 for x in dn - (-W + W.dot(n) * n - rho.cross(n))) control = all(sp.simplify(x) == 0 for x in dn - (-W + W.dot(n) * n - rho_c.cross(n))) check("d_r n = -W + (W.n) n + rho_c x n; the trajectory condition holds with rho = (u2', -u1', 0)/u3, not with +rho_c", unit and flow and trajectory and not control) # ------------------------------------------------------------------------------------------------------------- P2 print("P2 the shell variation, coordinate components") th, ph, eps = sp.symbols("theta phi epsilon", real=True) A = sp.Function("A")(r) Phi = sp.Function("Phi")(r) Y = sp.Function("Y")(th) Xc = [r, th, ph] g = sp.diag(A**2 * (1 + eps * Y)**2, Phi**2, Phi**2 * sp.sin(th)**2) gi = g.inv() Gam = [[[sum(gi[a, d] * (sp.diff(g[d, b], Xc[c]) + sp.diff(g[d, c], Xc[b]) - sp.diff(g[b, c], Xc[d])) for d in range(3)) / 2 for c in range(3)] for b in range(3)] for a in range(3)] def ric(i, j): return sp.simplify(sum(sp.diff(Gam[a][i][j], Xc[a]) - sp.diff(Gam[a][i][a], Xc[j]) + sum(Gam[a][a][b] * Gam[b][i][j] - Gam[a][j][b] * Gam[b][i][a] for b in range(3)) for a in range(3))) Rc = sp.Matrix(3, 3, ric) Rs = sp.simplify(sum(gi[i, j] * Rc[i, j] for i in range(3) for j in range(3))) Mmix = -(gi * (Rc - Rs * g / 2)) M1 = Mmix.applyfunc(lambda e: sp.simplify(sp.diff(e, eps).subs(eps, 0))) Pc = (A.diff(r) * Phi.diff(r) - A * Phi.diff(r, 2)) / (A**3 * Phi) want = {(0, 0): 2 * Y * Phi.diff(r)**2 / (A**2 * Phi**2), (0, 1): -Phi.diff(r) * Y.diff(th) / (A**2 * Phi), (1, 0): -Phi.diff(r) * Y.diff(th) / Phi**3, (1, 1): -sp.cot(th) * Y.diff(th) / Phi**2 - 2 * Y * Pc, (2, 2): -Y.diff(th, 2) / Phi**2 - 2 * Y * Pc} ok_vals = all(sp.simplify(M1[k] - v) == 0 for k, v in want.items()) ok_zero = all(sp.simplify(M1[i, j]) == 0 for i in range(3) for j in range(3) if (i, j) not in want) low = (g.subs(eps, 0) * M1).applyfunc(sp.simplify) ok_sym = sp.simplify(low[0, 1] - low[1, 0]) == 0 and sp.simplify(low[0, 1] + Phi.diff(r) * Y.diff(th) / Phi) == 0 check("the five printed components are the coordinate components; the rest vanish; lowered M_1 is symmetric", ok_vals and ok_zero and ok_sym, f"(M_1)_r_theta = {low[0, 1]}") # ------------------------------------------------------------------------------------------------------------- P3 print("P3 T and R vanish at a point where rank M <= 1") X = sp.symbols("x0:3") random.seed(344) def trunc(e, deg): e = sp.expand(e) if e == 0: return sp.Integer(0) return sum((c * sp.prod([x**k for x, k in zip(X, m)]) for m, c in sp.Poly(e, *X).terms() if sum(m) <= deg), sp.Integer(0)) def metric_with_M(M0): """g = delta - (1/3) R_iajb x^a x^b + random cubic, so that M(0) = M0 (in 3D the Riemann tensor is fixed by M).""" Ric0 = -M0 + M0.trace() * sp.eye(3) Rs0 = 2 * M0.trace() d = lambda i, j: int(i == j) Rm = lambda a, b, c, e: (Ric0[a, c] * d(b, e) - Ric0[a, e] * d(b, c) + Ric0[b, e] * d(a, c) - Ric0[b, c] * d(a, e) - Rs0 / 2 * (d(a, c) * d(b, e) - d(a, e) * d(b, c))) gm = sp.zeros(3, 3) mons3 = [X[i] * X[j] * X[k] for i in range(3) for j in range(i, 3) for k in range(j, 3)] for i in range(3): for j in range(i, 3): quad = -sp.Rational(1, 3) * sum(Rm(i, a, j, b) * X[a] * X[b] for a in range(3) for b in range(3)) cub = sum(sp.Rational(random.randint(-5, 5), random.randint(2, 7)) * m for m in mons3) gm[i, j] = gm[j, i] = d(i, j) + quad + cub return gm def jets(gm): """M(0), d_a M(0) and Gamma(0) = 0 (g = delta + O(x^2)), by truncated power series.""" A_ = gm - sp.eye(3) gi_ = sp.eye(3) - A_ + A_ * A_ gi_ = gi_.applyfunc(lambda e: trunc(e, 2)) dg = [[[sp.diff(gm[b, c], X[a]) for c in range(3)] for b in range(3)] for a in range(3)] G_ = [[[trunc(sum(gi_[i, e] * (dg[c][e][b] + dg[b][e][c] - dg[e][b][c]) for e in range(3)) / 2, 2) for c in range(3)] for b in range(3)] for i in range(3)] Riem = lambda a, b, c, d: trunc(sp.diff(G_[a][d][b], X[c]) - sp.diff(G_[a][c][b], X[d]) + sum(G_[a][c][e] * G_[e][d][b] - G_[a][d][e] * G_[e][c][b] for e in range(3)), 1) Ric = sp.Matrix(3, 3, lambda b, d: sum(Riem(a, b, a, d) for a in range(3))) Rsc = trunc(sum(gi_[b, d] * Ric[b, d] for b in range(3) for d in range(3)), 1) Gt = (Ric - Rsc * gm / 2).applyfunc(lambda e: trunc(e, 1)) M = (-gi_ * Gt).applyfunc(lambda e: trunc(e, 1)) o = {x: 0 for x in X} return M.subs(o), [M.diff(X[a]).subs(o) for a in range(3)] def forms_at_origin(M0, dM): """T(0) and R(0); at the origin g = delta and Gamma = 0, so covariant derivatives are partial ones.""" P0 = M0.adjugate() dP = [] for a in range(3): t = sp.Symbol("t") dP.append((M0 + t * dM[a]).adjugate().diff(t).subs(t, 0)) ddet = [(P0 * dM[a]).trace() for a in range(3)] # Jacobi det0 = M0.det() T = {(a, b, c): sp.simplify(2 * det0 * (dP[a][b, c] - dP[b][a, c]) - (ddet[a] * P0[b, c] - ddet[b] * P0[a, c])) for a in range(3) for b in range(3) for c in range(3)} R = {(a, b, d): sp.simplify(sp.Rational(1, 2) * (ddet[a] * int(b == d) - ddet[b] * int(a == d)) - (dM[a] * P0)[d, b] + (dM[b] * P0)[d, a]) for a in range(3) for b in range(3) for d in range(3)} return T, R, P0, ddet, dP det3 = [] ok3 = True for name, M0 in [("rank 1", sp.diag(1, 0, 0)), ("rank 0", sp.zeros(3, 3))]: gm = metric_with_M(M0) Mo, dM = jets(gm) T, R, P0, ddet, dP = forms_at_origin(Mo, dM) nonflat = any(x != 0 for m in dP for x in m) if name == "rank 1" else any(x != 0 for m in dM for x in m) good = (Mo == M0 and P0 == sp.zeros(3, 3) and all(x == 0 for x in ddet) and all(v == 0 for v in T.values()) and all(v == 0 for v in R.values()) and nonflat) ok3 &= good det3.append(f"{name}: {'silent' if good else 'NOT silent'}") gm = metric_with_M(sp.diag(1, 2, 0)) Mo, dM = jets(gm) T, R, *_ = forms_at_origin(Mo, dM) ctrl = any(v != 0 for v in T.values()) and any(v != 0 for v in R.values()) det3.append(f"rank 2 control: {'nonzero' if ctrl else 'ZERO'}") check("P(0) = 0, d det M(0) = 0, T(0) = R(0) = 0 at rank 1 and rank 0 (rank >= 2 nearby); nonzero at rank 2", ok3 and ctrl, "; ".join(det3)) # ------------------------------------------------------------------------------------------------------------- P4 print("P4 the flag bounds from the linearised immersions") Z = sp.symbols("z0:3") def mons(vars_, deg): return [sp.prod(c) for c in sp.utilities.iterables.combinations_with_replacement(vars_, deg)] if deg > 0 else [1] def image_rank(K, free): """rank of (omega, phi) -> d(.)omega + phi K on omega of degree 4 and phi of degree 3 in the variables Z[free:].""" vs = Z[free:] cols = [] for m in mons(vs, 4): for c in range(3): om = [0, 0, 0] om[c] = m H = sp.Matrix(3, 3, lambda a, b: (sp.diff(om[b], Z[a]) + sp.diff(om[a], Z[b])) / 2) cols.append(H) for m in mons(vs, 3): cols.append(m * K) basis = mons(Z, 3) rows = [] for H in cols: v = [] for a in range(3): for b in range(a, 3): poly = sp.Poly(sp.expand(H[a, b]), *Z) v += [poly.coeff_monomial(bm) for bm in basis] rows.append(v) return sp.Matrix(rows).rank(), len(cols) det4 = [] ok4 = True for K in [sp.diag(1, 2, 3), sp.diag(2, 3, -3), sp.eye(3), sp.diag(1, 1, -2)]: r1, n1 = image_rank(K, 1) r2, n2 = image_rank(K, 2) ok4 &= (r1, n1, r2, n2) == (19, 19, 4, 4) det4.append(f"diag{tuple(K[i, i] for i in range(3))}: {r1}/{n1}, {r2}/{n2}") check("free of the first coordinate: rank 19 = 3*5 + 4; of the first two: rank 4 = 3 + 1 (injective), at four K", ok4, "; ".join(det4)) print() if FAILURES: print(f"test_344: {len(FAILURES)} FAILED") sys.exit(1) print("test_344: ALL PASS")