import sys, time, collections from system import ERRDIMS, ERRORDER, err_offsets from solve import echelon, nullspace_mod, check_vec from gauge import gauge_errors, plus_eigen_basis def analyze(S, p, t, blocks_order=("E3","E25","E2","b","a"), verbose=False): """Column order: nu, then error blocks in blocks_order. Report projection dims onto successive tails.""" idx = {} for r in S.rows: for c in r: if c[0]=="nu" and c not in idx: idx[c]=len(idx) N=len(idx) off={} o=N for n in blocks_order: off[n]=o for i in range(ERRDIMS[n]): idx[("err",n,i)]=o+i o+=ERRDIMS[n] tot=o rows=[{idx[c]: int(v)%p for c,v in r.items() if int(v)%p} for r in S.rows] piv=echelon(rows,p,verbose=verbose) res={} for j,n in enumerate(blocks_order): tail=blocks_order[j:] start=off[n] ntail=tot-start npiv=sum(1 for c in piv if c>=start) res[tail]=ntail-npiv # gauge vectors projected G=[] for w in plus_eigen_basis(t): g=gauge_errors(S.rels,w,t) eo,_=err_offsets() vec=[0]*(tot-N) for n in ERRORDER: for i in range(ERRDIMS[n]): vec[off[n]-N+i]=int(g[eo[n]+i])%p G.append(vec) cons={c-N:{cc-N:v for cc,v in r.items()} for c,r in piv.items() if c>=N} bad=[check_vec(cons,g,p) for g in G] # gauge rank on each tail gr={} for j,n in enumerate(blocks_order): start=off[n]-N sub=[{i-start:g[i] for i in range(start,len(g)) if g[i]} for g in G] pv=echelon(sub,p) gr[blocks_order[j:]]=len(pv) return res, gr, bad, piv, N, off