def test_heisenberg(self, n, l, gap): ham = MPO_ham_heis(n) dmrg = DMRG2(ham) dmrg.solve() gl = gap // 2 gr = gap // 2 + gap % 2 m = n // 2 sysa = range(m - l - gl, m - gl) sysb = range(m + gr, m + l + gr) assert max(sysa) + gap + 1 == min(sysb) ln = dmrg.state.logneg_subsys(sysa, sysb, approx_spectral_opts={'bsz': 16}, verbosity=2) # exact lne = logneg_subsys(groundstate(ham_heis(n, cyclic=False)), [2] * n, sysa, sysb) assert_allclose(lne, ln, rtol=0.1, atol=0.1)
def test_half_filling_groundstate(self): H = qu.ham_hubbard_hardcore(8, t=0.5, V=1.0, mu=1.0) gs = qu.groundstate(H) dims = [2] * 8 cn = qu.num(2) ens = [qu.expec(cn, qu.ptr(gs, dims, i)) for i in range(8)] for en in ens: assert en == pytest.approx(0.5, rel=1e-6)
def test_spin_half_double_space(self, sz): prj = qu.zspin_projector(5, sz) h = qu.ham_heis(5) h0 = prj.T @ h @ prj v0s = qu.eigvecsh(h0) for v0 in v0s.T: vf = prj @ v0.T prjv = vf @ vf.H # Check reconstructed full eigenvectors commute with full ham assert_allclose(prjv @ h, h @ prjv, atol=1e-13) if sz == 0: # Groundstate must be in most symmetric subspace gs = qu.groundstate(h) gs0 = prj @ v0s[:, 0] assert_allclose(qu.expec(gs, gs0), 1.0) assert_allclose(qu.expec(h, gs0), qu.expec(h, gs))
def test_works(self, sz): prj = zspin_projector(4, sz) h = ham_heis(4) h0 = prj @ h @ prj.H v0s = eigvecs(h0) for v0 in v0s.T: vf = prj.H @ v0.T prjv = vf @ vf.H # Check reconstructed full eigenvectors commute with full ham assert_allclose(prjv @ h, h @ prjv, atol=1e-13) if sz == 0: # Groundstate must be in most symmetric subspace gs = groundstate(h) gs0 = prj .H @ v0s[:, 0] assert_allclose(expec(gs, gs0), 1.0) assert_allclose(expec(h, gs0), expec(h, gs))
def test_works(self, sz): prj = qu.zspin_projector(4, sz) h = qu.ham_heis(4) h0 = prj.T @ h @ prj v0s = qu.eigvecsh(h0) for i in range(v0s.shape[1]): v0 = v0s[:, [i]] vf = prj @ v0 prjv = vf @ vf.H # Check reconstructed full eigenvectors commute with full ham assert_allclose(prjv @ h, h @ prjv, atol=1e-13) if sz == 0: # Groundstate must be in most symmetric subspace gs = qu.groundstate(h) gs0 = prj @ v0s[:, [0]] assert_allclose(qu.expec(gs, gs0), 1.0) assert_allclose(qu.expec(h, gs0), qu.expec(h, gs))
def test_ham_heis_2(self): h = qu.ham_heis(2, cyclic=False) evals = qu.eigvalsh(h) assert_allclose(evals, [-0.75, 0.25, 0.25, 0.25]) gs = qu.groundstate(h) assert_allclose(qu.expec(gs, qu.singlet()), 1.)
def test_groundstate(self, mat_herm_dense, backend): u, a = mat_herm_dense gs = qu.groundstate(a, backend=backend) assert_allclose(abs(u[:, [3]].H @ gs), 1.)
U3_gates(i, gate_round=depth) return circuit circ_with_U3 = my_circuit(4, 4) ran_circ = qtn.circuit_gen.circ_ansatz_1D_rand(4, 4) # circ_with_U3.psi.graph(color=['PSI0'] + [f'ROUND_{i}' for i in range(5)]) V = circ_with_U3 H_0 = Ham V1 = ran_circ gs = qu.groundstate(H_0) target = qtn.Dense1D(gs) def negative_overlap(psi, target): a = - abs((psi.H & target).contract(all, optimize='auto-hq')) return a V.psi.graph(color=['H', 'CNOT', 'S', 'U3']) (V.psi.H & target).graph() target.graph() print(gs) print(evec_min)
def test_thermal_state_cold(self): full = ham_j1j2(4, j2=0.1253) rhoth = thermal_state(full, 100) gs = groundstate(full) assert_allclose(tr(gs.H @ rhoth @ gs), 1.0, rtol=1e-4)
def test_ham_heis_2(self): h = ham_heis(2, cyclic=False) evals = eigvals(h) assert_allclose(evals, [-0.75, 0.25, 0.25, 0.25]) gs = groundstate(h) assert_allclose(expec(gs, singlet()), 1.)
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()
def ising(n, jz=1.0, h=0.0, **ham_opts): # generate Ising Hamiltonian with X and Z fields Z = np.zeros((2**(n), 2**(n)), dtype=complex) return qu.ham_heis(n, j=(0, 0, jz), b=(h, 0, h), cyclic=False, **ham_opts) # %% n = 8 # the number of qubits d = 1 # the circuit depth beta = 31 # beta in Metropolis algorithm Ham = ising(n, jz=1.0, h=0.5 * 1) # the Hamiltonian used # Ham = random_ham() for t in range(1): data = {} evals, evecs = la.eig(Ham) min_eval = (evals).min() # calculate groundstate eigenvalue evec_min = qu.groundstate(Ham) # calculate groundstate of Hamiltonian for a in range(1): qc = qcnewcircuit(n, d) operations = op_list.copy() op_copy = op_list.copy() E1 = 5 t0 = 0 E3 = 1 exec(f'E_{a} = np.array([])') exec(f't_{a} = np.array([])') exec(f'energy_{a} = np.array([])') for i in range(1000): qc_new = update_qc(n, depth=d) psi = qc_new.to_dense() E2 = 1 - qu.calc.fidelity(psi, evec_min) Energy = np.real(qu.core.expectation(psi, Ham))