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)
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
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)
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
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
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")
"""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)
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)
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
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
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....