from pathlib import Path
import re, math, cmath, random

HERE=Path(__file__).resolve().parent
PAPER=HERE/"CSM_RH_Paper_81_Nonlinear_Moment_Degree_Invariance_and_Connected_Fourth_Cumulant_Screening_v0.1_2026-09-09.md"

def check_moment_degree():
    random.seed(81)
    for _ in range(10000):
        q=2*random.randint(1,6)
        k=random.uniform(0.01,0.99)
        tau=random.uniform(0.001,0.99)
        scrit=q*k/2
        sgauss=q*(1-tau)/2
        assert (sgauss>scrit)==(1-tau>k)
        assert abs((2*scrit/q)-k)<1e-14
    return True

def check_single_mode_cumulant():
    # Z=2 a cos t for real a>0.
    for a in [0.2,1.0,3.7]:
        EZ2=2*a*a
        EZ4=6*a**4
        cum=EZ4-3*EZ2**2
        assert abs(cum+6*a**4)<1e-12
    return True

def connected_coefficient(lam, amps):
    # Direct combinatorial Fourier coefficient at (lam,lam,-lam)
    # for finite frequency dict amps: freq->a_freq.
    target=(lam,lam,-lam)
    l1,l2,l3=target
    l0=-(l1+l2+l3)
    raw=amps.get(l0,0)*amps.get(l1,0)*amps.get(l2,0)*amps.get(l3,0)
    # Pairing (0,1)(2,3)
    p1=0j
    if abs(l0+l1)<1e-12 and abs(l2+l3)<1e-12:
        p1=amps.get(l0,0)*amps.get(l1,0)*amps.get(l2,0)*amps.get(l3,0)
    p2=0j
    if abs(l0+l2)<1e-12 and abs(l1+l3)<1e-12:
        p2=amps.get(l0,0)*amps.get(l2,0)*amps.get(l1,0)*amps.get(l3,0)
    p3=0j
    if abs(l0+l3)<1e-12 and abs(l1+l2)<1e-12:
        p3=amps.get(l0,0)*amps.get(l3,0)*amps.get(l1,0)*amps.get(l2,0)
    return raw-p1-p2-p3

def check_self_atom():
    # Add unrelated frequencies and even an additive relation; self coefficient is unchanged.
    a=0.7+0.2j
    b=0.4-0.1j
    amps={
        1.0:a,-1.0:a.conjugate(),
        2.0:b,-2.0:b.conjugate(),
        3.0:0.2+0.3j,-3.0:0.2-0.3j
    }
    coeff=connected_coefficient(1.0,amps)
    target=-abs(a)**4
    assert abs(coeff-target)<1e-12,(coeff,target)
    return coeff,target

def check_rank_one_determinant():
    v=[1+2j,0.4-0.3j,2.2+0.1j]
    # any 2x2 principal minor of vv* vanishes.
    for i in range(len(v)):
        for j in range(i+1,len(v)):
            a=abs(v[i])**2
            d=abs(v[j])**2
            b=v[i]*v[j].conjugate()
            det=a*d-abs(b)**2
            assert abs(det)<1e-12
    return True

def check_R4_exponent():
    q=4
    exponent=q/2-1/(7*q)
    assert abs(exponent-(2-1/28))<1e-14
    return exponent

def check_source():
    s=PAPER.read_text(encoding="utf-8")
    for pat in [r"(?<!\\)\\\(",r"(?<!\\)\\\)",r"(?<!\\)\\\[",r"(?<!\\)\\\]"]:
        assert re.search(pat,s) is None
    assert s.count("$$")%2==0
    tmp=re.sub(r"\$\$.*?\$\$","",s,flags=re.S)
    assert len(re.findall(r"(?<!\\)\$",tmp))%2==0
    return True

if __name__=="__main__":
    print("moment_degree",check_moment_degree())
    print("single_mode_cumulant",check_single_mode_cumulant())
    print("self_atom",check_self_atom())
    print("rank_one_determinant",check_rank_one_determinant())
    print("R4_exponent",check_R4_exponent())
    print("source_delimiters",check_source())
    print("PASS")
