string_tension.py โ€” src/27-fields

The file src/27-fields/string_tension.py of the validation package of the paper 27-fld, rendered with an anchor per line; the file itself is beside this page.

27-fields ledgersrc/27-fields/string_tension.py ยท 10.2 KBstring_tension.py
1# framed-rational status: MIXED -- exact framed-rational core; continuum constructs are confined to clearly-labelled [approx] / degenerate-idealisation comparisons (Tier 2/3/5 or measured-data), never to an exact claim.2"""3D6b -- the colour string tension from the finite strong-coupling expansion.4================================================================================5Closes the one *open* (closeable, not Omega-hard) residue of the strong sector:6the string tension sigma = -ln c_1(beta) had been computed only for the abelian7gauge groups U(1) and Z_N (qcd.py).  Here we give the NON-ABELIAN tension.89The area law itself (sigma>0) is a corollary of the positivity of S_rho10(Prop. corrarea, correspondence.py block F).  What was "still to be done" is the11*value* of the single-plaquette coefficient c_1(beta) for the colour group, in12finite units.  We supply it in three exact pieces and one resolved-window piece:1314  T1  finite-group area law: for ANY finite gauge group, the rectangular Wilson15      loop tiles to c_1^Area with c_1 = <(1/N) chi_f>_w an EXACT finite sum16      (finite-group character orthogonality; no Haar measure, no Omega->infty).17  T2  SU(2,F_3)=2T (the corpus's exact non-abelian instance, 2T < SU(2,C)):18      c_1(beta) in closed form; leading sigma = ln(4/beta), reproducing the19      continuum SU(2) tension EXACTLY through order beta^3.20  T3  colour SU(3): resolved-window single-link expansion21      c_1 = beta/18 + beta^2/216 + ... = (beta/18)(1 + beta/12 + ...),22      positive and confining; the finite SU(3,F_q) reproduces it (Thm corr).23  S   structural float-free checks on SU(3,F_2): |G|=216, centre Z_3.2425Everything exact is done over Q / closed form; the continuum Haar integrals are26the resolved-window (Omega->large) reference the finite group converges to.2728Conventions match correspondence.py block F:29  action  S_rho(U) = 1 - (1/N) Re chi_f(U)  (positive class function),30  weight  w(U) = e^{-beta S_rho} ~ e^{beta (1/N) Re chi_f(U)}  (const cancels),31  coeff   c_1(beta) = < (1/N) chi_f >_w ,   sigma = -ln c_1 .32"""33import numpy as np34import math, itertools35from fractions import Fraction as Fr36import sympy as sp3738PASS = []39def check(name, ok):40    PASS.append(bool(ok))41    print(f"  [{'PASS' if ok else 'FAIL'}] {name}")4243# =====================================================================44print("="*72)45print("CHECK 0  normalisation matches the corpus (U(1): sigma(0.5)=1.4168)")46# =====================================================================47def Iv(v, beta, k=35):48    return sum((beta/2)**(2*j+v)/(math.factorial(j)*math.factorial(j+v))49               for j in range(k))50c1_U1 = lambda beta: Iv(1, beta)/Iv(0, beta)           # I1/I051check("U(1) c_1=I1/I0, sigma(0.5)=1.4168",52      abs(-math.log(c1_U1(0.5)) - 1.4168) < 1e-3)5354# =====================================================================55print("="*72)56print("CHECK T1  finite-group area law: orthogonality gives c_1 as an EXACT sum")57# =====================================================================58# The two identities the tiling uses, on a finite group G (uniform average59# (1/|G|) sum), verified on the symmetric group S_3 as a generic finite group:60#   (i)  <chi_r, chi_0> = (1/|G|) sum_g chi_r(g) = 0  for any nontrivial irrep r61#   (ii) (1/|G|) sum_g chi_r(a g) chi_s(g^{-1} b) = delta_{rs} chi_r(ab)/d_r62# (i) is exactly what makes the fundamental link integrate to zero (no tadpole),63# so the loop tiles its minimal surface; both are finite identities, no measure.64# Character table of S_3: classes e,(12),(123) sizes 1,3,2; irreps triv,sgn,std(2).65classes = [('e',1),('t',3),('c',2)]                    # name, size66chars = {'triv':{'e':1,'t':1,'c':1},67         'sgn' :{'e':1,'t':-1,'c':1},68         'std' :{'e':2,'t':0,'c':-1}}69order = 670for r in ('sgn','std'):71    s = sum(sz*chars[r][nm] for nm,sz in classes)72    check(f"S_3: sum_g chi_{r} = 0  (fundamental has no singlet -> tiling closes)",73          s == 0)74# orthonormality (ii) at a=b=e: (1/|G|) sum |chi_r|^2 = 175for r in chars:76    s = sum(sz*chars[r][nm]**2 for nm,sz in classes)77    check(f"S_3: <chi_{r},chi_{r}> = 1", Fr(s,order) == 1)7879# =====================================================================80print("="*72)81print("CHECK T2  SU(2,F_3) = 2T < SU(2,C): exact closed-form string tension")82# =====================================================================83def quat_to_su2(q):84    a,b,c,d = q85    return np.array([[a+1j*b, c+1j*d], [-c+1j*d, a-1j*b]])86G2T = []87for s in ([1,0,0,0],[0,1,0,0],[0,0,1,0],[0,0,0,1]):88    for sg in (1,-1):89        G2T.append([sg*x for x in s])90for signs in itertools.product([0.5,-0.5], repeat=4):91    G2T.append(list(signs))92mats = [quat_to_su2(q) for q in G2T]93check("|2T| = 24 unit quaternions", len(mats) == 24)94check("2T < SU(2,C): all det=1, unitary",95      all(abs(np.linalg.det(M)-1) < 1e-9 and96          np.allclose(M.conj().T @ M, np.eye(2)) for M in mats))97from collections import Counter98trace_mult = Counter(int(round(np.trace(M).real)) for M in mats)99check("trace multiset {2:1,-2:1,0:6,1:8,-1:8}",100      dict(trace_mult) == {2:1,-2:1,0:6,1:8,-1:8})101# sum of the (nontrivial) fundamental character vanishes -> T1 hypothesis holds102check("sum_{g in 2T} chi_f(g) = 0 (orthogonality with trivial)",103      abs(sum(np.trace(M) for M in mats)) < 1e-9)104105# exact closed form via the trace multiset, c_1 = <(1/2)chi>_w106b = sp.symbols('beta', positive=True)107mult = {2:1, -2:1, 0:6, 1:8, -1:8}108Zsum = sum(m*sp.exp(b*sp.Rational(t,2)) for t,m in mult.items())109Nsum = sum(m*sp.Rational(t,2)*sp.exp(b*sp.Rational(t,2)) for t,m in mult.items())110c1_2T = sp.nsimplify(sp.simplify(Nsum/Zsum))111print("    c_1^{2T}(beta) =", sp.simplify(c1_2T))112ser = sp.series(c1_2T, b, 0, 6).removeO()113print("    series         =", ser)114# leading term beta/4115lead = sp.limit(c1_2T/b, b, 0)116check("leading c_1^{2T} = beta/4  (=> sigma = ln(4/beta))", lead == sp.Rational(1,4))117# continuum SU(2) single-link c_1 = I2/I1; compare series118c1_SU2_series = sp.series(119    (sum((b/2)**(2*j+2)/(sp.factorial(j)*sp.factorial(j+2)) for j in range(6))) /120    (sum((b/2)**(2*j+1)/(sp.factorial(j)*sp.factorial(j+1)) for j in range(6))),121    b, 0, 6).removeO()122# agreement through beta^3: difference starts at beta^5123diff = sp.simplify(ser - c1_SU2_series)124low = sp.series(diff, b, 0, 5).removeO()125check("2T reproduces continuum SU(2) tension through O(beta^3) (diff starts beta^5)",126      sp.simplify(low) == 0)127f2T = sp.lambdify(b, c1_2T, 'math')128def c1_SU2(beta): return Iv(2,beta)/Iv(1,beta)129print("    beta   c_1^2T      c_1^SU2(Haar)   sigma^2T    reldiff")130for beta in (0.2,0.5,1.0,2.0):131    a, c = f2T(beta), c1_SU2(beta)132    print(f"    {beta:4.1f}  {a:.6f}   {c:.6f}     {-math.log(a):7.4f}   {abs(a-c)/c:.2e}")133check("sigma^{2T}(beta) > 0 for all tested beta (confining)",134      all(-math.log(f2T(x)) > 0 for x in (0.2,0.5,1.0,2.0,4.0)))135136# =====================================================================137print("="*72)138print("CHECK T3  colour SU(3): resolved-window single-link expansion")139# =====================================================================140def c1_SU3(beta, n=600):141    p = np.linspace(0, 2*math.pi, n, endpoint=False)142    P1, P2 = np.meshgrid(p, p); P3 = -(P1+P2)143    z1, z2, z3 = np.exp(1j*P1), np.exp(1j*P2), np.exp(1j*P3)144    vdm = np.abs((z1-z2)*(z1-z3)*(z2-z3))**2            # SU(3) Weyl measure145    chi = z1+z2+z3146    w = np.exp(beta*chi.real/3.0)                        # w = e^{beta (1/3) Re chi}147    return float(np.sum((chi.real/3.0)*w*vdm)/np.sum(w*vdm))148bs = np.array([0.02,0.04,0.06,0.08,0.10,0.12])149vals = np.array([c1_SU3(x) for x in bs])150coef,*_ = np.linalg.lstsq(np.vstack([bs,bs**2,bs**3]).T, vals, rcond=None)151print(f"    fit: c_1^SU(3) = {coef[0]:.6f} b + {coef[1]:.6f} b^2 + ...")152check("SU(3) leading c_1 = beta/18 = 1/(2N^2)", abs(coef[0]-1/18) < 1e-4)153check("SU(3) next coeff = beta^2/216  (= (beta/18)(1+beta/12))", abs(coef[1]-1/216) < 1e-4)154print("    beta   c_1^SU(3)   sigma=-ln c_1")155for beta in (0.2,0.5,1.0,2.0,4.0):156    c = c1_SU3(beta); print(f"    {beta:4.1f}  {c:.6f}    {-math.log(c):7.4f}")157check("sigma^{SU(3)}(beta) > 0 for all tested beta (confining), ->0 as beta->inf",158      all(-math.log(c1_SU3(x)) > 0 for x in (0.2,0.5,1.0,2.0,4.0,8.0)))159160# =====================================================================161print("="*72)162print("CHECK S  structural float-free checks on SU(3,F_2) over F_4")163# =====================================================================164ADD = np.array([[0,1,2,3],[1,0,3,2],[2,3,0,1],[3,2,1,0]])165MUL = np.array([[0,0,0,0],[0,1,2,3],[0,2,3,1],[0,3,1,2]])166CONJ = np.array([0,1,3,2])                               # Frobenius x->x^2167def herm(u,v):168    s = 0169    for i in range(3): s = ADD[s, MUL[CONJ[u[i]], v[i]]]170    return s171def det3(c0,c1,c2):172    M = [[c0[0],c1[0],c2[0]],[c0[1],c1[1],c2[1]],[c0[2],c1[2],c2[2]]]173    a,b_,c = M[0]; d,e,f = M[1]; g,h,i = M[2]174    pos = ADD[ADD[MUL[a,MUL[e,i]],MUL[b_,MUL[f,g]]],MUL[c,MUL[d,h]]]175    neg = ADD[ADD[MUL[c,MUL[e,g]],MUL[a,MUL[f,h]]],MUL[b_,MUL[d,i]]]176    return ADD[pos,neg]                                  # char 2: +/- identical177vecs = list(itertools.product(range(4), repeat=3))178norm1 = [v for v in vecs if herm(v,v) == 1]179cnt = 0; centre = set()180for c0 in norm1:181    for c1 in norm1:182        if herm(c0,c1) != 0: continue183        for c2 in norm1:184            if herm(c0,c2) != 0 or herm(c1,c2) != 0: continue185            if det3(c0,c1,c2) != 1: continue186            cnt += 1187            if (c0[1]==0 and c0[2]==0 and c1[0]==0 and c1[2]==0188                and c2[0]==0 and c2[1]==0 and c0[0]==c1[1]==c2[2]):189                centre.add(c0[0])190check("|SU(3,2)| = 216 = q^3(q^2-1)(q^3+1) at q=2",191      cnt == 216 == 2**3*(2**2-1)*(2**3+1))192check("centre = Z_3 (norm-one cube roots of unity; 3 | q+1)",193      len(centre) == 3 and (2+1) % 3 == 0)194195# =====================================================================196print("="*72)197print(f"RESULT: {sum(PASS)}/{len(PASS)} checks pass")198print("D6b: the string tension sigma(beta) is computed in finite units --")199print("exact for U(1),Z_N (qcd.py) and 2T (closed form here), resolved-window")200print("series for SU(3).  The remaining strong-sector residue is the PHYSICAL")201print("value of beta (= the cross-scale running fixing Lambda_QCD = sqrt(sigma)),")202print("which is D6c, Omega-hard.  Clean cut: the function sigma(beta) is T; the")203print("point beta_phys on it is Omega.")204assert all(PASS), "some checks failed"205