def get_Sm(): Sm = PArray([[1], [0, 1], [0, 1]], [[1], [1, 1], [1, 1]]) Sm[0, 1, 0] = np.array(1).reshape(1, 1, 1) return Sm
def get_Sp(): Sp = PArray([[1], [0, 1], [0, 1]], [[1], [1, 1], [1, 1]]) # To match with PEPS qnums! Sp[0, 0, 1] = np.array(1).reshape(1, 1, 1) return Sp
idx += 1 return x def fromBits2Conf(bt,nr,nc): conf = np.zeros([nr,nc], dtype=np.int) idx = 0 for i in range(nr): for j in range(nc): if bits.testBit(bt,idx): conf[i,j] = 1 idx += 1 return conf # # Heisenberg Hamiltonian # SzMat = np.array([[0.5,0.],[0.,-0.5]]) SpMat = np.array([[0. ,1.],[0.,0. ]]) SmMat = np.array([[0. ,0.],[1.,0. ]]) def genHeisenbergHmn(m,n,mtx): diff = m^n # xor: 0,1->1; 1,0->1 ndiff = bits.bitCount(diff) Hmn = 0. if ndiff == 0: for i in range(mtx.shape[0]): for j in mtx.rows[i]: # (a,b) or (b,a) if bits.testBit(m,i)^bits.testBit(m,j): Hmn -= 0.25 # (a,a) or (b,b) else:
def get_Sz(): Sz = PArray([[0, 1], [0, 1]], [[1, 1], [1, 1]]) Sz[0, 0] = np.array(0.5).reshape(1, 1) Sz[1, 1] = np.array(-0.5).reshape(1, 1) return Sz
def test_mc(vec, nr, nc, pdim, bond): P = peps.aspeps(vec, (nr, nc), pdim, bond) # Initialization auxbond = 20 configa = np.zeros([nr, nc], dtype=np.int) configb = np.zeros([nr, nc], dtype=np.int) for i in range(nr): for j in range(nc): configa[i, j] = (i + j) % 2 configb[i, j] = (i + j + 1) % 2 assert np.sum(configa) % 2 == 0 assert np.sum(configb) % 2 == 0 def genWs(by): cy = mc_helper.fromBits2Conf(by, nr, nc) py = peps.create(pdim, cy) wy = peps.dot(py, P, auxbond) return wy mtx = mc_helper.genHeisenbergHlst(nr, nc) x = mc_helper.fromConf2Bits(configa) wsx = genWs(x) nsample = 10000 maxiter = 30 sample = [x] * nsample ws = np.array([wsx] * nsample) iop = 1 for niter in range(maxiter): print '\nniter=', niter for i in range(nsample): bx = sample[i] wx = ws[i] by = mc_helper.genHeisenbergMove(bx, nr, nc) wy = genWs(by) if niter == 0: # accept all print 'i=', i, bin(by) sample[i] = by ws[i] = wy else: prob = min([1, (wy / wx)**2]) rand = np.random.rand() if prob > rand: sample[i] = by ws[i] = wy else: sample[i] = bx ws[i] = wx print 'i=', i, prob, rand, 'accept=', prob > rand # Compute energy z = np.sum(ws**2) eloc = np.zeros(nsample) # E = 1/Z*sum_S |<P|S>|^2*Eloc if iop == 0: # Eloc = <P|H|S>/<P|S> (Variational?) for i in range(nsample): by = sample[i] cy = mc_helper.fromBits2Conf(by, nr, nc) py = peps.create(pdim, cy) PHP = peps_h.eval_heish(P, py, auxbond) eloc[i] = PHP / ws[i] print 'i=', i, eloc[i] else: # Eloc = sum_S' <P|S'><S'|H|S>/<P|S> # We need a way to generate S' from <S'|H|S> for i in range(nsample): sample2 = mc_helper.genHeisenbergConnected(sample[i], nr, nc) hs = map( lambda s1: mc_helper.genHeisenbergHmn(s1, sample[i], mtx), sample2) wsp = map(lambda s1: genWs(s1), sample2) eloc[i] = np.dot(wsp, hs) / ws[i] print 'i=', i, eloc[i] # # THIS IS WRONG !!! SIMPLE AVERAGE IS OK. # esum = np.dot(eloc, ws**2) / z print 'etot=', esum, ' e_per_site=', esum / (nr * nc) return 0