def test_trotter_hamiltonian_make_compatible_repeating(nqubits): """Check ``make_compatible`` when first target is repeated in parts.""" h0target = X(nqubits) h0 = X(nqubits, trotter=True) term = TFIM(2, numpy=True) parts = [{(0, i): term} for i in range(1, nqubits)] parts.extend(({(i, 0): term} for i in range(1, nqubits))) h1 = TrotterHamiltonian(*parts) h0c = h1.make_compatible(h0) assert not h1.is_compatible(h0) assert h1.is_compatible(h0c) np.testing.assert_allclose(h0c.matrix, h0target.matrix)
def test_trotter_hamiltonian_make_compatible_simple(): """Test ``make_compatible`` on a simple 3-qubit example.""" h0target = X(3) h0 = X(3, trotter=True) term1 = Y(1, numpy=True) term2 = TFIM(2, numpy=True) parts = [{(0, 1): term2, (1, 2): term2, (0, 2): term2, (2, ): term1}] h1 = TrotterHamiltonian(*parts) h0c = h1.make_compatible(h0) assert not h1.is_compatible(h0) assert h1.is_compatible(h0c) np.testing.assert_allclose(h0c.matrix, h0target.matrix)
def test_from_symbolic_application_hamiltonian(): """Check ``from_symbolic`` for a specific four-qubit Hamiltonian.""" import sympy z1, z2, z3, z4 = sympy.symbols("z1 z2 z3 z4") symmap = {z: (i, matrices.Z) for i, z in enumerate([z1, z2, z3, z4])} symham = (z1 * z2 - 0.5 * z1 * z3 + 2 * z2 * z3 + 0.35 * z2 + 0.25 * z3 * z4 + 0.5 * z3 + z4 - z1) # Check that Trotter dense matrix agrees will full Hamiltonian matrix fham = Hamiltonian.from_symbolic(symham, symmap) tham = TrotterHamiltonian.from_symbolic(symham, symmap) np.testing.assert_allclose(tham.dense.matrix, fham.matrix) # Check that no one-qubit terms exist in the Trotter Hamiltonian # (this means that merging was successful) first_targets = set() for part in tham.parts: for targets, term in part.items(): first_targets.add(targets[0]) assert len(targets) == 2 assert term.nqubits == 2 assert first_targets == set(range(4)) # Check making an ``X`` Hamiltonian compatible with ``tham`` xham = X(nqubits=4, trotter=True) cxham = tham.make_compatible(xham) assert not tham.is_compatible(xham) assert tham.is_compatible(cxham) np.testing.assert_allclose(xham.dense.matrix, cxham.dense.matrix)
def test_trotter_hamiltonian_make_compatible(nqubits): """Test that ``make_compatible`` method works for ``X`` Hamiltonian.""" h0target = X(nqubits) h0 = X(nqubits, trotter=True) h1 = XXZ(nqubits, delta=0.5, trotter=True) assert not h1.is_compatible(h0) assert not h0.is_compatible(h1) np.testing.assert_allclose(h0.matrix, h0target.matrix) h0c = h1.make_compatible(h0) assert not h1.is_compatible(h0) assert h1.is_compatible(h0c) assert h0c.is_compatible(h1) np.testing.assert_allclose(h0.matrix, h0target.matrix) np.testing.assert_allclose(h0c.matrix, h0target.matrix) # for coverage h0c = h1.make_compatible(h0c) assert not h1.is_compatible("test") h2 = XXZ(nqubits, delta=0.5, trotter=True) h2.parts[0].pop((0, 1)) assert not h1.is_compatible(h2)
def test_trotter_hamiltonian_make_compatible_redundant(): """Test ``make_compatible`` with redudant two-qubit terms.""" h0 = X(2, trotter=True) target_matrix = h0.dense.matrix.numpy() target_matrix = np.kron(target_matrix, np.eye(2, dtype=target_matrix.dtype)) parts = [{(0, 1, 2): TFIM(3, numpy=True)}] h1 = TrotterHamiltonian(*parts) h0c = h1.make_compatible(h0) assert not h1.is_compatible(h0) assert h1.is_compatible(h0c) np.testing.assert_allclose(h0c.matrix, target_matrix)
def test_x_hamiltonian_from_symbols(nqubits, trotter): """Check creating sum(X) Hamiltonian using sympy.""" import sympy x_symbols = sympy.symbols(" ".join((f"X{i}" for i in range(nqubits)))) symham = -sum(x_symbols) symmap = {x: (i, matrices.X) for i, x in enumerate(x_symbols)} target_matrix = X(nqubits).matrix if trotter: trotter_ham = TrotterHamiltonian.from_symbolic(symham, symmap) final_matrix = trotter_ham.dense.matrix else: full_ham = Hamiltonian.from_symbolic(symham, symmap) final_matrix = full_ham.matrix np.testing.assert_allclose(final_matrix, target_matrix)
def test_trotter_hamiltonian_make_compatible_onequbit_terms(): """Check ``make_compatible`` when the two-qubit Hamiltonian has one-qubit terms.""" term1 = Hamiltonian(1, matrices.Z, numpy=True) term2 = Hamiltonian(2, np.kron(matrices.Z, matrices.Z), numpy=True) terms = { (0, 1): term2, (0, 2): -0.5 * term2, (1, 2): 2 * term2, (1, ): 0.35 * term1, (2, 3): 0.25 * term2, (2, ): 0.5 * term1, (3, ): term1 } tham = TrotterHamiltonian.from_dictionary(terms) + 1.5 xham = X(nqubits=4, trotter=True) cxham = tham.make_compatible(xham) assert not tham.is_compatible(xham) assert tham.is_compatible(cxham) np.testing.assert_allclose(xham.dense.matrix, cxham.dense.matrix)
def test_trotter_hamiltonian_operation_errors(): """Test errors in ``TrotterHamiltonian`` addition and subtraction.""" # test addition with different number of parts h1 = TFIM(nqubits=5, trotter=True) term = TFIM(nqubits=2, numpy=True) h2 = TrotterHamiltonian({ (0, 1): term, (2, 3): term, (4, 0): term }, { (1, 2): term, (3, 4): term }) with pytest.raises(ValueError): h = h1 + h2 # test subtraction with incompatible parts h2 = TrotterHamiltonian({ (0, 1): term, (2, 3): term }, {(1, 2): term}, {(4, 0): term}) with pytest.raises(ValueError): h = h1 - h2 # test matmul with bad type with pytest.raises(NotImplementedError): s = h1 @ "abc" # test matmul with bad shape with pytest.raises(ValueError): s = h1 @ np.zeros((2, 2)) # test ``make_compatible`` with non-Trotter Hamiltonian with pytest.raises(TypeError): h2 = h1.make_compatible("test") # test ``make_compatible`` with interacting Hamiltonian with pytest.raises(NotImplementedError): h2 = h1.make_compatible(h2) # test ``make_compatible`` with insufficient two-qubit terms h3 = X(nqubits=7, trotter=True) with pytest.raises(ValueError): h3 = h1.make_compatible(h3)