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_model_H_conversion(L=6): bc = 'finite' model_params = {'L': L, 'hz': np.random.random([L]), 'bc_MPS': bc} m = XXZChain(model_params) # can we run the conversion? # conversion from bond to MPO in NearestNeighborModel H_MPO = m.calc_H_MPO_from_bond() # conversion from MPO to bond in MPOModel H_bond = m.calc_H_bond_from_MPO() # compare: did we get the correct result? ED = ExactDiag(m) ED.build_full_H_from_bonds() H0 = ED.full_H # this should be correct ED.full_H = None m.H_MPO = H_MPO ED.build_full_H_from_mpo() full_H_mpo = ED.full_H # the one generated by NearstNeighborModel.calc_H_MPO_from_bond() print("npc.norm(H0 - full_H_mpo) = ", npc.norm(H0 - full_H_mpo)) assert npc.norm(H0 - full_H_mpo) < 1.e-14 # round off errors on order of 1.e-15 m.H_bond = H_bond ED.full_H = None ED.build_full_H_from_bonds() full_H_bond = ED.full_H # the one generated by NearstNeighborModel.calc_H_MPO_from_bond() print("npc.norm(H0 - full_H_bond) = ", npc.norm(H0 - full_H_bond)) assert npc.norm( H0 - full_H_bond) < 1.e-14 # round off errors on order of 1.e-15
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_exact_diagonalization(L, Jz): xxz_pars = dict(L=L, Jxx=1., Jz=Jz, hz=0.0, bc_MPS='finite') M = XXZChain(xxz_pars) product_state = ["up", "down"] * (xxz_pars['L'] // 2) # this selects a charge sector! psi_DMRG = MPS.from_product_state(M.lat.mps_sites(), product_state) charge_sector = psi_DMRG.get_total_charge(True) # ED charge sector should match ED = ExactDiag(M, charge_sector=charge_sector, max_size=2.e6) ED.build_full_H_from_mpo() # ED.build_full_H_from_bonds() # whatever you prefer print("start diagonalization") ED.full_diagonalization() # the expensive part for large L E0_ED, psi_ED = ED.groundstate() # return the ground state print("psi_ED =", psi_ED) print("run DMRG") dmrg.run(psi_DMRG, M, {'verbose': 0}) # modifies psi_DMRG in place! # first way to compare ED with DMRG: convert MPS to ED vector psi_DMRG_full = ED.mps_to_full(psi_DMRG) print("psi_DMRG_full =", psi_DMRG_full) ov = npc.inner(psi_ED, psi_DMRG_full, axes='range', do_conj=True) print("<psi_ED|psi_DMRG_full> =", ov) assert (abs(abs(ov) - 1.) < 1.e-13) # second way: convert ED vector to MPS psi_ED_mps = ED.full_to_mps(psi_ED) ov2 = psi_ED_mps.overlap(psi_DMRG) print("<psi_ED_mps|psi_DMRG> =", ov2) assert (abs(abs(ov2) - 1.) < 1.e-13) assert (abs(ov - ov2) < 1.e-13) # -> advantage: expectation_value etc. of MPS are available! print("<Sz> =", psi_ED_mps.expectation_value('Sz'))
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 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 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_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_model_plus_hc(L=6): params = dict(x=0.5, y=0.25, L=L, bc_MPS='finite', conserve=None) m1 = MyMod(params) m2 = MyMod(params) params['explicit_plus_hc'] = True m3 = MyMod(params) nu = np.random.random(L) m1.add_onsite(nu, 0, 'Sp', plus_hc=True) m2.add_onsite(nu, 0, 'Sp', plus_hc=True) m3.add_onsite(nu, 0, 'Sp', plus_hc=True) t = np.random.random(L - 1) m1.add_coupling(t, 0, 'Sp', 0, 'Sm', 1) m1.add_coupling(t, 0, 'Sp', 0, 'Sm', -1) m2.add_coupling(t, 0, 'Sp', 0, 'Sm', 1, plus_hc=True) m3.add_coupling(t, 0, 'Sp', 0, 'Sm', 1, plus_hc=True) t2 = np.random.random(L - 1) m1.add_multi_coupling(t2, [('Sp', [+1], 0), ('Sm', [0], 0), ('Sz', [0], 0)]) m1.add_multi_coupling(t2, [('Sz', [0], 0), ('Sp', [0], 0), ('Sm', [+1], 0)]) m2.add_multi_coupling(t2, [('Sp', [+1], 0), ('Sm', [0], 0), ('Sz', [0], 0)], plus_hc=True) m3.add_multi_coupling(t2, [('Sp', [+1], 0), ('Sm', [0], 0), ('Sz', [0], 0)], plus_hc=True) for m in [m1, m2, m3]: # added extra terms: need to re-calculate H_bond and H_MPO m.H_bond = m.calc_H_bond() m.H_MPO = m.calc_H_MPO() assert m1.H_MPO.is_hermitian() assert m2.H_MPO.is_hermitian() assert not m3.H_MPO.is_hermitian() assert m3.H_MPO.chi[ 3] == m3.H_MPO.chi[2] - 1 # check for smaller MPO bond dimension ED1 = ExactDiag(m1) ED2 = ExactDiag(m2) ED3 = ExactDiag(m3) for ED in [ED1, ED2, ED3]: ED.build_full_H_from_bonds() assert ED1.full_H == ED2.full_H assert ED1.full_H == ED3.full_H for ED in [ED1, ED2, ED3]: ED.full_H = None ED.build_full_H_from_mpo() assert ED1.full_H == ED2.full_H assert ED1.full_H == ED3.full_H
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 to_dense(self): self.tpmpo.IdL[0] = 0 self.tpmpo.IdR[-1] = 0 #How is this my job? ed = ExactDiag.from_H_mpo(self.tpmpo) ed.build_full_H_from_mpo() nda = ed.full_H.to_ndarray() if nda.shape[-1] == 1: nda = nda[:, :, 0] return nda
def compare(m1, m2, m3, use_bonds=True): for m in [m1, m2, m3]: # added extra terms: need to re-calculate H_bond and H_MPO if use_bonds: m.H_bond = m.calc_H_bond() m.H_MPO = m.calc_H_MPO() assert m1.H_MPO.is_hermitian() assert m2.H_MPO.is_hermitian() assert not m3.H_MPO.is_hermitian() assert m3.H_MPO.chi[ 3] == m3.H_MPO.chi[2] - 1 # check for smaller MPO bond dimension ED1 = ExactDiag(m1) ED2 = ExactDiag(m2) ED3 = ExactDiag(m3) if use_bonds: for ED in [ED1, ED2, ED3]: ED.build_full_H_from_bonds() assert ED1.full_H == ED2.full_H assert ED1.full_H == ED3.full_H for ED in [ED1, ED2, ED3]: ED.full_H = None ED.build_full_H_from_mpo() assert ED1.full_H == ED2.full_H assert ED1.full_H == ED3.full_H
def test_CouplingMPOModel_group(): m = MyMod(dict(x=0.5, L=5, bc_MPS='finite')) assert m.H_MPO.max_range == 1 # test grouping sites ED = ExactDiag(m) # ED.build_full_H_from_mpo() ED.build_full_H_from_bonds() m.group_sites(n=2) assert m.H_MPO.max_range == 1 ED_gr = ExactDiag(m) ED_gr.build_full_H_from_mpo() H = ED.full_H.split_legs().to_ndarray() Hgr = ED_gr.full_H.split_legs() Hgr.idrop_labels() Hgr = Hgr.split_legs().to_ndarray() assert np.linalg.norm(H - Hgr) == 0 ED_gr.full_H = None ED_gr.build_full_H_from_bonds() Hgr = ED_gr.full_H.split_legs() Hgr.idrop_labels() Hgr = Hgr.split_legs().to_ndarray() assert np.linalg.norm(H - Hgr) == 0
def test_ED(): # just quickly check that it runs without errors for a small system xxz_pars = dict(L=4, Jxx=1., Jz=1., hz=0.0, bc_MPS='finite') M = XXZChain(xxz_pars) ED = ExactDiag(M) ED.build_full_H_from_mpo() H, ED.full_H = ED.full_H, None ED.build_full_H_from_bonds() H2 = ED.full_H assert (npc.norm(H - H2, np.inf) < 1.e-14) ED.full_diagonalization() E, psi = ED.groundstate() print("select charge_sector =", psi.qtotal) assert np.all(psi.qtotal == [0]) E_sec2, psi_sec2 = ED.groundstate([2]) assert np.all(psi_sec2.qtotal == [2]) ED2 = ExactDiag(M, psi.qtotal) ED2.build_full_H_from_mpo() ED2.full_diagonalization() E2, psi2 = ED2.groundstate() full_psi2 = psi.zeros_like() full_psi2[ED2._mask] = psi2 ov = npc.inner(psi, full_psi2, 'range', do_conj=True) print("overlab <psi | psi2> = 1. -", 1. - ov) assert (abs(abs(ov) - 1.) < 1.e-15) # starting from a random guess in the correct charge sector, # check if we can also do lanczos. np.random.seed(12345) psi3 = npc.Array.from_func(np.random.random, psi2.legs, qtotal=psi2.qtotal, shape_kw='size') E0, psi3, N = lanczos(ED2, psi3) print("Lanczos E0 =", E0) ov = npc.inner(psi3, psi2, 'range', do_conj=True) print("overlab <psi2 | psi3> = 1. -", 1. - ov) assert (abs(abs(ov) - 1.) < 1.e-15) ED3 = ExactDiag.from_H_mpo(M.H_MPO) ED3.build_full_H_from_mpo() assert npc.norm(ED3.full_H - H, np.inf) < 1.e-14
def test_CouplingMPOModel_group(): class MyMod(model.CouplingMPOModel, model.NearestNeighborModel): def __init__(self, model_params): model.CouplingMPOModel.__init__(self, model_params) def init_sites(self, model_params): return tenpy.networks.site.SpinHalfSite('parity') def init_terms(self, model_params): x = get_parameter(model_params, 'x', 1., self.name) self.add_onsite_term(0.25, 0, 'Sz') self.add_onsite_term(0.25, 4, 'Sz') self.add_coupling_term(x, 0, 1, 'Sx', 'Sx') self.add_coupling_term(2. * x, 1, 2, 'Sy', 'Sy') self.add_coupling_term(3. * x, 3, 4, 'Sy', 'Sy') m = MyMod(dict(x=0.5, L=5, bc_MPS='finite')) m.test_sanity() for Hb in m.H_bond: if Hb is not None: Hb.test_sanity() # test grouping sites ED = ExactDiag(m) # ED.build_full_H_from_mpo() ED.build_full_H_from_bonds() m.group_sites(n=2) ED_gr = ExactDiag(m) ED_gr.build_full_H_from_mpo() H = ED.full_H.split_legs().to_ndarray() Hgr = ED_gr.full_H.split_legs() Hgr.idrop_labels() Hgr = Hgr.split_legs().to_ndarray() assert np.linalg.norm(H - Hgr) == 0 ED_gr.full_H = None ED_gr.build_full_H_from_bonds() Hgr = ED_gr.full_H.split_legs() Hgr.idrop_labels() Hgr = Hgr.split_legs().to_ndarray() assert np.linalg.norm(H - Hgr) == 0
def test_CouplingMPOModel_group(): m1 = MyMod(dict(x=0.5, L=5, bc_MPS='finite')) model_params = {'L': 6, 'hz': np.random.random([6]), 'bc_MPS': 'finite'} m2 = XXZChain(model_params) for m in [m1, m2]: print("model = ", m) assert m.H_MPO.max_range == 1 # test grouping sites ED = ExactDiag(m) # ED.build_full_H_from_mpo() ED.build_full_H_from_bonds() m.group_sites(n=2) assert m.H_MPO.max_range == 1 ED_gr = ExactDiag(m) ED_gr.build_full_H_from_mpo() H = ED.full_H.split_legs().to_ndarray() Hgr = ED_gr.full_H.split_legs() Hgr.idrop_labels() Hgr = Hgr.split_legs().to_ndarray() assert np.linalg.norm(H - Hgr) < 1.e-14 ED_gr.full_H = None ED_gr.build_full_H_from_bonds() Hgr = ED_gr.full_H.split_legs() Hgr.idrop_labels() Hgr = Hgr.split_legs().to_ndarray() assert np.linalg.norm(H - Hgr) < 1.e-14
def test_SpinChainNNN_comparison(): model_pars = { 'hz': 0.5, 'Jx': -2., 'Jy': -2., 'Jz': 0.4, 'L': 3, 'conserve': 'Sz', 'bc_MPS': 'finite' } M1 = spins_nnn.SpinChainNNN(model_pars.copy()) model_pars['L'] = 2 * model_pars['L'] M2 = spins_nnn.SpinChainNNN2(model_pars.copy()) M2.group_sites(2) M2nn = NearestNeighborModel.from_MPOModel(M2) ED1 = ExactDiag(M1) ED2 = ExactDiag(M2) ED2nn = ExactDiag(M2nn) ED1.build_full_H_from_mpo() ED2.build_full_H_from_mpo() ED2nn.build_full_H_from_bonds() assert (ED1.full_H - ED2.full_H).norm() < 1.e-13 assert (ED1.full_H - ED2nn.full_H).norm() < 1.e-13
Sorry that this is not well documented! ED is meant to be used for debugging only ;) """ # Copyright 2018 TeNPy Developers import tenpy.linalg.np_conserved as npc from tenpy.models.xxz_chain import XXZChain from tenpy.networks.mps import MPS from tenpy.algorithms.exact_diag import ExactDiag from tenpy.algorithms.dmrg import run as run_DMRG xxz_pars = dict(L=4, Jxx=1., Jz=1., hz=0.0, bc_MPS='finite') M = XXZChain(xxz_pars) ED = ExactDiag(M, [0]) ED.build_full_H_from_mpo() # ED.build_full_H_from_bonds() # whatever you prefer print("start diagonalization") ED.full_diagonalization() psi_ED = ED.groundstate() print("psi_ED =", psi_ED) print("start DMRG") product_state = [0, 1] * (xxz_pars['L'] // 2) # this selects a charge sector! psi_DMRG = MPS.from_product_state(M.lat.mps_sites(), product_state) res = run_DMRG(psi_DMRG, M, {'verbose': 0}) # first way to compare ED with DMRG: convert MPS to ED vector psi_DMRG_full = ED.mps_to_full(psi_DMRG) print("psi_DMRG_full =", psi_DMRG_full)