def energy_fn(vec, pdim, bond): P = peps.aspeps(vec, (nr, nc), pdim, bond) PHP = peps_h.eval_heish(P, P, auxbond) PP = peps.dot(P, P, auxbond) e = PHP / PP print ' PHP,PP,PHP/PP,eav=', PHP, PP, e, e / (nr * nc) return PHP / PP
def test(): pdim = 2 bond = 2 numpy.random.seed(5) nr = 4 nc = 4 configs = spins.configs(nr * nc, pdim) zpeps = peps.random([nr, nc], pdim, bond) print zpeps for i in range(nr): for j in range(nc): print np.linalg.norm(zpeps[i, j]) #auxbond = 2 # for config in configs: # print config # cpeps = peps.cpeps(zpeps,config) # print "norms", np.linalg.norm(cpeps[0,0]), np.linalg.norm(cpeps[0,1]), np.linalg.norm(cpeps[1,0]), np.linalg.norm(cpeps[1,1]) # print peps.ceval(zpeps,config,auxbond) php = peps_h.eval_heish(zpeps, None) pp = peps.dot(zpeps, zpeps, None) print pp print numpy.random.random([1]) print "Expectation value", php, pp, php / pp
def test_basic(vec, nr, nc, pdim, bond): P = peps.aspeps(vec, (nr, nc), pdim, bond) # Initialization auxbond = 16 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 x = mc_helper.fromConf2Bits(configa) print configa print x, bin(x) conf = mc_helper.fromBits2Conf(x, nr, nc) print conf print configb = configa.copy() configb[1, 1] = 1 configb[1, 2] = 0 y = mc_helper.fromConf2Bits(configb) print configb print y, bin(y) Pa = peps.create(pdim, configa) Pb = peps.create(pdim, configb) print '<Pa|P>=', peps.dot(Pa, P, auxbond) print '<Pb|P>=', peps.dot(Pb, P, auxbond) print print ' configa=\n', configa print ' configb=\n', configb #peps_h.eval_hbond(Pa, Pb, 1, 1, auxbond) Hab = peps_h.eval_heish(Pa, Pb, auxbond) print ' Hab=', Hab assert abs(Hab - 0.5) < 1.e-10 Haa = peps_h.eval_heish(Pa, Pa, auxbond) print ' Haa=', Haa assert abs(Haa + 6.0) < 1.e-10 Hbb = peps_h.eval_heish(Pb, Pb, auxbond) print ' Hbb=', Hbb assert abs(Hbb + 3.0) < 1.e-10 return 0
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
def energy_fn(vec, pdim, bond): P = peps.aspeps(vec, (nr, nc), pdim, bond) PHP = peps_h.eval_heish(P, auxbond) PP = peps.dot(P, P, auxbond) print PHP, PP, PHP / PP return PHP / PP
def test_min(): numpy.random.seed(5) nr = 6 nc = 4 auxbond = 8 def energy_fn(vec, pdim, bond): P = peps.aspeps(vec, (nr, nc), pdim, bond) PHP = peps_h.eval_heish(P, auxbond) PP = peps.dot(P, P, auxbond) print PHP, PP, PHP / PP return PHP / PP afma = np.zeros([nr * nc]) 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 #print afma #print afmb pdim = 2 pepsa = peps.create((nr, nc), pdim, configa) pepsb = peps.create((nr, nc), pdim, configb) print peps.dot(pepsa, pepsa, None) print peps.dot(pepsb, pepsb, None) print peps.dot(pepsa, pepsb, None) PHP = peps_h.eval_heish(pepsa, None) #print "config", configa[0,0], configa[0,1] print "PHP energy", PHP print "PP", peps.dot(pepsa, pepsa, None) # flata = peps.flatten(pepsa) # pepsA = peps.aspeps(flata, (nr,nc), pdim, bond=1) # print "reconstituted dot", peps.dot(pepsA,pepsa,None) # print pepsa # print pepsA print "A energy", energy_fn(peps.flatten(pepsa), pdim, bond=1) print "B energy", energy_fn(peps.flatten(pepsb), pdim, bond=1) print "---start opt-----" pdim = 2 bond = 2 peps0 = peps.add(pepsa, pepsb) # this has bond=2 pepsc = peps.zeros(pepsa.shape, pdim, bond - 2) # add some zeros to make up full bond peps0 = peps.add(peps0, pepsc) peps0 = add_noise(peps0, 0.1) print energy_fn(peps.flatten(peps0), pdim, bond) #vec = 0.3*np.random.random(nparam) vec = peps.flatten(peps0) #0.3*np.random.random(nparam) def bound_energy_fn(vec): return energy_fn(vec, pdim, bond) deriv = autograd.grad(bound_energy_fn) d = deriv(vec) print bound_energy_fn(vec) result = scipy.optimize.minimize(bound_energy_fn, jac=deriv, x0=vec) print "max value", np.max(result.x) P0 = peps.aspeps(result.x, (nr, nc), pdim, bond)