Beispiel #1
0
def test_time_methods(algorithm):
    L = 6
    g = 1.2

    model_params = dict(L=L, J=1., g=g, bc_MPS='finite', conserve=None)
    M = TFIChain(model_params)
    product_state = ["up"] * L  #prepare system in spin polarized state
    psi = MPS.from_product_state(M.lat.mps_sites(),
                                 product_state,
                                 bc=M.lat.bc_MPS)

    dt = 0.01
    N_steps = 2
    t = 0.5  #total time evolution
    params = {
        'order': 2,
        'dt': dt,
        'N_steps': N_steps,
        'trunc_params': {
            'chi_max': 50,
            'svd_min': 1.e-10,
            'trunc_cut': None
        }
    }
    if algorithm == 'TEBD':
        eng = tebd.TEBDEngine(psi, M, params)
    elif algorithm == 'TDVP':
        params['active_sites'] = 2
        del params['order']
        eng = tdvp.TDVPEngine(psi, M, params)
    elif algorithm == 'ExpMPO':
        params['compression_method'] = 'SVD'
        del params['order']
        eng = mpo_evolution.ExpMPOEvolution(psi, M, params)
    else:
        raise ValueError("test works only for TEDB and TDVP so far")

    mag = [psi.expectation_value("Sigmaz")]
    szsz = [psi.correlation_function("Sigmaz", "Sigmaz")]
    corr = psi.correlation_function("Sp", "Sm")
    spsm = [corr.diagonal(1) + corr.diagonal(-1)]

    for ti in np.arange(0, t, dt * N_steps):
        eng.run()
        mag.append(psi.expectation_value("Sigmaz"))
        szsz.append(psi.correlation_function("Sigmaz", "Sigmaz"))
        corr = psi.correlation_function("Sp", "Sm")
        spsm.append(corr.diagonal(1) + corr.diagonal(-1))

    m_exact, szsz_exact, spsm_exact = exact_expectation(L, g, t, dt * N_steps)
    npt.assert_almost_equal(np.array(mag)[:-1, :], m_exact, 4)
    npt.assert_almost_equal(np.array(szsz)[:-1, :, :], szsz_exact, 4)
    npt.assert_almost_equal(np.array(spsm)[:-1, :], spsm_exact, 4)
Beispiel #2
0
def setup_benchmark(mod_q=[1], legs=10, size=20, **kwargs):
    """Setup TEBD benchmark.

    Mapping of parameters:
        size -> chi
        legs -> L = number of sites
        mod_q -> conserve
    """
    L = legs  # number of sites: legs is abbreviated with `l`
    if len(mod_q) == 0:
        conserve = None
    elif mod_q == [2]:
        conserve = 'parity'
    elif mod_q == [1]:
        conserve = 'Sz'
    model_params = dict(L=L,
                        S=2.,
                        D=0.3,
                        bc_MPS='infinite',
                        conserve=conserve,
                        verbose=0)
    #  print("conserve =", repr(conserve))
    M = SpinChain(model_params)
    initial_state = (['up', 'down'] * L)[:L]
    psi = MPS.from_product_state(M.lat.mps_sites(),
                                 initial_state,
                                 bc='infinite')
    local_dim = psi.sites[0].dim
    tebd_params = {
        'trunc_params': {
            'chi_max': size,
            'svd_min': 1.e-45,
        },
        'order': 2,
        'N_steps': 5,
        'dt': 0.1,
        'verbose': 0.,
    }
    eng = tebd.TEBDEngine(psi, M, tebd_params)
    eng.verbose = 0.02
    optimization.set_level(3)
    for i in range(5 + int(np.log(size) / np.log(local_dim))):
        eng.run()
        if eng.verbose > 0.1:
            print(eng.psi.chi)
            print(eng.psi.entanglement_entropy())
    assert min(eng.psi.chi) == size  # ensure full bond dimension
    if eng.verbose > 0.1:
        print("set up tebd for size", size)
    return eng
Beispiel #3
0
def example_TEBD_tf_ising_lightcone(L, g, tmax, dt):
    print("finite TEBD, real time evolution")
    print("L={L:d}, g={g:.2f}, tmax={tmax:.2f}, dt={dt:.3f}".format(L=L,
                                                                    g=g,
                                                                    tmax=tmax,
                                                                    dt=dt))
    # find ground state with TEBD or DMRG
    #  E, psi, M = example_TEBD_gs_tf_ising_finite(L, g)
    from d_dmrg import example_DMRG_tf_ising_finite
    print("(run DMRG to get the groundstate)")
    E, psi, M = example_DMRG_tf_ising_finite(L, g)
    print("(DMRG finished)")
    i0 = L // 2
    # apply sigmaz on site i0
    psi.apply_local_op(i0, 'Sigmaz', unitary=True)
    dt_measure = 0.05
    # tebd.TEBDEngine makes 'N_steps' steps of `dt` at once;
    # for second order this is more efficient.
    tebd_params = {
        'order': 2,
        'dt': dt,
        'N_steps': int(dt_measure / dt + 0.5),
        'trunc_params': {
            'chi_max': 50,
            'svd_min': 1.e-10,
            'trunc_cut': None
        },
    }
    eng = tebd.TEBDEngine(psi, M, tebd_params)
    S = [psi.entanglement_entropy()]
    for n in range(int(tmax / dt_measure + 0.5)):
        eng.run()
        S.append(psi.entanglement_entropy())
    import matplotlib.pyplot as plt
    plt.figure()
    plt.imshow(S[::-1],
               vmin=0.,
               aspect='auto',
               interpolation='nearest',
               extent=(0, L - 1., -0.5 * dt_measure,
                       eng.evolved_time + 0.5 * dt_measure))
    plt.xlabel('site $i$')
    plt.ylabel('time $t/J$')
    plt.ylim(0., tmax)
    plt.colorbar().set_label('entropy $S$')
    filename = 'c_tebd_lightcone_{g:.2f}.pdf'.format(g=g)
    plt.savefig(filename)
    print("saved " + filename)
Beispiel #4
0
def example_TEBD_gs_tf_ising_finite(L, g):
    print("finite TEBD, imaginary time evolution, transverse field Ising")
    print("L={L:d}, g={g:.2f}".format(L=L, g=g))
    model_params = dict(L=L, J=1., g=g, bc_MPS='finite', conserve=None)
    M = TFIChain(model_params)
    product_state = ["up"] * M.lat.N_sites
    psi = MPS.from_product_state(M.lat.mps_sites(),
                                 product_state,
                                 bc=M.lat.bc_MPS)
    tebd_params = {
        'order': 2,
        'delta_tau_list': [0.1, 0.01, 0.001, 1.e-4, 1.e-5],
        'N_steps': 10,
        'max_error_E': 1.e-6,
        'trunc_params': {
            'chi_max': 30,
            'svd_min': 1.e-10
        },
    }
    eng = tebd.TEBDEngine(psi, M, tebd_params)
    eng.run_GS()  # the main work...

    # expectation values
    E = np.sum(M.bond_energies(
        psi))  # M.bond_energies() works only a for NearestNeighborModel
    # alternative: directly measure E2 = np.sum(psi.expectation_value(M.H_bond[1:]))
    print("E = {E:.13f}".format(E=E))
    print("final bond dimensions: ", psi.chi)
    mag_x = np.sum(psi.expectation_value("Sigmax"))
    mag_z = np.sum(psi.expectation_value("Sigmaz"))
    print("magnetization in X = {mag_x:.5f}".format(mag_x=mag_x))
    print("magnetization in Z = {mag_z:.5f}".format(mag_z=mag_z))
    if L < 20:  # compare to exact result
        from tfi_exact import finite_gs_energy
        E_exact = finite_gs_energy(L, 1., g)
        print("Exact diagonalization: E = {E:.13f}".format(E=E_exact))
        print("relative error: ", abs((E - E_exact) / E_exact))
    return E, psi, M
Beispiel #5
0
def example_TEBD_gs_tf_ising_infinite(g):
    print("infinite TEBD, imaginary time evolution, transverse field Ising")
    print("g={g:.2f}".format(g=g))
    model_params = dict(L=2, J=1., g=g, bc_MPS='infinite', conserve=None)
    M = TFIChain(model_params)
    product_state = ["up"] * M.lat.N_sites
    psi = MPS.from_product_state(M.lat.mps_sites(),
                                 product_state,
                                 bc=M.lat.bc_MPS)
    tebd_params = {
        'order': 2,
        'delta_tau_list': [0.1, 0.01, 0.001, 1.e-4, 1.e-5],
        'N_steps': 10,
        'max_error_E': 1.e-8,
        'trunc_params': {
            'chi_max': 30,
            'svd_min': 1.e-10
        },
    }
    eng = tebd.TEBDEngine(psi, M, tebd_params)
    eng.run_GS()  # the main work...
    E = np.mean(M.bond_energies(
        psi))  # M.bond_energies() works only a for NearestNeighborModel
    # alternative: directly measure E2 = np.mean(psi.expectation_value(M.H_bond))
    print("E (per site) = {E:.13f}".format(E=E))
    print("final bond dimensions: ", psi.chi)
    mag_x = np.mean(psi.expectation_value("Sigmax"))
    mag_z = np.mean(psi.expectation_value("Sigmaz"))
    print("<sigma_x> = {mag_x:.5f}".format(mag_x=mag_x))
    print("<sigma_z> = {mag_z:.5f}".format(mag_z=mag_z))
    print("correlation length:", psi.correlation_length())
    # compare to exact result
    from tfi_exact import infinite_gs_energy
    E_exact = infinite_gs_energy(1., g)
    print("Analytic result: E (per site) = {E:.13f}".format(E=E_exact))
    print("relative error: ", abs((E - E_exact) / E_exact))
    return E, psi, M
Beispiel #6
0
def test_tdvp():
    L = 10
    J = 1
    chi = 20
    delta_t = 0.01
    parameters = {
        'L': L,
        'S': 0.5,
        'conserve': 'Sz',
        'Jz': 1.0,
        'Jy': 1.0,
        'Jx': 1.0,
        'hx': 0.0,
        'hy': 0.0,
        'hz': 0.0,
        'muJ': 0.0,
        'bc_MPS': 'finite',
    }

    heisenberg = tenpy.models.spins.SpinChain(parameters)
    H_MPO = heisenberg.H_MPO
    h_test = []
    for i_sites in range(H_MPO.L):
        h_test.append(
            H_MPO.get_W(i_sites).transpose(['wL', 'wR', 'p*',
                                            'p']).to_ndarray())

    def random_prod_state_tenpy(L, a_model):
        product_state = []
        #the numpy mps used to compare
        psi_compare = []
        sz = 2. * np.random.randint(0, 2, size=L) - 1.0
        for i in range(L):
            psi_compare.append(np.zeros((2, 1, 1)))
            if sz[i] > 0:
                product_state += ["up"]
                psi_compare[-1][0, 0, 0] = 1
            else:
                product_state += ["down"]
                psi_compare[-1][1, 0, 0] = 1

        psi = MPS.from_product_state(a_model.lat.mps_sites(),
                                     product_state,
                                     bc=a_model.lat.bc_MPS,
                                     form='B')
        psi_converted = []
        for i in range(L):
            site = psi.sites[i]
            perm = site.perm
            B_tmp = psi.get_B(i).transpose(['p', 'vL', 'vR']).to_ndarray()
            B = B_tmp[inverse_permutation(perm), :, :]
            B = B[::-1, :, :]
            psi_converted.append(B)

        return psi

    psi = random_prod_state_tenpy(heisenberg.lat.N_sites, heisenberg)
    N_steps = 50
    tebd_params = {
        'order': 2,
        'dt': delta_t,
        'N_steps': N_steps,
        'trunc_params': {
            'chi_max': 50,
            'svd_min': 1.e-10,
            'trunc_cut': None
        }
    }

    tdvp_params = {
        'start_time': 0,
        'dt': delta_t,
        'N_steps': N_steps,
        'trunc_params': {
            'chi_max': 50,
            'svd_min': 1.e-10,
            'trunc_cut': None
        }
    }

    psi_tdvp2 = copy.deepcopy(psi)
    engine = tebd.TEBDEngine(psi, heisenberg, tebd_params)
    tdvp_engine = tdvp.TDVPEngine(psi_tdvp2, heisenberg, tdvp_params)
    engine.run()
    tdvp_engine.run_two_sites(N_steps)
    ov = psi.overlap(psi_tdvp2)
    print("overlap TDVP and TEBD")
    psi = engine.psi
    print("difference")
    print(np.abs(1 - np.abs(ov)))
    assert np.abs(1 - np.abs(ov)) < 1e-10
    print("two sites tdvp works")

    # test that the initial conditions are the same

    tdvp_engine = tdvp.TDVPEngine(psi, heisenberg, tdvp_params)
    psit_compare = []
    for i in range(L):
        B_tmp = psi.get_B(i).transpose(['p', 'vL', 'vR']).to_ndarray()
        B = B_tmp[::-1, :, :]
        psit_compare.append(B)
    #**********************************************************************************************************
    #Initialize TDVP
    tdvp_params = {
        'start_time': 0,
        'dt': delta_t,
        'N_steps': 1,
    }
    tdvp_engine = tdvp.TDVPEngine(psi, heisenberg, tdvp_params)
    for t in range(10):
        tdvp_engine.run_one_site(N_steps=1)
        psit_compare, Rp_list, spectrum = tdvp_numpy.tdvp(psit_compare,
                                                          h_test,
                                                          0.5 * 1j * delta_t,
                                                          Rp_list=None)
        psit_ = []
    for i in range(L):
        B = psi.get_B(i).transpose(['p', 'vL', 'vR']).to_ndarray()
        B = B[::-1, :, :]
        psit_.append(B)
    assert np.abs(np.abs(overlap(psit_, psit_compare)) - 1.0) < 1e-13
    print("one site TDVP works")
Beispiel #7
0
"""Call of (infinite) TEBD."""

from tenpy.networks.mps import MPS
from tenpy.models.tf_ising import TFIChain
from tenpy.algorithms import tebd

M = TFIChain({"L": 2, "J": 1., "g": 1.5, "bc_MPS": "infinite"})
psi = MPS.from_product_state(M.lat.mps_sites(), [0] * 2, "infinite")
tebd_params = {
    "order": 2,
    "delta_tau_list": [0.1, 0.001, 1.e-5],
    "max_error_E": 1.e-6,
    "trunc_params": {
        "chi_max": 30,
        "svd_min": 1.e-10
    }
}
eng = tebd.TEBDEngine(psi, M, tebd_params)
eng.run_GS()  # imaginary time evolution with TEBD
print("E =", sum(psi.expectation_value(M.H_bond)) / psi.L)
print("final bond dimensions: ", psi.chi)
Beispiel #8
0
def test_ExpMPOEvolution(bc_MPS, approximation, compression, g=1.5):
    # Test a time evolution against exact diagonalization for finite bc
    dt = 0.01
    if bc_MPS == 'finite':
        L = 6
    else:
        L = 2
    #  model_pars = dict(L=L, Jx=0., Jy=0., Jz=-4., hx=2. * g, bc_MPS=bc_MPS, conserve=None)
    #  state = ([[1 / np.sqrt(2), -1 / np.sqrt(2)]] * L)  # pointing in (-x)-direction
    #  state = ['up'] * L  # pointing in (-z)-direction
    model_pars = dict(L=L,
                      Jx=1.,
                      Jy=1.,
                      Jz=1.,
                      hz=0.2,
                      bc_MPS=bc_MPS,
                      conserve='best')
    state = ['up', 'down'] * (L // 2)  # Neel
    M = SpinChain(model_pars)
    psi = MPS.from_product_state(M.lat.mps_sites(), state, bc=bc_MPS)

    options = {
        'dt': dt,
        'N_steps': 1,
        'order': 1,
        'approximation': approximation,
        'compression_method': compression,
        'trunc_params': {
            'chi_max': 30,
            'svd_min': 1.e-8
        }
    }
    eng = mpo_evolution.ExpMPOEvolution(psi, M, options)

    if bc_MPS == 'finite':
        ED = exact_diag.ExactDiag(M)
        ED.build_full_H_from_mpo()
        ED.full_diagonalization()
        psiED = ED.mps_to_full(psi)
        psiED /= psiED.norm()

        UED = ED.exp_H(dt)
        for i in range(30):
            psi = eng.run()
            psiED = npc.tensordot(UED, psiED, ('ps*', [0]))
            psi_full = ED.mps_to_full(psi)
            assert (abs(abs(npc.inner(psiED, psi_full, [0, 0], True)) - 1) <
                    dt)

    if bc_MPS == 'infinite':
        psiTEBD = psi.copy()
        TEBD_params = {
            'dt': dt,
            'order': 2,
            'N_steps': 1,
            'trunc_params': options['trunc_params']
        }
        EngTEBD = tebd.TEBDEngine(psiTEBD, M, TEBD_params)
        for i in range(30):
            EngTEBD.run()
            psi = eng.run()
            #  print(psi.norm)
            print(abs(abs(psi.overlap(psiTEBD)) - 1),
                  abs(psi.overlap(psiTEBD) - 1))
            assert (abs(abs(psi.overlap(psiTEBD)) - 1) < 1e-4)
Beispiel #9
0
 def solve(self, model_params, psi):
     M = TFIChain(model_params)
     eng = tebd.TEBDEngine(psi, M, self.options)
     eng.run_GS()
     return np.mean(M.bond_energies(psi)), psi
Beispiel #10
0
def example_TEBD_gs_tf_ising_next_nearest_neighbor(L, g, Jp):
    from tenpy.models.spins_nnn import SpinChainNNN2
    from tenpy.models.model import NearestNeighborModel
    print(
        "finite TEBD, imaginary time evolution, transverse field Ising next-nearest neighbor"
    )
    print("L={L:d}, g={g:.2f}, Jp={Jp:.2f}".format(L=L, g=g, Jp=Jp))
    model_params = dict(
        L=L,
        Jx=1.,
        Jy=0.,
        Jz=0.,
        Jxp=Jp,
        Jyp=0.,
        Jzp=0.,
        hz=g,
        bc_MPS='finite',
        conserve=None,
    )
    # we start with the non-grouped sites, but next-nearest neighbor interactions, building the MPO
    M = SpinChainNNN2(model_params)
    product_state = ["up"] * M.lat.N_sites
    psi = MPS.from_product_state(M.lat.mps_sites(),
                                 product_state,
                                 bc=M.lat.bc_MPS)

    # now we group each to sites ...
    psi.group_sites(n=2)  # ... in the state
    M.group_sites(n=2)  # ... and model
    # now, M has only 'nearest-neighbor' interactions with respect to the grouped sites
    # thus, we can convert the MPO into H_bond terms:
    M_nn = NearestNeighborModel.from_MPOModel(
        M)  # hence, we can initialize H_bond from the MPO

    # now, we continue to run TEBD as before
    tebd_params = {
        'order': 2,
        'delta_tau_list': [0.1, 0.01, 0.001, 1.e-4, 1.e-5],
        'N_steps': 10,
        'max_error_E': 1.e-6,
        'trunc_params': {
            'chi_max': 30,
            'svd_min': 1.e-10
        },
    }
    eng = tebd.TEBDEngine(psi, M_nn, tebd_params)  # use M_nn and grouped psi
    eng.run_GS()  # the main work...

    # expectation values:
    E = np.sum(M_nn.bond_energies(
        psi))  # bond_energies() works only a for NearestNeighborModel
    print("E = {E:.13f}".format(E=E))
    print("final bond dimensions: ", psi.chi)
    # we can split the sites of the state again for an easier evaluation of expectation values
    psi.group_split()
    mag_x = 2. * np.sum(
        psi.expectation_value("Sx"))  # factor of 2 for Sx vs Sigmax
    mag_z = 2. * np.sum(psi.expectation_value("Sz"))
    print("magnetization in X = {mag_x:.5f}".format(mag_x=mag_x))
    print("magnetization in Z = {mag_z:.5f}".format(mag_z=mag_z))
    return E, psi, M
Beispiel #11
0
def test_tebd(bc_MPS, g=0.5):
    L = 2 if bc_MPS == 'infinite' else 6
    #  xxz_pars = dict(L=L, Jxx=1., Jz=3., hz=0., bc_MPS=bc_MPS)
    #  M = XXZChain(xxz_pars)
    # factor of 4 (2) for J (h) to change spin-1/2 to Pauli matrices
    model_pars = dict(L=L,
                      Jx=0.,
                      Jy=0.,
                      Jz=-4.,
                      hx=2. * g,
                      bc_MPS=bc_MPS,
                      conserve=None)
    M = SpinChain(model_pars)
    state = ([[1, -1.], [1, -1.]] * L)[:L]  # pointing in (-x)-direction
    psi = MPS.from_product_state(M.lat.mps_sites(), state, bc=bc_MPS)

    tebd_param = {
        'dt': 0.01,
        'order': 2,
        'delta_tau_list': [0.1, 1.e-4, 1.e-8],
        'max_error_E': 1.e-9,
        'trunc_params': {
            'chi_max': 50,
            'trunc_cut': 1.e-13
        }
    }
    engine = tebd.TEBDEngine(psi, M, tebd_param)
    engine.run_GS()

    print("norm_test", psi.norm_test())
    if bc_MPS == 'finite':
        psi.canonical_form()
        ED = ExactDiag(M)
        ED.build_full_H_from_mpo()
        ED.full_diagonalization()
        E_ED, psi_ED = ED.groundstate()
        Etebd = np.sum(M.bond_energies(psi))
        print("E_TEBD={Etebd:.14f} vs E_exact={Eex:.14f}".format(Etebd=Etebd,
                                                                 Eex=E_ED))
        assert (abs((Etebd - E_ED) / E_ED) < 1.e-7)
        ov = npc.inner(psi_ED, ED.mps_to_full(psi), 'range', do_conj=True)
        print("compare with ED: overlap = ", abs(ov)**2)
        assert (abs(abs(ov) - 1.) < 1.e-7)

        # Test real time TEBD: should change on an eigenstate
        Sold = np.average(psi.entanglement_entropy())
        for i in range(3):
            engine.run()
        Enew = np.sum(M.bond_energies(psi))
        Snew = np.average(psi.entanglement_entropy())
        assert (abs(Enew - Etebd) < 1.e-8)
        assert (abs(Sold - Snew) < 1.e-5
                )  # somehow we need larger tolerance here....

    if bc_MPS == 'infinite':
        Etebd = np.average(M.bond_energies(psi))
        Eexact = e0_tranverse_ising(g)
        print("E_TEBD={Etebd:.14f} vs E_exact={Eex:.14f}".format(Etebd=Etebd,
                                                                 Eex=Eexact))

        Sold = np.average(psi.entanglement_entropy())
        for i in range(2):
            engine.run()
        Enew = np.average(M.bond_energies(psi))
        Snew = np.average(psi.entanglement_entropy())
        assert (abs(Etebd - Enew) < 1.e-7)
        assert (abs(Sold - Snew) < 1.e-5
                )  # somehow we need larger tolerance here....