예제 #1
0
 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
예제 #2
0
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
예제 #3
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
예제 #4
0
def test_min():
    np.random.seed(5)
    nr = 4
    nc = 4
    pdim = 2
    bond = 2
    auxbond = 4  # None - PHP,PP,PHP/PP,eav= -6.0 1.0 -6.0 -0.375

    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

    # Initialization
    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
    pepsa = peps.create(pdim, configa)
    pepsb = peps.create(pdim, configb)

    # AUTOGRAD
    pepsc = peps.random(pepsa.shape, pdim, bond - 1, fac=1.e-2)
    peps0 = peps.add(pepsa, pepsc)
    peps0 = peps.add_noise(peps0, fac=1.e-1)
    vec = peps.flatten(peps0)

    import scipy.optimize
    import autograd

    def bound_energy_fn(vec):
        return energy_fn(vec, pdim, bond)

    deriv = autograd.grad(bound_energy_fn)
    print 'nparams=', len(vec)

    #print bound_energy_fn(vec)
    #print deriv(vec)

    def save_vec(vec):
        fname = 'peps_vec1'
        np.save(fname, vec)
        print ' --- save vec into fname=', fname
        return 0

    #vec = np.load('peps_vec.npy')
    #peps0 = peps.aspeps(vec, (nr,nc), pdim, bond)
    #peps0 = peps.add_noise(peps0,fac=5.e-1)
    #vec = peps.flatten(peps0)

    # Optimize
    result = scipy.optimize.minimize(bound_energy_fn, jac=deriv, x0=vec,\
             tol=1.e-4, callback=save_vec)
    P0 = peps.aspeps(result.x, (nr, nc), pdim, bond)
    print "final =", energy_fn(peps.flatten(P0), pdim, bond)
    return 0
예제 #5
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
예제 #6
0
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)