import numpy as np, itertools, sys sys.path.insert(0,'/home/claude/jw/jw') import matrices as M def magic(H): N=H.shape[0] return np.array([[np.outer(H[i]*H[j].conj(), (H[i]*H[j].conj()).conj())/N for j in range(N)] for i in range(N)]) def find_outer(W, M_out): """partitions of rows into M_out blocks of equal size such that sum_a W[(i,a),(j,b)] is independent of b""" N=W.shape[0]; n=N//M_out; out=[] for blocks in set_partitions(list(range(N)), n): ok=True for I in blocks: for J in blocks: S=[sum(W[a,b] for a in I) for b in J] if max(np.abs(S[k]-S[0]).max() for k in range(len(S)))>1e-9: ok=False; break if not ok: break if ok: out.append(blocks) return out def set_partitions(lst, n): if not lst: yield []; return f=lst[0] for rest in itertools.combinations(lst[1:], n-1): blk=[f]+list(rest); rem=[x for x in lst if x not in blk] for p in set_partitions(rem, n): yield [blk]+p def Tk(U, k): """T_k[(i),(j)] = tr(U_{i1j1}...U_{ikjk}) / dim, for a magic matrix U[i][j] of d x d projections""" n=U.shape[0]; d=U.shape[2]; idx=list(itertools.product(range(n),repeat=k)) T=np.zeros((len(idx),len(idx)),complex) for x,I in enumerate(idx): for y,J in enumerate(idx): P=np.eye(d) for s in range(k): P=P@U[I[s],J[s]] T[x,y]=np.trace(P)/d return T def ck_model(U,k,tol=1e-7): ev=np.linalg.eigvals(Tk(U,k)); return int(np.sum(np.abs(ev-1)