Beispiel #1
0
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
Beispiel #2
0
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
Beispiel #3
0
          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:
Beispiel #4
0
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
Beispiel #5
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