def test_construct(self, cyclic, sparse, dh_dim, dh_dist): qu.ham_mbl(n=3, dh=3, cyclic=cyclic, sparse=sparse, dh_dim=dh_dim, dh_dist=dh_dist)
def test_eigh(self): H = qu.ham_mbl(6, dh=2.5) a_el, a_ev = qu.eigh(H, autoblock=False) el, ev = qu.eigh(H, autoblock=True) assert qu.norm(ev @ qu.ldmul(el, ev.H) - H, 'fro') < 1e-12 assert_allclose(a_el, el) assert_allclose(ev.H @ ev, np.eye(H.shape[0]), atol=1e-12)
def test_expm_slepc(self, expm_backend): ham = qu.ham_mbl(7, dh=0.5, sparse=True) psi = qu.rand_ket(2**7) evo_exact = qu.Evolution(psi, ham, method='solve') evo_slepc = qu.Evolution(psi, ham, method='expm', expm_backend=expm_backend) ts = np.linspace(0, 100, 6) for p1, p2 in zip(evo_exact.at_times(ts), evo_slepc.at_times(ts)): assert abs(qu.expec(p1, p2) - 1) < 1e-9
def test_non_trans_invar(self): n = 10 tf = 1.0 p0 = qtn.MPS_rand_state(n, bond_dim=1) H = qtn.NNI_ham_mbl(n, dh=1.7, cyclic=False, seed=42) print(H) assert H.special_sites == {(i, i + 1) for i in range(n)} tebd = qtn.TEBD(p0, H) tebd.update_to(tf, tol=1e-3) p0d = p0.to_dense() Hd = qu.ham_mbl(n, dh=1.7, cyclic=False, seed=42, sparse=True) evo = qu.Evolution(p0d, Hd) evo.update_to(tf) assert qu.expec(tebd.pt.to_dense(), evo.pt) == pytest.approx(1.0)
def ham_mbl_pbc_complex(): L = 10 chi = 8 dtype = 'complex64' psi0 = qtn.MPS_rand_state(L, chi, cyclic=True, seed=42).astype(dtype) ham_opts = {'cyclic': True, 'dh': 0.7, 'dh_dim': 3, 'seed': 42} H = qtn.MPO_ham_mbl(L, **ham_opts).astype(dtype) def norm_fn(psi): factor = (psi.H & psi).contract(all, optimize='random-greedy') return psi * factor**-0.5 def loss_fn(psi, H): k, H, b = qtn.align_TN_1D(psi, H, psi.H) energy = (k & H & b).contract(all, optimize='random-greedy') return real(energy) en_ex = qu.groundenergy(qu.ham_mbl(L, sparse=True, **ham_opts)) return psi0, H, norm_fn, loss_fn, en_ex
def test_construct_qp(self, cyclic, sparse): qu.ham_mbl(n=3, dh=3, cyclic=cyclic, sparse=sparse, dh_dist='qp')
seed = int(1000000 * np.random.random()) int_flag = params.Int_flag t_tab = np.logspace(-1, 1.5, 200) if int_flag == 0: J_tab = (J, J, 0) else: J_tab = (J, J, J) P = qu.zspin_projector(N, sz=0) if dis_flag == 1: H_0 = qu.ham_mbl(N, W_i, J_tab, cyclic=False, dh_dist='qp', beta=0.721, seed=seed, sparse=True).real else: H_0 = qu.ham_mbl(N, W_i, J_tab, cyclic=False, seed=seed, sparse=True).real H_pre = P.T @ H_0 @ P psi_0 = qu.eigvecsh(H_pre, k=1, which='SA').ravel() if dis_flag == 1: H_1 = qu.ham_mbl(N, W, J_tab, cyclic=False,
def test_var_terms(self, cyclic): n = 8 Hd = qu.ham_mbl(n, dh=0.77, seed=42, cyclic=cyclic) Ht = qtn.MPO_ham_mbl(n, dh=0.77, seed=42, cyclic=cyclic).to_dense() assert_allclose(Hd, Ht)
def test_evo_timedep_adiabatic_with_callbacks(self, dop, linop, num_callbacks): # tests time dependent Evolution via an adiabatic sweep with: # a) no callbacks # b) 1 callback that accesses the time-dependent Hamiltonian # c) 2 callbacks where one access the Hamiltonian and one doesn't if num_callbacks > 0 and (dop or linop): # should implement this at some point return L = 6 T = 20 H1 = qu.ham_mbl(L, dh=1.0, seed=4, sparse=True) gs1 = qu.groundstate(H1) H2 = qu.ham_mbl(L, dh=1.0, seed=5, sparse=True) gs2 = qu.groundstate(H2) if linop: import scipy.sparse.linalg as spla H1 = spla.aslinearoperator(H1) H2 = spla.aslinearoperator(H2) # make sure two ground states are different assert qu.fidelity(gs1, gs2) < 0.5 # linearly interpolate from one ham to the other def ham(t): return (1 - t / T) * H1 + (t / T) * H2 if linop: assert isinstance(ham(0.3), spla.LinearOperator) if dop: p0 = qu.dop(gs1) else: p0 = gs1 if num_callbacks == 0: evo = qu.Evolution(p0, ham, progbar=True) else: def gs_overlap(t, pt, H): evals, evecs = eigs_scipy(H(t), k=1, which='SA') return np.abs(qu.dot(pt.T, qu.qu(evecs[:, 0])))**2 if num_callbacks == 1: compute = gs_overlap if num_callbacks == 2: def norm(t, pt): return qu.dot(pt.T, pt) compute = {'norm': norm, 'gs_overlap': gs_overlap} evo = qu.Evolution(p0, ham, compute=compute, progbar=True) evo.update_to(T) # final state should now overlap much more with second hamiltonian GS assert qu.fidelity(evo.pt, gs1) < 0.5 assert qu.fidelity(evo.pt, gs2) > 0.99 if num_callbacks == 1: gs_overlap_results = evo.results # check that we stayed in the ground state the whole time assert ((np.array(gs_overlap_results) - 1.0) < 1e-3).all() if num_callbacks == 2: norm_results = evo.results['norm'] gs_overlap_results = evo.results['gs_overlap'] # check that we stayed normalized the whole time assert ((np.array(norm_results) - 1.0) < 1e-3).all() # check that we stayed in the ground state the whole time assert ((np.array(gs_overlap_results) - 1.0) < 1e-3).all()
int_flag = 1 t_tab = np.logspace(-2, 1.5, 300) ### ETH ---> MBL ### J_ETH = (J, J, J) P = qu.zspin_projector(N, sz=0) H_ETH = P.T @ qu.ham_heis(N, J_ETH, sparse=True, cyclic=False) @ P Psi_ETH = qu.eigvecsh(H_ETH, k=1, which='SA') J_evo1 = (0.0, 0.0, 0.0) H_evo1 = P.T @ qu.ham_mbl(N, W, J_evo1, cyclic=False, dh_dist='qp', beta=0.721, seed=seed, sparse=True).real @ P compute = { 'time': lambda t, p: t, 'losch': lambda t, p: qu.fidelity(Psi_ETH, p) } evo_ETH = qu.Evolution(Psi_ETH, H_evo1, compute=compute, method='expm') for t in evo_ETH.at_times(t_tab): continue TS = evo_ETH.results['time'] LOSCH_ETH = np.array(-np.log(evo_ETH.results['losch'])) / N