import numpy as np, math from itertools import product from experiment import lattice def calc(L,K,mode): e=lattice(L); d=[] for u,v in e:d += [(u,v),(v,u)] m=len(d); T=np.zeros((m,m),complex); pos=lambda x:np.array([x%L,x//L],float) for a,(u,v) in enumerate(d): for b,(v2,w) in enumerate(d): if v2!=v or w==u:continue if mode[0]=='rev': a1=pos(u)-pos(v) else:a1=pos(v)-pos(u) a2=pos(w)-pos(v) th=math.atan2(a1[0]*a2[1]-a1[1]*a2[0],a1.dot(a2)) if mode[1]=='half':th/=2 k=K[e.index(tuple(sorted((u,v))))] T[a,b]=np.tanh(k)*np.exp(1j*th) sg,ld=np.linalg.slogdet(np.eye(m)-T) return (2**(L*L))*np.prod(np.cosh(K))*np.sqrt(sg*np.exp(ld)) for mode in [('rev','full'),('rev','half'),('fwd','full'),('fwd','half')]: for L in [2,3]: e=lattice(L); K=np.array([.17+.04*(k%3-1) for k in range(len(e))]); ss=np.array(list(product([-1,1],repeat=L*L))) z=np.exp(np.sum([K[k]*ss[:,u]*ss[:,v] for k,(u,v) in enumerate(e)],0)).sum() print(mode,L,z,calc(L,K,mode),abs(z-calc(L,K,mode))/z)