def test_dmrg_explicit_plus_hc(N, bc_MPS, tol=1.e-13, bc='finite'): model_params = dict(L=2 * N, Jx=1., Jy=1., Jz=2.5, hz=5.125, bc_MPS=bc_MPS) dmrg_params = dict(N_sweeps_check=2, mixer=True, trunc_params={'chi_max': 50}) M1 = SpinChain(model_params) model_params['explicit_plus_hc'] = True M2 = SpinChain(model_params) assert M2.H_MPO.explicit_plus_hc psi1 = mps.MPS.from_product_state(M1.lat.mps_sites(), ['up', 'down'] * N, bc=bc_MPS) E1, psi1 = dmrg.TwoSiteDMRGEngine(psi1, M1, dmrg_params).run() psi2 = mps.MPS.from_product_state(M2.lat.mps_sites(), ['up', 'down'] * N, bc=bc_MPS) E2, psi2 = dmrg.TwoSiteDMRGEngine(psi2, M2, dmrg_params).run() print(E1, E2, abs(E1 - E2)) assert abs(E1 - E2) < tol ov = abs(psi1.overlap(psi2)) print("ov =", ov) assert abs(ov - 1) < tol dmrg_params['combine'] = True psi3 = mps.MPS.from_product_state(M2.lat.mps_sites(), ['up', 'down'] * N, bc=bc_MPS) E3, psi3 = dmrg_parallel.DMRGThreadPlusHC(psi3, M2, dmrg_params).run() print(E1, E3, abs(E1 - E3)) assert abs(E1 - E3) < tol ov = abs(psi1.overlap(psi3)) print("ov =", ov) assert abs(ov - 1) < tol
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.TwoSiteDMRGEngine(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_groundstate_xxz(L=30, Jz=1., hz=0., conserve='best', chi_max=50, Jz_init=None): model_params = dict(L=L, Jx=1., Jy=1., Jz=Jz, hz=hz, bc_MPS='finite', conserve='best', verbose=1) result = {} M = SpinChain(model_params) result['model'] = 'SpinChain' result['model_params'] = model_params result['sites'] = np.arange(L) result['bonds'] = np.arange(L - 1) + 0.5 psi = MPS.from_product_state(M.lat.mps_sites(), (["up", "down"] * L)[:L]) dmrg_params = { 'trunc_params': { 'chi_max': chi_max, 'svd_min': 1.e-10, 'trunc_cut': None }, 'mixer': True, 'verbose': 1 } if Jz_init: # run first time with small hx to break the symmetry model_params_Jz = model_params.copy() model_params_Jz['Jz'] = Jz_init M_Jz = SpinChain(model_params_Jz) dmrg_params['start_env'] = 10, run_DMRG(psi, M_Jz, dmrg_params) # run simulation t0 = time.time() info = run_DMRG(psi, M, dmrg_params) print("DMRG finished after", time.time() - t0, "s") # save results in output file result['chi'] = np.array(psi.chi) result['S'] = np.array(psi.entanglement_entropy()) result['E'] = info['E'] result['sweeps'] = info['sweep_statistics']['sweep'] for key in ['E', 'S', 'max_trunc_err', 'max_E_trunc', 'max_chi']: result_key = 'sweep_' + key result[result_key] = np.array(info['sweep_statistics'][key]) return result
def test_UI(bc_MPS, g=0.5): # Test a time evolution against exact diagonalization for finite bc L = 10 dt = 0.01 if bc_MPS == 'finite': L = 6 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 / np.sqrt(2), -1 / np.sqrt(2)]] * L ) # pointing in (-x)-direction psi = tenpy.networks.mps.MPS.from_product_state(M.lat.mps_sites(), state, bc=bc_MPS) psi.test_sanity() U = make_U(M.calc_H_MPO(), dt * 1j, which='I') if bc_MPS == 'finite': ED = tenpy.algorithms.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 = apply_mpo(psi, U, {}) psiED = npc.tensordot(UED, psiED, ('ps*', [0])) assert (np.abs(np.abs(npc.inner(psiED, ED.mps_to_full(psi))) - 1) < 1e-2) if bc_MPS == 'infinite': psiTEBD = psi.copy() TEBD_params = {'dt': dt, 'N_steps': 1} EngTEBD = tenpy.algorithms.tebd.Engine(psiTEBD, M, TEBD_params) for i in range(30): EngTEBD.run() psi = apply_mpo(psi, U, {}) print(np.abs(psi.overlap(psiTEBD) - 1)) print(psi.norm) #This test fails assert (np.abs(np.abs(psi.overlap(psiTEBD)) - 1) < 1e-2)
def test_apply_mpo(method): bc_MPS = "finite" # NOTE: overlap doesn't work for calculating the energy (density) in infinite systems! # energy is extensive, overlap exponential.... L = 5 g = 0.5 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 / np.sqrt(2), -1 / np.sqrt(2)]] * L ) # pointing in (-x)-direction psi = mps.MPS.from_product_state(M.lat.mps_sites(), state, bc=bc_MPS) H = M.H_MPO Eexp = H.expectation_value(psi) psi2 = psi.copy() options = {'compression_method': method, 'trunc_params': {'chi_max': 50}} H.apply(psi2, options) Eapply = psi2.overlap(psi) assert abs(Eexp - Eapply) < 1e-5 psi3 = psi.copy() H.apply(psi3, options) Eapply3 = psi3.overlap(psi) assert abs(Eexp - Eapply3) < 1e-5
def test_MPO_var(L=8, tol=1.e-13): xxz_pars = dict(L=L, Jx=1., Jy=1., Jz=1.1, hz=0.1, bc_MPS='finite', conserve=None) M = SpinChain(xxz_pars) psi = random_MPS(L, 2, 10) exp_val = M.H_MPO.expectation_value(psi) ED = ExactDiag(M) ED.build_full_H_from_mpo() psi_full = ED.mps_to_full(psi) exp_val_full = npc.inner(psi_full, npc.tensordot(ED.full_H, psi_full, axes=1), axes='range', do_conj=True) assert abs(exp_val - exp_val_full) / abs(exp_val_full) < tol Hsquared = M.H_MPO.variance(psi, 0.) Hsquared_full = npc.inner(psi_full, npc.tensordot(ED.full_H, npc.tensordot(ED.full_H, psi_full, axes=1), axes=1), axes='range', do_conj=True) assert abs(Hsquared - Hsquared_full) / abs(Hsquared_full) < tol var = M.H_MPO.variance(psi) var_full = Hsquared_full - exp_val_full**2 assert abs(var - var_full) / abs(var_full) < tol
def test_dmrg_explicit_plus_hc(tol=1.e-13): model_params = dict(L=12, Jx=1., Jy=1., Jz=1.25, hz=5.125) dmrg_params = dict(N_sweeps_check=2, mixer=False) M1 = SpinChain(model_params) model_params['explicit_plus_hc'] = True M2 = SpinChain(model_params) assert M2.H_MPO.explicit_plus_hc psi1 = mps.MPS.from_product_state(M1.lat.mps_sites(), ['up', 'down'] * 6) E1, psi1 = dmrg.TwoSiteDMRGEngine(psi1, M1, dmrg_params).run() psi2 = mps.MPS.from_product_state(M2.lat.mps_sites(), ['up', 'down'] * 6) E2, psi2 = dmrg.TwoSiteDMRGEngine(psi2, M2, dmrg_params).run() print(E1, E2, abs(E1 - E2)) assert abs(E1 - E2) < tol ov = abs(psi1.overlap(psi2)) print("ov =", ov) assert abs(ov - 1) < tol
def test_dmrg_diag_method(engine, diag_method, tol=1.e-6): bc_MPS = 'finite' model_params = dict(L=6, S=0.5, bc_MPS=bc_MPS, conserve='Sz', verbose=0) M = SpinChain(model_params) # chose total Sz= 4, not 3=6/2, i.e. not the sector with lowest energy! # make sure below that we stay in that sector, if we're supposed to. init_Sz_4 = ['up', 'down', 'up', 'up', 'up', 'down'] psi_Sz_4 = mps.MPS.from_product_state(M.lat.mps_sites(), init_Sz_4, bc=bc_MPS) dmrg_pars = { 'verbose': 1, 'N_sweeps_check': 1, 'combine': True, 'max_sweeps': 5, 'diag_method': diag_method, 'mixer': True, } ED = ExactDiag(M) ED.build_full_H_from_mpo() ED.full_diagonalization() if diag_method == "ED_all": charge_sector = None # allow to change the sector else: charge_sector = [2] # don't allow to change the sector E_ED, psi_ED = ED.groundstate(charge_sector=charge_sector) DMRGEng = dmrg.__dict__.get(engine) print("DMRGEng = ", DMRGEng) print("setting diag_method = ", dmrg_pars['diag_method']) eng = DMRGEng(psi_Sz_4.copy(), M, dmrg_pars) E0, psi0 = eng.run() print("E0 = {0:.15f}".format(E0)) assert abs(E_ED - E0) < tol ov = npc.inner(psi_ED, ED.mps_to_full(psi0), 'range', do_conj=True) assert abs(abs(ov) - 1) < tol
def test_map_Fermions_Spins(L=6, Jxx=1., Jz=0.1, hz=0.01): # we only check for correctness in the (uniform) bulk, not caring about the boundary terms print("Spins") spar = dict(L=L, Jx=Jxx, Jy=Jxx, Jz=Jz, hz=hz) schain = SpinChain(spar) # Sz + 0.5 -> n, thus some constants appearing constant = -0.25 * Jz - 0.5 * hz Hb_s = schain.H_bond[L // 2].transpose(['p0', 'p1', 'p0*', 'p1*']).to_ndarray() Hb_s = Hb_s.reshape(4, 4) + constant * np.eye(4) print(Hb_s) print("Fermions") fpar = dict(L=spar['L'], J=-0.5 * spar['Jx'], V=spar['Jz'], mu=spar['hz'] + spar['Jz']) fchain = FermionChain(fpar) Hb_f = fchain.H_bond[L // 2].transpose(['p0', 'p1', 'p0*', 'p1*']).to_ndarray() Hb_f = Hb_f.reshape(4, 4) print(Hb_f) for i in range(2, L - 1): Hb_s = schain.H_bond[i].transpose(['p0', 'p1', 'p0*', 'p1*']).to_ndarray().reshape(4, 4) Hb_f = fchain.H_bond[i].transpose(['p0', 'p1', 'p0*', 'p1*']).to_ndarray().reshape(4, 4) assert (np.allclose(Hb_s + constant * np.eye(4), Hb_f))
def run(Jzs): L = 2 model_params = dict(L=L, Jx=1., Jy=1., Jz=1., bc_MPS='infinite', conserve='Sz', verbose=0) chi = 300 dmrg_params = dict(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=True) M = SpinChain(model_params) psi = MPS.from_product_state(M.lat.mps_sites(), (["up", "down"] * L)[:L], M.lat.bc_MPS) 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) run_DMRG(psi, M, dmrg_params) corr_length.append(psi.correlation_length(tol_ev0=1.e-3)) print("corr. length", corr_length[-1]) print("<Sz>", psi.expectation_value('Sz')) 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 test_dmrg_add_hc_to_MPO(tol=1.e-13): model_params = dict(L=6, Jx=1., Jy=1., Jz=1.25, hz=5.125) M1 = SpinChain(model_params) dmrg_params = dict(N_sweeps_check=2, mixer=False) psi = mps.MPS.from_product_state(M1.lat.mps_sites(), ['up', 'down'] * 3) model_params['add_hc_to_MPO'] = True M2 = SpinChain(model_params) psi = mps.MPS.from_product_state(M1.lat.mps_sites(), ['up', 'down'] * 3) E1, psi1 = dmrg.TwoSiteDMRGEngine(psi, M1, dmrg_params).run() psi2 = mps.MPS.from_product_state(M1.lat.mps_sites(), ['up', 'down'] * 3) E2, psi2 = dmrg.TwoSiteDMRGEngine(psi, M2, dmrg_params).run() print(E1, E2, abs(E1-E2)) assert abs(E1 - E2) < tol ov = abs(psi1.overlap(psi2)) print("ov =", ov) assert abs(ov - 1) < tol
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) M = SpinChain(model_pars) state = ([[1 / np.sqrt(2), -1 / np.sqrt(2)]] * L ) # pointing in (-x)-direction state = ['up'] * L # pointing in (-z)-direction 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 } } 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, 'N_steps': 1} EngTEBD = tebd.Engine(psiTEBD, M, TEBD_params) for i in range(30): EngTEBD.run() psi = eng.run() print(psi.norm) print(np.abs(psi.overlap(psiTEBD) - 1)) #This test fails assert (abs(abs(psi.overlap(psiTEBD)) - 1) < 1e-2)
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.TwoSiteDMRGEngine(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 benchmark_DMRG(max_chi=200, use_Sz=False): print("use_Sz = ", use_Sz) # S = 1 Heisenberg chain model_params = { # https://tenpy.readthedocs.io/en/latest/reference/tenpy.models.spins.SpinModel.html#cfg-config-SpinModel 'L': 100, 'S': 1, 'Jx': 1, 'Jy': 1, 'Jz': 1, 'hz': 0., 'bc_MPS': 'finite', 'conserve': 'Sz' if use_Sz else None, } M = SpinChain(model_params) psi = MPS.from_lat_product_state( M.lat, [['up'], ['down']]) # start from Neel state dmrg_params = { # https://tenpy.readthedocs.io/en/latest/reference/tenpy.algorithms.dmrg.TwoSiteDMRGEngine.html#cfg-config-TwoSiteDMRGEngine 'trunc_params': { 'chi_max': None, # set by chi_list below 'svd_min': 1.e-14, # discard any singular values smaller than this }, 'chi_list': { # ramp-up the bond dimension with (sweep: max_chi) pairs 0: 10, 1: 20, 2: 100, 3: max_chi, # after the 3rd sweep, use the full bond dimension # alternatively, directly set the `chi_max`. }, 'N_sweeps_check': 1, 'min_sweeps': 5, 'max_sweeps': 5, # explicitly fix the number of sweeps 'mixer': None, # no subspace expansion 'diag_method': 'lanczos', 'lanczos_params': { # https://tenpy.readthedocs.io/en/latest/reference/tenpy.linalg.lanczos.LanczosGroundState.html#cfg-config-Lanczos 'N_max': 3, # fix the number of Lanczos iterations: the number of `matvec` calls 'N_min': 3, 'N_cache': 20, # keep the states during Lanczos in memory 'reortho': False, }, } optimization.set_level(3) # disables a few consistency checks eng = dmrg.TwoSiteDMRGEngine(psi, M, dmrg_params) t0_proc = time.process_time() t0_wall = time.time() eng.run() proc_time = time.process_time() - t0_proc wall_time = time.time() - t0_wall print("process time: {0:.1f}s, wallclock time: {1:.1f}s".format( proc_time, wall_time)) return proc_time, wall_time
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 = { 'verbose': 2, '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.Engine(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() psi_ED = ED.groundstate() Etebd = np.sum(M.bond_energies(psi)) Eexact = np.min(ED.E) print("E_TEBD={Etebd:.14f} vs E_exact={Eex:.14f}".format(Etebd=Etebd, Eex=Eexact)) assert (abs((Etebd - Eexact) / Eexact) < 1.e-7) ov = npc.inner(psi_ED, ED.mps_to_full(psi), 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....
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.Engine(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 test_apply_mpo(bc_MPS): L = 4 g = 0.5 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 / np.sqrt(2), -1 / np.sqrt(2)]] * L ) # pointing in (-x)-direction psi = tenpy.networks.mps.MPS.from_product_state(M.lat.mps_sites(), state, bc=bc_MPS) H = M.calc_H_MPO() Eexp = H.expectation_value(psi) psi2 = apply_mpo(psi, H, {}) Eapply = psi2.overlap(psi) #The following norm is false. Don't know how to avoid this due to guessed Svalues print(psi2.norm) if bc_MPS == 'infinite': Eapply /= L assert np.abs(Eexp - Eapply) < 1e-5
def test_svd_two_theta(bc_MPS): L = 4 g = 0.5 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 / np.sqrt(2), -1 / np.sqrt(2)], [1 / np.sqrt(2), 1 / np.sqrt(2)]] * L)[:L] # pointing in (-x)-direction psi = tenpy.networks.mps.MPS.from_product_state(M.lat.mps_sites(), state, bc=bc_MPS) psi2 = psi.copy() for i in range(L if bc_MPS == 'infinite' else L - 1): # test for every non trivial bond svd_two_site(i, psi, {}) assert (np.abs(psi2.norm - 1) < 1e-5) assert (np.abs(psi2.overlap(psi) - 1) < 1e-5)
def test_apply_mpo(): bc_MPS = "finite" # NOTE: overlap doesn't work for calculating the energy (density) in infinite systems! # energy is extensive, overlap exponential.... L = 5 g = 0.5 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 / np.sqrt(2), -1 / np.sqrt(2)]] * L ) # pointing in (-x)-direction psi = tenpy.networks.mps.MPS.from_product_state(M.lat.mps_sites(), state, bc=bc_MPS) H = M.H_MPO Eexp = H.expectation_value(psi) psi2 = apply_mpo(H, psi, {}) Eapply = psi2.overlap(psi) assert abs(Eexp - Eapply) < 1e-5
def run(Jzs): L = 2 bc = 'infinite' model_params = dict(L=L, Jx=1., Jy=1., Jz=1., bc_MPS=bc, conserve='Sz', verbose=0) chi = 300 dmrg_params = dict(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=True) # TODO: mixer? M = SpinChain(model_params) psi = MPS.from_product_state(M.lat.mps_sites(), [1, 0] * (L // 2), bc) # B = np.zeros([2, 2, 2]) # B[0, 0, 0] = B[1, 1, 1] = 1. # psi = MPS.from_Bflat(M.lat.mps_sites(), [B]*L, bc=bc) 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) # # psi = MPS.from_product_state(M.lat.mps_sites(), [1, 1]*(L//2), bc) # B = np.zeros([2, 2, 2]) # B[0, 0, 0] = B[1, 1, 1] = 1. # psi = MPS.from_Bflat(M.lat.mps_sites(), [B]*L, bc=bc) run_DMRG(psi, M, dmrg_params) if bc == 'infinite': # T = TransferMatrix(psi, psi, charge_sector=None) # E, V = T.eigenvectors(4, which='LM') # chi = psi.chi[0] # print V[0].to_ndarray().reshape([chi, chi])[:5, :5] * chi**0.5 # if len(V) > 1: # print V[1].to_ndarray().reshape([chi, chi])[:5, :5] * chi**0.5 # print "chi:", psi.chi # print "eigenvalues transfermatrix:", E # print "norm_test:", psi.norm_test() corr_length.append( psi.correlation_length(charge_sector=0, tol_ev0=1.e-3)) print("corr. length", corr_length[-1]) print("corr. fct.", psi.correlation_function('Sz', 'Sz', sites1=[0], sites2=6)) print("<Sz>", psi.expectation_value('Sz')) else: print(psi.correlation_function('Sz', 'Sz')) 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