def test_dmrg_rerun(L=2): bc_MPS = 'infinite' model_params = dict(L=L, J=1., g=1.5, bc_MPS=bc_MPS, conserve=None, verbose=0) M = TFIChain(model_params) psi = mps.MPS.from_product_state(M.lat.mps_sites(), [0] * L, bc=bc_MPS) dmrg_pars = { 'verbose': 5, 'chi_list': { 0: 5, 5: 10 }, 'N_sweeps_check': 4, 'combine': True } eng = dmrg.TwoSiteDMRGEngine(psi, M, dmrg_pars) E1, _ = eng.run() assert abs(E1 - -1.67192622) < 1.e-6 model_params['g'] = 1.3 M = TFIChain(model_params) del eng.options['chi_list'] new_chi = 15 eng.options['trunc_params']['chi_max'] = new_chi eng.init_env(M) E2, psi = eng.run() assert max(psi.chi) == new_chi assert abs(E2 - -1.50082324) < 1.e-6
def test_enlarge_mps_unit_cell(): g = 1.3 # deep in the paramagnetic phase bc_MPS = 'infinite' model_params = dict(L=2, J=1., g=g, bc_MPS=bc_MPS, conserve=None, verbose=0) M_2 = TFIChain(model_params) M_4 = TFIChain(model_params) M_4.enlarge_mps_unit_cell(2) psi_2 = mps.MPS.from_product_state(M_2.lat.mps_sites(), ['up', 'up'], bc=bc_MPS) psi_4 = mps.MPS.from_product_state(M_2.lat.mps_sites(), ['up', 'up'], bc=bc_MPS) psi_4.enlarge_mps_unit_cell(2) dmrg_params = { 'verbose': 1, 'combine': True, 'max_sweeps': 30, 'update_env': 0, 'mixer': False, # not needed in this case 'trunc_params': { 'svd_min': 1.e-10, 'chi_max': 50 } } E_2, _ = dmrg.TwoSiteDMRGEngine(psi_2, M_2, dmrg_params).run() E_4, _ = dmrg.TwoSiteDMRGEngine(psi_4, M_4, dmrg_params).run() assert abs(E_2 - E_4) < 1.e-12 psi_2.enlarge_mps_unit_cell(2) ov = abs(psi_2.overlap(psi_4)) print("ov = ", ov) assert abs(ov - 1.) < 1.e-12
def evolve(self): for t, g, J in zip(self._ts, self._gs, self._Js): self.t = t self.g = g self.J = J model_params = dict(L=2, J=J, g=g, bc_MPS='infinite', conserve=None) M = TFIChain(model_params) self.M = M self.psi = self.Evolver.evolve(self.psi, M) self.Es.append(np.mean(M.bond_energies(self.psi))) self.Ss.append(self.psi.entanglement_entropy()[-1]) self.Es_exact.append(exact_energy(J, g)) self.ts.append(t) self.gs.append(g) self.Js.append(J) self.chis.append(np.mean(self.psi.chi)) self.Sxs.append(np.mean(self.psi.expectation_value('Sx'))) self.Sys.append(np.mean(self.psi.expectation_value('Sy'))) self.Szs.append(np.mean(self.psi.expectation_value('Sz'))) print('v:', self.v, 'g:', round(g, 5), 'J:', round(J, 5), 'chi:', self.chi, 'Sx:', round(self.Sxs[-1], 6), 'Sy:', round(self.Sys[-1], 6), 'Sz:', round(self.Szs[-1], 6)) self.write_log() self.save_checkpoint() self.write_log() self.save_checkpoint() print('done') print('*' * 80)
def example_TEBD_gs_tf_ising_infinite(g, verbose=True): 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, verbose=verbose) 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 }, 'verbose': verbose, } eng = tebd.Engine(psi, M, tebd_params) eng.run_GS() # the main work... E = np.sum(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_dmrg_rerun(L=2): bc_MPS='infinite' model_params = dict(L=L, J=1., g=1.5, bc_MPS=bc_MPS, conserve=None, verbose=0) M = TFIChain(model_params) psi = mps.MPS.from_product_state(M.lat.mps_sites(), [0]*L, bc=bc_MPS) dmrg_pars = {'verbose': 5, 'chi_list': {0: 10, 5: 20}, 'N_sweeps_check': 4} eng = dmrg.EngineCombine(psi, M, dmrg_pars) E1, _ = eng.run() assert abs(E1 - -1.67192622) < 1.e-6 model_params['g'] = 1.3 M = TFIChain(model_params) eng.init_env(M) E2, _ = eng.run() assert abs(E2 - -1.50082324) < 1.e-6
def run_tebd_tfi(L, mindim, g, tf, dt, verbose=False, order=2): model_params = dict(L=L, J=1., g=g, bc_MPS='finite', conserve=None, verbose=verbose) 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': order, 'dt': dt, 'N_steps': int(tf / dt), 'trunc_params': { 'trunc_cut': 1e-14, 'svd_min': 1e-24, 'chi_max': mindim # 'chi_min': mindim }, 'verbose': verbose, } eng = tebd.Engine(psi, M, tebd_params) eng.run() print(np.amax(psi.chi)) return psi
def imag_apply_mpo(L=30, beta_max=3., dt=0.05, order=2, bc="finite", approx="II"): model_params = dict(L=L, J=1., g=1.2) M = TFIChain(model_params) psi = PurificationMPS.from_infiniteT(M.lat.mps_sites(), bc=bc) options = {'trunc_params': {'chi_max': 100, 'svd_min': 1.e-8}} beta = 0. if order == 1: Us = [M.H_MPO.make_U(-dt, approx)] elif order == 2: Us = [ M.H_MPO.make_U(-d * dt, approx) for d in [0.5 + 0.5j, 0.5 - 0.5j] ] eng = PurificationApplyMPO(psi, Us[0], options) Szs = [psi.expectation_value("Sz")] betas = [0.] while beta < beta_max: beta += 2. * dt # factor of 2: |psi> ~= exp^{- dt H}, but rho = |psi><psi| betas.append(beta) for U in Us: eng.init_env(U) # reset environment, initialize new copy of psi eng.run() # apply U to psi Szs.append(psi.expectation_value("Sz")) # and further measurements... return {'beta': betas, 'Sz': Szs}
def example_DMRG_finite(L, g): print("finite DMRG, 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, verbose=0) M = TFIChain(model_params) psi = MPS.from_product_state(M.lat.mps_sites(), [0] * L, bc='finite') dmrg_params = { 'mixer': None, 'trunc_params': { 'chi_max': 30, 'svd_min': 1.e-10 }, 'max_E_err': 1.e-10, 'verbose': 1 } dmrg.run(psi, M, dmrg_params) E = np.sum(psi.expectation_value(M.H_bond[1:])) print("E = {E:.13f}".format(E=E)) print("final bond dimensions: ", psi.chi) if L < 20: # compare to exact result E_exact = tfi_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 calc_infinite_groundstates(dmrg_params, g=0.1): L = 2 model_params = dict(L=L, J=1., g=g, bc_MPS='infinite', conserve=None, verbose=0) model = TFIChain(model_params) plus_x = np.array([1., 1.]) / np.sqrt(2) minus_x = np.array([1., -1.]) / np.sqrt(2) psi_plus = MPS.from_product_state(model.lat.mps_sites(), [plus_x] * L, model.lat.bc_MPS) psi_minus = MPS.from_product_state(model.lat.mps_sites(), [minus_x] * L, model.lat.bc_MPS) engine_plus = dmrg.TwoSiteDMRGEngine(psi_plus, model, dmrg_params) engine_plus.run() print("<Sx> =", psi_plus.expectation_value("Sigmax")) engine_minus = dmrg.TwoSiteDMRGEngine(psi_minus, model, dmrg_params) engine_minus.run() print("<Sx> =", psi_minus.expectation_value("Sigmax")) data_plus = {'psi': psi_plus} data_plus.update(**engine_plus.env.get_initialization_data()) data_minus = {'psi': psi_minus} data_minus.update(**engine_minus.env.get_initialization_data()) return model, data_plus, data_minus
def example_1site_DMRG_tf_ising_infinite(g): print("single-site infinite DMRG, transverse field Ising model") 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) dmrg_params = { 'mixer': True, # setting this to True is essential for the 1-site algorithm to work. 'trunc_params': { 'chi_max': 30, 'svd_min': 1.e-10 }, 'max_E_err': 1.e-10, 'combine': True } eng = dmrg.SingleSiteDMRGEngine(psi, M, dmrg_params) E, psi = eng.run() # equivalent to dmrg.run() up to the return parameters. print("E = {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))
def test_dmrg_excited(eps=1.e-12): # checks ground state and 2 excited states (in same symmetry sector) for a small system # (without truncation) L, g = 8, 1.3 bc = 'finite' model_params = dict(L=L, J=1., g=g, bc_MPS=bc, conserve='parity', verbose=0) M = TFIChain(model_params) # compare to exact solution ED = ExactDiag(M) ED.build_full_H_from_mpo() ED.full_diagonalization() # Note: energies sorted by chargesector (first 0), then ascending -> perfect for comparison print("Exact diag: E[:5] = ", ED.E[:5]) print("Exact diag: (smalles E)[:10] = ", np.sort(ED.E)[:10]) psi_ED = [ED.V.take_slice(i, 'ps*') for i in range(5)] print("charges : ", [psi.qtotal for psi in psi_ED]) # first DMRG run psi0 = mps.MPS.from_product_state(M.lat.mps_sites(), [0] * L, bc=bc) dmrg_pars = { 'verbose': 0, 'N_sweeps_check': 1, 'lanczos_params': { 'reortho': False }, 'diag_method': 'lanczos', 'combine': True } eng0 = dmrg.TwoSiteDMRGEngine(psi0, M, dmrg_pars) E0, psi0 = eng0.run() assert abs((E0 - ED.E[0]) / ED.E[0]) < eps ov = npc.inner(psi_ED[0], ED.mps_to_full(psi0), 'range', do_conj=True) assert abs(abs(ov) - 1.) < eps # unique groundstate: finite size gap! # second DMRG run for first excited state dmrg_pars['verbose'] = 1. dmrg_pars['orthogonal_to'] = [psi0] psi1 = mps.MPS.from_product_state(M.lat.mps_sites(), [0] * L, bc=bc) eng1 = dmrg.TwoSiteDMRGEngine(psi1, M, dmrg_pars) E1, psi1 = eng1.run() assert abs((E1 - ED.E[1]) / ED.E[1]) < eps ov = npc.inner(psi_ED[1], ED.mps_to_full(psi1), 'range', do_conj=True) assert abs(abs(ov) - 1.) < eps # unique groundstate: finite size gap! # and a third one to check with 2 eigenstates dmrg_pars['orthogonal_to'] = [psi0, psi1] # note: different intitial state necessary, otherwise H is 0 psi2 = mps.MPS.from_singlets(psi0.sites[0], L, [(0, 1), (2, 3), (4, 5), (6, 7)], bc=bc) eng2 = dmrg.TwoSiteDMRGEngine(psi2, M, dmrg_pars) E2, psi2 = eng2.run() print(E2) assert abs((E2 - ED.E[2]) / ED.E[2]) < eps ov = npc.inner(psi_ED[2], ED.mps_to_full(psi2), 'range', do_conj=True) assert abs(abs(ov) - 1.) < eps # unique groundstate: finite size gap!
def example_DMRG_tf_ising_infinite(g, verbose=True): print("infinite DMRG, transverse field Ising model") print("g={g:.2f}".format(g=g)) model_params = dict(L=2, J=1., g=g, bc_MPS='infinite', conserve=None, verbose=verbose) 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) dmrg_params = { 'mixer': True, # setting this to True helps to escape local minima 'trunc_params': { 'chi_max': 30, 'svd_min': 1.e-10 }, 'max_E_err': 1.e-10, 'verbose': verbose, } # instead of # info = dmrg.run(psi, M, dmrg_params) # E = info['E'] # we can also use the a Engine directly: eng = dmrg.EngineCombine(psi, M, dmrg_params) E, psi = eng.run() # equivalent to dmrg.run() up to the return parameters. print("E = {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 example_TEBD_gs_finite(L, g): print("finite TEBD, imaginary time evolution, 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, verbose=0) M = TFIChain(model_params) psi = MPS.from_product_state(M.lat.mps_sites(), [0] * L, bc='finite') 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 }, 'verbose': 1 } eng = tebd.Engine(psi, M, tebd_params) eng.run_GS() # the main work... E = np.sum(psi.expectation_value(M.H_bond[1:])) print("E = {E:.13f}".format(E=E)) print("final bond dimensions: ", psi.chi) if L < 20: M2 = SimpleTFIModel(L=L, J=1., g=g, bc='finite') E_ed = M2.exact_finite_gs_energy() print("Exact diagonalization: E = {E:.13f}".format(E=E_ed)) print("relative error: ", abs((E - E_ed) / E_ed)) return E, psi, M
def run_tenpy_tdvp(L, maxdim, tf, verbose=False): model_params = dict(L=L, J=1., g=1, bc_MPS='finite', conserve=None, verbose=verbose) 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) tdvp_params = { 'start_time': 0, 'dt': 0.1, 'trunc_params': { 'chi_max': maxdim, 'svd_min': 0, 'trunc_cut': None } } tdvp_engine = tdvp.Engine(psi=psi, model=M, TDVP_params=tdvp_params) tdvp_engine.run_two_sites(N_steps=int(tf / 0.1)) return np.amax(psi.chi)
def example_TEBD_gs_infinite(g): print("infinite TEBD, imaginary time evolution, g={g:.2f}".format(g=g)) model_params = dict(L=2, J=1., g=g, bc_MPS='infinite', conserve=None, verbose=0) M = TFIChain(model_params) psi = MPS.from_product_state(M.lat.mps_sites(), [0] * 2, bc='infinite') 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 }, 'verbose': 1 } eng = tebd.Engine(psi, M, tebd_params) eng.run_GS() # the main work... E = np.mean(psi.expectation_value(M.H_bond)) print("E = {E:.13f}".format(E=E)) print("final bond dimensions: ", psi.chi) print("correlation length:", psi.correlation_length()) M2 = SimpleTFIModel(L=2, J=1., g=g, bc='infinite') E_ex = M2.exact_infinite_gs_energy() print("Analytic result: E/L = {E:.13f}".format(E=E_ex)) print("relative error: ", abs((E - E_ex) / E_ex)) return E, psi, M
def example_DMRG_infinite(g): print("infinite DMRG, g={g:.2f}".format(g=g)) model_params = dict(L=2, J=1., g=g, bc_MPS='infinite', conserve=None, verbose=0) M = TFIChain(model_params) psi = MPS.from_product_state(M.lat.mps_sites(), [0] * 2, bc='infinite') dmrg_params = { 'mixer': True, 'trunc_params': { 'chi_max': 30, 'svd_min': 1.e-10 }, 'max_E_err': 1.e-10, 'verbose': 1 } dmrg.run(psi, M, dmrg_params) E = np.mean(psi.expectation_value(M.H_bond)) print("E = {E:.13f}".format(E=E)) print("final bond dimensions: ", psi.chi) print("correlation length:", psi.correlation_length()) # compare to exact result E_exact = tfi_exact.infinite_gs_energy(1., g) print("Analytic result: E/L = {E:.13f}".format(E=E_exact)) print("relative error: ", abs((E - E_exact) / E_exact)) return E, psi, M
def example_DMRG_tf_ising_finite(L, g, verbose=True): print("finite DMRG, transverse field Ising model") 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, verbose=verbose) 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) dmrg_params = { 'mixer': None, # setting this to True helps to escape local minima 'max_E_err': 1.e-10, 'trunc_params': { 'chi_max': 30, 'svd_min': 1.e-10 }, 'verbose': verbose, } info = dmrg.run(psi, M, dmrg_params) # the main work... E = info['E'] 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_DMRG_tf_ising_infinite_S_xi_scaling(g): model_params = dict(L=2, J=1., g=g, bc_MPS='infinite', conserve='best', verbose=0) 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) dmrg_params = { 'start_env': 10, 'mixer': False, # 'mixer_params': {'amplitude': 1.e-3, 'decay': 5., 'disable_after': 50}, 'trunc_params': { 'chi_max': 5, 'svd_min': 1.e-10 }, 'max_E_err': 1.e-9, 'max_S_err': 1.e-6, 'update_env': 0, 'verbose': 0 } chi_list = np.arange(7, 31, 2) s_list = [] xi_list = [] eng = dmrg.TwoSiteDMRGEngine(psi, M, dmrg_params) for chi in chi_list: t0 = time.time() eng.reset_stats( ) # necessary if you for example have a fixed numer of sweeps, if you don't set this you option your simulation stops after initial number of sweeps! eng.trunc_params['chi_max'] = chi ## DMRG Calculation ## print("Start IDMRG CALCULATION") eng.run() eng.engine_params['mixer'] = None psi.canonical_form() ## Calculating bond entropy and correlation length ## s_list.append(np.mean(psi.entanglement_entropy())) xi_list.append(psi.correlation_length()) print(chi, time.time() - t0, np.mean(psi.expectation_value(M.H_bond)), s_list[-1], xi_list[-1], flush=True) tenpy.tools.optimization.optimize( 3) # quite some speedup for small chi print("SETTING NEW BOND DIMENSION") return s_list, xi_list
def test_dmrg(bc_MPS, combine, mixer, n, g=1.2): L = 2 if bc_MPS == 'infinite' else 8 model_params = dict(L=L, J=1., g=g, bc_MPS=bc_MPS, conserve=None, verbose=0) M = TFIChain(model_params) state = [0] * L # Ferromagnetic Ising psi = mps.MPS.from_product_state(M.lat.mps_sites(), state, bc=bc_MPS) dmrg_pars = { 'verbose': 5, 'combine': combine, 'mixer': mixer, 'chi_list': { 0: 10, 5: 30 }, 'max_E_err': 1.e-12, 'max_S_err': 1.e-8, 'N_sweeps_check': 4, 'mixer_params': { 'disable_after': 15, 'amplitude': 1.e-5 }, 'trunc_params': { 'svd_min': 1.e-10, }, 'max_N_for_ED': 20, # small enough that we test both diag_method=lanczos and ED_block! 'max_sweeps': 40, 'active_sites': n, } if not mixer: del dmrg_pars['mixer_params'] # avoid warning of unused parameter if bc_MPS == 'infinite': # if mixer is not None: # dmrg_pars['mixer_params']['amplitude'] = 1.e-12 # don't actually contribute... dmrg_pars['start_env'] = 1 res = dmrg.run(psi, M, dmrg_pars) if bc_MPS == 'finite': ED = ExactDiag(M) ED.build_full_H_from_mpo() ED.full_diagonalization() E_ED, psi_ED = ED.groundstate() ov = npc.inner(psi_ED, ED.mps_to_full(psi), 'range', do_conj=True) print("E_DMRG={Edmrg:.14f} vs E_exact={Eex:.14f}".format(Edmrg=res['E'], Eex=E_ED)) print("compare with ED: overlap = ", abs(ov)**2) assert abs(abs(ov) - 1.) < 1.e-10 # unique groundstate: finite size gap! var = M.H_MPO.variance(psi) assert var < 1.e-10 else: # compare exact solution for transverse field Ising model Edmrg = res['E'] Eexact = e0_tranverse_ising(g) print("E_DMRG={Edmrg:.12f} vs E_exact={Eex:.12f}".format(Edmrg=Edmrg, Eex=Eexact)) print("relative energy error: {err:.2e}".format(err=abs((Edmrg - Eexact) / Eexact))) print("norm err:", psi.norm_test()) Edmrg2 = np.mean(psi.expectation_value(M.H_bond)) Edmrg3 = M.H_MPO.expectation_value(psi) assert abs((Edmrg - Eexact) / Eexact) < 1.e-10 assert abs((Edmrg - Edmrg2) / Edmrg2) < max(1.e-10, np.max(psi.norm_test())) assert abs((Edmrg - Edmrg3) / Edmrg3) < max(1.e-10, np.max(psi.norm_test()))
def test_dmrg_excited(eps=1.e-12): # checks ground state and 2 excited states (in same symmetry sector) for a small system # (without truncation) L, g = 8, 1.1 bc = 'finite' model_params = dict(L=L, J=1., g=g, bc_MPS=bc, conserve='parity', verbose=0) M = TFIChain(model_params) # compare to exact solution ED = ExactDiag(M) ED.build_full_H_from_mpo() ED.full_diagonalization() # Note: energies sorted by chargesector (first 0), then ascending -> perfect for comparison print("Exact diag: E[:5] = ", ED.E[:5]) # first DMRG run psi0 = mps.MPS.from_product_state(M.lat.mps_sites(), [0] * L, bc=bc) dmrg_pars = { 'verbose': 1, 'N_sweeps_check': 1, 'lanczos_params': { 'reortho': True } } eng0 = dmrg.EngineCombine(psi0, M, dmrg_pars) E0, psi0 = eng0.run() assert abs((E0 - ED.E[0]) / ED.E[0]) < eps ov = npc.inner(ED.V.take_slice(0, 'ps*'), ED.mps_to_full(psi0), do_conj=True) assert abs(abs(ov) - 1.) < eps # unique groundstate: finite size gap! # second DMRG run for first excited state dmrg_pars['orthogonal_to'] = [psi0] psi1 = mps.MPS.from_product_state(M.lat.mps_sites(), [0] * L, bc=bc) eng1 = dmrg.EngineCombine(psi1, M, dmrg_pars) E1, psi1 = eng1.run() assert abs((E1 - ED.E[1]) / ED.E[1]) < eps ov = npc.inner(ED.V.take_slice(1, 'ps*'), ED.mps_to_full(psi1), do_conj=True) assert abs(abs(ov) - 1.) < eps # unique groundstate: finite size gap! # and a third one to check with 2 eigenstates dmrg_pars['orthogonal_to'] = [psi0, psi1] # note: different intitial state necessary, otherwise H is 0 psi2 = mps.MPS.from_product_state(M.lat.mps_sites(), [0, 1] * (L // 2), bc=bc) eng2 = dmrg.EngineCombine(psi2, M, dmrg_pars) E2, psi2 = eng2.run() print(E2) assert abs((E2 - ED.E[2]) / ED.E[2]) < eps ov = npc.inner(ED.V.take_slice(2, 'ps*'), ED.mps_to_full(psi2), do_conj=True) assert abs(abs(ov) - 1.) < eps # unique groundstate: finite size gap!
def example_TEBD_gs_tf_ising_finite(L, g, verbose=True): 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, verbose=verbose) 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 }, 'verbose': verbose, } eng = tebd.Engine(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 check_dmrg(L=4, bc_MPS='finite', engine='EngineCombine', mixer=None, g=1.5): model_params = dict(L=L, J=1., g=g, bc_MPS=bc_MPS, conserve=None, verbose=0) M = TFIChain(model_params) state = [0] * L # Ferromagnetic Ising psi = mps.MPS.from_product_state(M.lat.mps_sites(), state, bc=bc_MPS) dmrg_pars = { 'verbose': 5, 'engine': engine, 'mixer': mixer, 'chi_list': { 0: 10, 5: 30 }, 'max_E_err': 1.e-12, 'max_S_err': 1.e-8, 'N_sweeps_check': 4, 'mixer_params': { 'disable_after': 6, 'amplitude': 1.e-5 }, 'trunc_params': { 'svd_min': 1.e-10, }, 'lanczos_params': { 'reortho': True, 'N_cache': 20 }, 'max_sweeps': 40, } if mixer is None: del dmrg_pars['mixer_params'] # avoid warning of unused parameter if bc_MPS == 'infinite': if mixer is not None: dmrg_pars['mixer_params']['amplitude'] = 1.e-12 # don't actually contribute... dmrg_pars['start_env'] = 1 res = dmrg.run(psi, M, dmrg_pars) if bc_MPS == 'finite': ED = ExactDiag(M) ED.build_full_H_from_mpo() ED.full_diagonalization() psi_ED = ED.groundstate() ov = npc.inner(psi_ED, ED.mps_to_full(psi), do_conj=True) print("E_DMRG={Edmrg:.14f} vs E_exact={Eex:.14f}".format(Edmrg=res['E'], Eex=np.min(ED.E))) print("compare with ED: overlap = ", abs(ov)**2) assert abs(abs(ov) - 1.) < 1.e-10 # unique groundstate: finite size gap! else: # compare exact solution for transverse field Ising model Edmrg = res['E'] Eexact = e0_tranverse_ising(g) print("E_DMRG={Edmrg:.12f} vs E_exact={Eex:.12f}".format(Edmrg=Edmrg, Eex=Eexact)) print("relative energy error: {err:.2e}".format(err=abs((Edmrg - Eexact) / Eexact))) print("norm err:", psi.norm_test()) Edmrg2 = np.mean(psi.expectation_value(M.H_bond)) assert abs((Edmrg - Eexact) / Eexact) < 1.e-10 assert abs((Edmrg - Edmrg2) / Edmrg2) < max(1.e-10, np.max(psi.norm_test()))
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 solve(self, model_params, psi): field_params1 = model_params.copy() field_params2 = model_params.copy() field_params1['h'] = 0.1 field_params2['h'] = 0.01 M = TFIChain(model_params) Mb1 = TFIChainField(field_params1) Mb2 = TFIChainField(field_params2) eng = dmrg.TwoSiteDMRGEngine(psi, Mb1, self.options) _, psi = eng.run() eng = dmrg.TwoSiteDMRGEngine(psi, Mb2, self.options) _, psi = eng.run() eng = dmrg.TwoSiteDMRGEngine(psi, M, self.options) return eng.run()
def _set_params(self): self.chi = self.options.get('chi', 10) self.g = self.options.get('g', 1.0) self.J = self.options.get('J', 1.0) self.solver = self.options.get('solver', 'DMRG2') self.conserve = self.options.get('conserve', None) self.model_params = dict(L=2, J=self.J, g=self.g, bc_MPS='infinite', conserve=self.conserve) self.M = TFIChain(self.model_params) # defaults that need to be set self.psi0 = None self.E0 = None
def get_initial_state(self, g): self.g = g self.J = 0.0 model_params = dict(L=2, J=self.J, g=self.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) self.psi0 = psi.copy() self.Si = np.mean((self.psi0.entanglement_entropy())) self.Sxi = np.mean(self.psi0.expectation_value('Sx')) self.Syi = np.mean(self.psi0.expectation_value('Sy')) self.Szi = np.mean(self.psi0.expectation_value('Sz'))
def _update_couplings(self): inds = np.argwhere( self._gs < self.g ) # there are more g values to run, we assume g is decreasing throughout the run if len(inds) > 0: it = inds[0][0] self._ts = self._ts[it:] self._gs = self._gs[it:] self._Js = self._Js[it:] if self.g == self._gs[-1]: # job finished: self._ts = np.array([]) self._gs = np.array([]) self._Js = np.array([]) model_params = dict(L=self.psi.L, J=self.J, g=self.g, bc_MPS='infinite', conserve=None) self.M = TFIChain(model_params)
def imag_tebd(L=30, beta_max=3., dt=0.05, order=2, bc="finite"): model_params = dict(L=L, J=1., g=1.2) M = TFIChain(model_params) psi = PurificationMPS.from_infiniteT(M.lat.mps_sites(), bc=bc) options = { 'trunc_params': { 'chi_max': 100, 'svd_min': 1.e-8 }, 'order': order, 'dt': dt, 'N_steps': 1 } beta = 0. eng = PurificationTEBD(psi, M, options) Szs = [psi.expectation_value("Sz")] betas = [0.] while beta < beta_max: beta += 2. * dt # factor of 2: |psi> ~= exp^{- dt H}, but rho = |psi><psi| betas.append(beta) eng.run_imaginary(dt) # cool down by dt Szs.append(psi.expectation_value("Sz")) # and further measurements... return {'beta': betas, 'Sz': Szs}
def run(gs): print("running for gs = ", gs) L = 2 model_params = dict(L=L, J=1., g=gs[0], bc_MPS='infinite', conserve=None) chi = 100 dmrg_params = { 'trunc_params': { 'chi_max': chi, 'svd_min': 1.e-10, 'trunc_cut': None }, 'update_env': 5, 'start_env': 5, 'max_E_err': 0.0001, 'max_S_err': 0.0001, 'max_sweeps': 100, # NOTE: this is not enough to fully converge at the critical point! 'mixer': False } M = TFIChain(model_params) psi = MPS.from_product_state(M.lat.mps_sites(), (["up", "down"] * L)[:L], M.lat.bc_MPS) engine = dmrg.TwoSiteDMRGEngine(psi, M, dmrg_params) np.set_printoptions(linewidth=120) corr_length = [] fidelity = [] Sz = [] E = [] S = [] SxSx = [] old_psi = None for g in gs: print("-" * 80) print("g =", g) print("-" * 80) model_params['g'] = g M = TFIChain(model_params) engine.init_env( model=M) # (re)initialize DMRG environment with new model # this uses the result from the previous DMRG as first initial guess E0, psi = engine.run() E.append(E0) # psi is modified by engine.run() and now represents the ground state for the current `g`. S.append(psi.entanglement_entropy()[0]) corr_length.append(psi.correlation_length(tol_ev0=1.e-3)) print("corr. length", corr_length[-1]) Sz.append(psi.expectation_value('Sigmaz')) print("<Sigmaz>", Sz[-1]) SxSx.append( psi.correlation_function("Sigmax", "Sigmax", [0], 20)[0, :]) print("<Sigmax_0 Sigmax_i>", SxSx[-1]) if old_psi is not None: fidelity.append(np.abs(old_psi.overlap(psi))) print("fidelity", fidelity[-1]) old_psi = psi.copy() dmrg_params[ 'start_env'] = 0 # (some of) the parameters are read out again results = { 'model_params': model_params, 'dmrg_params': dmrg_params, 'gs': gs, 'corr_length': np.array(corr_length), 'fidelity': np.array(fidelity), 'Sz': np.array(Sz), 'E': np.array(E), 'S': np.array(S), 'SxSx': np.array(SxSx), 'eval_transfermatrix': np.exp(-1. / np.array(corr_length)), } return results
"""Call of infinite DMRG.""" # Copyright 2019 TeNPy Developers, GNU GPLv3 from tenpy.networks.mps import MPS from tenpy.models.tf_ising import TFIChain from tenpy.algorithms import dmrg N = 2 # number of sites in unit cell model = TFIChain({"L": N, "J": 1., "g": 1.1, "bc_MPS": "infinite"}) sites = model.lat.mps_sites() psi = MPS.from_product_state(sites, ['up'] * N, "infinite") dmrg_params = { "trunc_params": { "chi_max": 100, "svd_min": 1.e-10 }, "mixer": True } info = dmrg.run(psi, model, dmrg_params) print("E =", info['E']) # E = -1.342864022725017 print("max. bond dimension =", max(psi.chi)) # max. bond dimension = 56 print("corr. length =", psi.correlation_length()) # corr. length = 4.915809146764157