def test_index_conversion(): from tenpy.networks.mps import MPS s = site.SpinHalfSite(conserve=None) state1 = [[[0, 1]]] # 0=up, 1=down for order in ["snake", "default"]: lat = lattice.Honeycomb(2, 3, [s, s], order=order, bc_MPS="finite") psi1 = MPS.from_lat_product_state(lat, state1) sz1_mps = psi1.expectation_value("Sigmaz") sz1_lat = lat.mps2lat_values(sz1_mps) npt.assert_equal(sz1_lat[:, :, 0], +1.) npt.assert_equal(sz1_lat[:, :, 1], -1.) # and a random state state2 = np.random.random(lat.shape + (2, )) psi2 = MPS.from_lat_product_state(lat, state2) sz2_mps = psi2.expectation_value("Sigmaz") sz2_lat = lat.mps2lat_values(sz2_mps) expect_sz2 = np.sum(state2**2 * np.array([1., -1]), axis=-1) npt.assert_equal(sz2_lat, expect_sz2)
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_HelicalLattice(): s = site.SpinHalfSite() honey = lattice.Honeycomb(2, 3, s, bc=['periodic', -1], bc_MPS='infinite', order='Cstyle') hel = lattice.HelicalLattice(honey, 2) strength = np.array([[1.5, 2.5, 1.5], [2.5, 1.5, 2.5]]) def assert_same(i1, j1, s1, ij2, s2): """check that coupling and multi_coupling agree up to sorting order""" assert len(i1) == len(ij2) sort1 = np.lexsort(np.stack([i1, j1])) sort2 = np.lexsort(ij2.T) for a, b in zip(sort1, sort2): assert (i1[a], j1[a]) == tuple(ij2[b]) assert s1[a] == s2[b] i, j, s = hel.possible_couplings(0, 1, [0, 0], strength) ijm, sm = hel.possible_multi_couplings([('X', [0, 0], 0), ('X', [0, 0], 1)], strength) assert np.all(i == [0, 2]) and np.all(j == [1, 3]) assert np.all(s == [1.5, 2.5]) assert_same(i, j, s, ijm, sm) i, j, s = hel.possible_couplings(0, 0, [1, 0], strength) ijm, sm = hel.possible_multi_couplings([('X', [0, 0], 0), ('X', [1, 0], 0)], strength) assert np.all(i == [0, 2]) and np.all(j == [6, 8]) assert np.all(s == [1.5, 2.5]) assert_same(i, j, s, ijm, sm) i, j, s = hel.possible_couplings(0, 0, [-1, 1], strength) assert np.all(i == [4, 6]) and np.all(j == [0, 2]) assert np.all(s == [2.5, 1.5]) # swapped! ijm, sm = hel.possible_multi_couplings([('X', [0, 0], 0), ('X', [-1, 1], 0)], strength) assert_same(i, j, s, ijm, sm) ijm, sm = hel.possible_multi_couplings([('X', [1, 0], 0), ('X', [0, 1], 0)], strength) assert_same(i, j, s, ijm, sm) # test that MPS.from_lat_product_state checks translation invariance p_state = [[['up', 'down'], ['down', 'down'], ['up', 'down']], [['down', 'down'], ['up', 'down'], ['down', 'down']]] psi = MPS.from_lat_product_state(hel, p_state) p_state[0][2] = ['down', 'down'] with pytest.raises(ValueError, match='.* not translation invariant .*'): psi = MPS.from_lat_product_state(hel, p_state)
def test_AKLT_finite(): L = 4 check_general_model(aklt.AKLTChain, {'L': L}, {}) M = aklt.AKLTChain({'L': L, 'bc_MPS': 'finite'}) psi = MPS.from_lat_product_state(M.lat, [['up'], ['down']]) eng = TwoSiteDMRGEngine( psi, M, {'trunc_params': { 'svd_min': 1.e-10, 'chi_max': 10 }}) E0, psi0 = eng.run() assert abs(E0 - (-2 / 3.) * (L - 1)) < 1.e-10 # note: if we view the system as spin-1/2 projected to spin-1, the first and last spin # are arbitrary. # if they are in a superposition, this will contribute at most another factor of 2 to chi. assert all([chi <= 4 for chi in psi0.chi])
def test_AKLT_infinite(): # switch to infinite L = 4 M = aklt.AKLTChain({'L': L, 'bc_MPS': 'infinite'}) psi = MPS.from_lat_product_state(M.lat, [['up'], ['down']]) eng = TwoSiteDMRGEngine( psi, M, { 'trunc_params': { 'svd_min': 1.e-10, 'chi_max': 10 }, 'N_sweeps_check': 1, 'mixer': False }) E0, psi0 = eng.run() assert abs(E0 - (-2 / 3.)) < 1.e-10 psi_aklt = M.psi_AKLT() assert abs(1. - abs(psi0.overlap(psi_aklt))) < 1.e-10
def test_mixed_hubbard(): """ compare the Hubbard model on a small square lattice in in real and mixed space """ Lx, Ly = 2, 3 t, U = 1., 10 chimax = 100 #real space model_params = dict(t=t, U=U, lattice='Square', Lx=Lx, Ly=Ly, bc_x='open', bc_y='cylinder', bc_MPS='finite') M = FermiHubbardModel(model_params) dmrg_params = { 'mixer': True, 'max_E_err': 1.e-12, 'max_S_err': 1.e-8, 'trunc_params': { 'chi_max': chimax, 'svd_min': 1.e-10 }, } product_state = [[['full'], ['empty'], ['full']], [['full'], ['empty'], ['empty']]] #yapf: disable psi = MPS.from_lat_product_state(M.lat, product_state) info = dmrg.run(psi, M, dmrg_params) E_real = info['E'] #measure Sz onsite and SpSm correlators Sz_real = M.lat.mps2lat_values(psi.expectation_value('Sz')) SpSm_real = M.lat.mps2lat_values(psi.correlation_function('Sp', 'Sm')[0, :]) #mixed space #implemented with two spinless fermion sites for up/down ! model_params = dict(t=t, U=U, Lx=Lx, Ly=Ly, bc_MPS='finite', conserve_k=True) M2 = HubbardMixedXKSquare(model_params) #initial product state with momentum 0 product_xk = [['full', 'full', 'full', 'empty', 'empty', 'empty'], ['full', 'full', 'empty', 'empty', 'empty', 'full']] psi_xk = MPS.from_lat_product_state(M2.lat, product_xk) info = dmrg.run(psi_xk, M2, dmrg_params) # the main work... E_mixed = info['E'] #measure Sz onsite and SpSm correlators Sz_mixed = np.zeros((Lx, Ly), dtype='complex') SpSm_mixed = np.zeros((Lx, Ly), dtype='complex') Sp = np.array([[0, 1], [0, 0]]) Sm = np.array([[0, 0], [1, 0]]) Sz = np.array([[1, 0], [0, -1]]) * 0.5 for i in range(Lx): for j in range(Ly): terms_Sz = M2.real_to_mixed_onsite(Sz, (i, j)) Sz_mixed[i, j] = psi_xk.expectation_value_terms_sum(terms_Sz)[0] terms_SpSm = M2.real_to_mixed_two_site(Sp, (0, 0), Sm, (i, j)) SpSm_mixed[i, j] = psi_xk.expectation_value_terms_sum(terms_SpSm)[0] assert np.abs(E_real - E_mixed) < 1e-7 assert np.all(np.abs(Sz_real - Sz_mixed) < 1e-7) assert np.all(np.abs(SpSm_real - SpSm_mixed) < 1e-7)
def test_mixed_spinless(): """ compare a small system of spinless fermions in real and mixed space """ Lx, Ly = 2, 4 J, V = 1., 10 chimax = 100 #real space model_params = dict(J=J, V=V, lattice='Square', Lx=Lx, Ly=Ly, bc_x='open', bc_y='cylinder', bc_MPS='finite') M = FermionModel(model_params) dmrg_params = { 'mixer': True, 'max_E_err': 1.e-12, 'max_S_err': 1.e-8, 'trunc_params': { 'chi_max': chimax, 'svd_min': 1.e-10 }, } product_state = [[['full'], ['empty'], ['full'], ['empty']], [['full'], ['empty'], ['full'], ['empty']]] # half filling psi = MPS.from_lat_product_state(M.lat, product_state) info = dmrg.run(psi, M, dmrg_params) E_real = info['E'] #measure particle number and Cd C correlators N_real = M.lat.mps2lat_values(psi.expectation_value('N')) CdC_real = M.lat.mps2lat_values(psi.correlation_function('Cd', 'C')[0, :]) #mixed space model_params = dict(t=J, V=V, Lx=Lx, Ly=Ly, bc_MPS='finite', conserve_k=True) M = SpinlessMixedXKSquare(model_params) #initial product state with momentum 0 product_xk = [['full', 'empty', 'full', 'empty'], ['full', 'empty', 'full', 'empty']] psi_xk = MPS.from_lat_product_state(M.lat, product_xk) info = dmrg.run(psi_xk, M, dmrg_params) # the main work... E_mixed = info['E'] #measure particle number and Cd C correlators N_mixed = np.zeros((Lx, Ly), dtype='complex') CdC_mixed = np.zeros((Lx, Ly), dtype='complex') for i in range(Lx): for j in range(Ly): terms_N = M.real_to_mixed_onsite([[1]], (i, j)) N_mixed[i, j] = psi_xk.expectation_value_terms_sum(terms_N)[0] terms_CdC = M.real_to_mixed_correlations_any(['Cd', 'C'], [(1., [0, 0])], [(0, 0), (i, j)]) CdC_mixed[i, j] = psi_xk.expectation_value_terms_sum(terms_CdC)[0] assert np.abs(E_real - E_mixed) < 1e-10 assert np.all(np.abs(N_real - N_mixed) < 1e-10) assert np.all(np.abs(CdC_real - CdC_mixed) < 1e-10)