def test_purification_TEBD(L=3): xxz_pars = dict(L=L, Jxx=1., Jz=3., hz=0., bc_MPS='finite') M = XXZChain(xxz_pars) for disent in [ None, 'backwards', 'min(None,last)-renyi', 'noise-norm', 'renyi-min(None,noise-renyi)' ]: psi = purification_mps.PurificationMPS.from_infiniteT( M.lat.mps_sites(), bc='finite') TEBD_params = { 'trunc_params': { 'chi_max': 16, 'svd_min': 1.e-8 }, 'disentangle': disent, 'dt': 0.1, 'verbose': 30, 'N_steps': 2 } eng = PurificationTEBD(psi, M, TEBD_params) eng.run() N = psi.expectation_value('Id') # check normalization : <1> =?= 1 npt.assert_array_almost_equal_nulp(N, np.ones([L]), 100) eng.run_imaginary(0.2) N = psi.expectation_value('Id') # check normalization : <1> =?= 1 npt.assert_array_almost_equal_nulp(N, np.ones([L]), 100) if disent == 'last-renyi': eng.run_imaginary(0.3) eng.disentangle_global()
def gen_disentangler_psi_singlet_test(site_P=spin_half, L=6, max_range=4): psi0, pairs_PQ = gen_disentangler_psi_singlets(site_P, L, max_range) psi0.test_sanity() print("pairs: P", pairs_PQ[0]) print("pairs: Q", pairs_PQ[1]) print("entanglement entropy: ", psi0.entanglement_entropy() / np.log(2.)) coords, mutinf_pq = psi0.mutinf_two_site(legs='pq') print("(i,j)=", [tuple(c) for c in coords]) print("PQ:", np.round(mutinf_pq / np.log(2), 3)) print("P: ", np.round(psi0.mutinf_two_site(legs='p')[1] / np.log(2), 3)) print("Q: ", np.round(psi0.mutinf_two_site(legs='q')[1] / np.log(2), 3)) M = XXZChain(dict(L=L)) tebd_pars = dict(trunc_params={'trunc_cut': 1.e-10}, disentangle='diag') eng = PurificationTEBD(psi0, M, tebd_pars) for i in range(L): eng.disentangle_global() print(psi0.entanglement_entropy() / np.log(2)) mutinf_Q = psi0.mutinf_two_site(legs='q')[1] print("P: ", np.round(psi0.mutinf_two_site(legs='p')[1] / np.log(2), 3)) print("Q: ", np.round(mutinf_Q / np.log(2), 3)) assert (np.all(mutinf_Q < 1.e-10))
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 test_renyi_disentangler(L=4, eps=1.e-15): xxz_pars = dict(L=L, Jxx=1., Jz=3., hz=0., bc_MPS='finite') M = XXZChain(xxz_pars) psi = purification_mps.PurificationMPS.from_infiniteT(M.lat.mps_sites(), bc='finite') eng = PurificationTEBD(psi, M, {'verbose': 30, 'disentangle': 'renyi'}) theta = eng.psi.get_theta(1, 2) print(theta[0, :, :, 0, :, :]) # find random unitary: SVD of random matix pleg = psi.sites[0].leg pipe = npc.LegPipe([pleg, pleg]) A = npc.Array.from_func_square(rmat.CUE, pipe).split_legs() A.iset_leg_labels(['p0', 'p1', 'p0*', 'p1*']) # Now we have unitary `A`, i.e. the optimal `U` should be `A^dagger`. theta = npc.tensordot(A, theta, axes=[['p0*', 'p1*'], ['p0', 'p1']]) U0 = npc.outer(npc.eye_like(theta, 'q0', labels=['q0', 'q0*']), npc.eye_like(theta, 'q1', labels=['q1', 'q1*'])) U = U0 Sold = np.inf for i in range(20): S, U = eng.used_disentangler.iter(theta, U) if i == 0: S_0 = S print("iteration {i:d}: S={S:.5f}, DS={DS:.4e} ".format(i=i, S=S, DS=Sold - S)) if abs(Sold - S) < eps: print("break: S converged down to {eps:.1e}".format(eps=eps)) break Sold, S = S, Sold else: print("maximum number of iterations reached") theta = npc.tensordot(U, theta, axes=[['q0*', 'q1*'], ['q0', 'q1']]) print("new theta = ") print(theta.itranspose(['vL', 'vR', 'p0', 'q0', 'p1', 'q1'])) print(theta[0, 0]) assert (S < S_0) # this should always be true... if S > 100 * eps: print("final S =", S) assert False # test of purification failed to find the optimum.
def test_canoncial_purification(L=6, charge_sector=0, eps=1.e-14): site = spin_half psi = purification_mps.PurificationMPS.from_infiniteT_canonical( [site] * L, [charge_sector]) psi.test_sanity() total_psi = psi.get_theta(0, L).take_slice(0, 'vL').take_slice(0, 'vR') total_psi.itranspose(['p' + str(i) for i in range(L)] + ['q' + str(i) for i in range(L)]) # note: don't `combine_legs`: it will permute the p legs differently than q due to charges total_psi_dense = total_psi.to_ndarray().reshape(2**L, 2**L) # now it should be diagonal diag = np.diag(total_psi_dense) assert np.all( np.abs(total_psi_dense - np.diag(diag) < eps)) # is it diagonal? # and the diagonal should be sqrt(L choose L//2) for states with fitting numbers pref = 1. / scipy.special.comb(L, L // 2 + charge_sector)**0.5 Q_p = site.leg.to_qflat()[:, 0] for i, entry in enumerate(diag): Q_i = sum([Q_p[int(b)] for b in format(i, 'b').zfill(L)]) if Q_i == charge_sector: assert abs(entry - pref) < eps else: assert abs(entry) < eps # and one quick test of TEBD xxz_pars = dict(L=L, Jxx=1., Jz=3., hz=0., bc_MPS='finite') M = XXZChain(xxz_pars) TEBD_params = { 'trunc_params': { 'chi_max': 16, 'svd_min': 1.e-8 }, 'disentangle': None, # 'renyi' should work as well, 'backwards' not. 'dt': 0.1, 'N_steps': 2 } eng = PurificationTEBD(psi, M, TEBD_params) eng.run_imaginary(0.2) eng.run() N = psi.expectation_value('Id') # check normalization : <1> =?= 1 npt.assert_array_almost_equal_nulp(N, np.ones([L]), 100)