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_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_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.EngineCombine(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.DMRG_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 run(model_params, phi_ext=np.linspace(0, 1.0, 7)): data = dict(phi_ext=phi_ext, QL=[], ent_spectrum=[]) dmrg_params = { 'mixer': True, # setting this to True helps to escape local minima 'mixer_params': { 'amplitude': 1.e-5, 'decay': 1.2, 'disable_after': 30 }, 'trunc_params': { 'svd_min': 1.e-10, }, 'lanczos_params': { 'N_min': 5, 'N_max': 20 }, 'chi_list': { 0: 9, 10: 49, 20: 100 }, 'max_E_err': 1.e-10, 'max_S_err': 1.e-6, 'max_sweeps': 150, 'verbose': 1., } prod_state = ['empty', 'full'] * (model_params['Lx'] * model_params['Ly']) eng = None for phi in phi_ext: print("=" * 100) print("phi_ext = ", phi) model_params['phi_ext'] = phi if eng is None: # first time in the loop M = FermionicHaldaneModel(model_params) psi = MPS.from_product_state(M.lat.mps_sites(), prod_state, bc=M.lat.bc_MPS) eng = dmrg.EngineCombine(psi, M, dmrg_params) else: del eng.DMRG_params['chi_list'] M = FermionicHaldaneModel(model_params) eng.init_env(model=M) E, psi = eng.run() data['QL'].append(psi.average_charge(bond=0)[0]) data['ent_spectrum'].append( psi.entanglement_spectrum(by_charge=True)[0]) return data
def setup_benchmark(mod_q=[1], legs=10, size=20, **kwargs): """Setup DMRG 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') dmrg_params = { 'trunc_params': { 'chi_max': size, 'svd_min': 1.e-45, }, 'lanczos_params': { 'N_min': 10, 'N_max': 10 }, # 'mixer': None, # 'N_sweeps_check': 1, # 'min_sweeps': 10, # 'max_sweeps': 100, # 'max_E_err': 1.e-13, 'verbose': 0., } eng = dmrg.EngineCombine(psi, M, dmrg_params) eng.verbose = 0.02 for i in range(100): eng.sweep(meas_E_trunc=False) eng.sweep(optimize=False, meas_E_trunc=False) # environment sweep if eng.verbose > 0.1: print(eng.psi.chi) print(eng.psi.entanglement_entropy()) if eng.verbose > 0.1: print("set up dmrg for size", size) if eng.verbose > 0.01: print('initial chi', eng.psi.chi) eng.reset_stats() return eng
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(Jzs): L = 2 model_params = dict(L=L, Jx=1., Jy=1., Jz=Jzs[0], bc_MPS='infinite', conserve='Sz', verbose=0) chi = 300 dmrg_params = { 'trunc_params': { 'chi_max': chi, 'svd_min': 1.e-10, 'trunc_cut': None }, 'update_env': 20, 'start_env': 20, 'max_E_err': 0.0001, 'max_S_err': 0.0001, 'verbose': 1, 'mixer': False } M = SpinChain(model_params) psi = MPS.from_product_state(M.lat.mps_sites(), (["up", "down"] * L)[:L], M.lat.bc_MPS) engine = dmrg.EngineCombine(psi, M, dmrg_params) np.set_printoptions(linewidth=120) corr_length = [] for Jz in Jzs: print("-" * 80) print("Jz =", Jz) print("-" * 80) model_params['Jz'] = Jz M = SpinChain(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 engine.run() # psi is modified by engine.run() and now represents the ground state for the current `Jz`. corr_length.append(psi.correlation_length(tol_ev0=1.e-3)) print("corr. length", corr_length[-1]) print("<Sz>", psi.expectation_value('Sz')) dmrg_params['start_env'] = 0 # (some of) the parameters are read out again corr_length = np.array(corr_length) results = { 'model_params': model_params, 'dmrg_params': dmrg_params, 'Jzs': Jzs, 'corr_length': corr_length, 'eval_transfermatrix': np.exp(-1. / corr_length) } return results
def run(model_params, phi_ext=np.linspace(0, 2.0, 7)): data = dict(phi_ext=phi_ext, QL=[], ent_spectrum=[]) dmrg_params = { 'mixer': True, # setting this to True helps to escape local minima 'mixer_params': { 'amplitude': 1.e-5, 'decay': 1.2, 'disable_after': 30 }, 'trunc_params': { 'svd_min': 1.e-10, }, 'lanczos_params': { 'N_min': 5, 'N_max': 20 }, 'chi_list': { 0: 9, 10: 49, 20: 100 }, 'max_E_err': 1.e-10, 'max_S_err': 1.e-6, 'max_sweeps': 150, 'verbose': 1., } prod_state = [1] if 2 * model_params['Lx'] * model_params['Ly'] % 4 != 0: warnings.warn( "Total filling factor = 1/4 cannot be achieved with this unit cell geometry." ) for i in range(1, 2 * model_params['Lx'] * model_params['Ly']): if i % 4 == 0: prod_state.append(1) else: prod_state.append(0) print(prod_state) eng = None for phi in phi_ext: print("=" * 100) print("phi_ext = ", phi) model_params['phi_ext'] = phi if eng is None: # first time in the loop M = BosonicHaldaneModel(model_params) psi = MPS.from_product_state(M.lat.mps_sites(), prod_state, bc=M.lat.bc_MPS) eng = dmrg.EngineCombine(psi, M, dmrg_params) else: del eng.DMRG_params['chi_list'] M = BosonicHaldaneModel(model_params) eng.init_env(model=M) E, psi = eng.run() data['QL'].append(psi.average_charge(bond=0)[0]) data['ent_spectrum'].append( psi.entanglement_spectrum(by_charge=True)[0]) return data