def test_tfim_hamiltonian_from_symbols(nqubits, hamtype, calcterms): """Check creating TFIM Hamiltonian using sympy.""" if hamtype == "symbolic": from qibo.symbols import X, Z h = 0.5 symham = sum(Z(i) * Z(i + 1) for i in range(nqubits - 1)) symham += Z(0) * Z(nqubits - 1) symham += h * sum(X(i) for i in range(nqubits)) ham = hamiltonians.SymbolicHamiltonian(-symham) else: h = 0.5 z_symbols = sympy.symbols(" ".join((f"Z{i}" for i in range(nqubits)))) x_symbols = sympy.symbols(" ".join((f"X{i}" for i in range(nqubits)))) symham = sum(z_symbols[i] * z_symbols[i + 1] for i in range(nqubits - 1)) symham += z_symbols[0] * z_symbols[-1] symham += h * sum(x_symbols) symmap = {z: (i, matrices.Z) for i, z in enumerate(z_symbols)} symmap.update({x: (i, matrices.X) for i, x in enumerate(x_symbols)}) ham = hamiltonians.Hamiltonian.from_symbolic(-symham, symmap) if calcterms: _ = ham.terms final_matrix = ham.matrix target_matrix = hamiltonians.TFIM(nqubits, h=h).matrix K.assert_allclose(final_matrix, target_matrix)
def symbolic_tfim(nqubits, h=1.0): """Constructs symbolic Hamiltonian for TFIM.""" from qibo.symbols import Z, X sham = -sum(Z(i) * Z(i + 1) for i in range(nqubits - 1)) sham -= Z(0) * Z(nqubits - 1) sham -= h * sum(X(i) for i in range(nqubits)) return sham
def tsp_phaser(distance_matrix): num_cities = distance_matrix.shape[0] two_to_one = calculate_two_to_one(num_cities) form = 0 for i in range(num_cities): for u in range(num_cities): for v in range(num_cities): if u != v: form += distance_matrix[u, v] * Z(int(two_to_one[u, i]))* Z( int(two_to_one[v, (i + 1) % num_cities])) ham = SymbolicHamiltonian(form) return ham
def test_symbolicxxz_hamiltonian_to_dense(backend, nqubits, calcterms): from qibo.symbols import X, Y, Z sham = sum(X(i) * X(i + 1) for i in range(nqubits - 1)) sham += sum(Y(i) * Y(i + 1) for i in range(nqubits - 1)) sham += 0.5 * sum(Z(i) * Z(i + 1) for i in range(nqubits - 1)) sham += X(0) * X(nqubits - 1) + Y(0) * Y(nqubits - 1) + 0.5 * Z(0) * Z(nqubits - 1) final_ham = hamiltonians.SymbolicHamiltonian(sham) target_ham = hamiltonians.XXZ(nqubits) if calcterms: _ = final_ham.terms K.assert_allclose(final_ham.matrix, target_ham.matrix, atol=1e-15)
def test_hamiltonian_with_identity_symbol(calcterms): """Check creating Hamiltonian from expression which contains the identity symbol.""" from qibo.symbols import I, X, Y, Z symham = X(0) * I(1) * Z(2) + 0.5 * Y(0) * Z(1) * I(3) + Z(0) * I(1) * X(2) ham = hamiltonians.SymbolicHamiltonian(symham) if calcterms: _ = ham.terms final_matrix = ham.matrix target_matrix = np.kron(np.kron(matrices.X, matrices.I), np.kron(matrices.Z, matrices.I)) target_matrix += 0.5 * np.kron(np.kron(matrices.Y, matrices.Z), np.kron(matrices.I, matrices.I)) target_matrix += np.kron(np.kron(matrices.Z, matrices.I), np.kron(matrices.X, matrices.I)) K.assert_allclose(final_matrix, target_matrix)
def test_symbolic_term_merge(backend): """Test merging ``SymbolicTerm`` to ``HamiltonianTerm``.""" from qibo.symbols import X, Z matrix = np.random.random((4, 4)) term1 = terms.HamiltonianTerm(matrix, 0, 1) term2 = terms.SymbolicTerm(1, X(0) * Z(1)) term = term1.merge(term2) target_matrix = matrix + np.kron(matrices.X, matrices.Z) K.assert_allclose(term.matrix, target_matrix)
def test_symbolic_term_matrix(backend): """Test matrix calculation of ``SymbolicTerm``.""" from qibo.symbols import X, Y, Z expression = X(0) * Y(1) * Z(2) * X(1) term = terms.SymbolicTerm(2, expression) assert term.target_qubits == (0, 1, 2) target_matrix = np.kron(matrices.X, matrices.Y @ matrices.X) target_matrix = 2 * np.kron(target_matrix, matrices.Z) K.assert_allclose(term.matrix, target_matrix)
def test_symbolic_term_mul(backend): """Test multiplying scalar to ``SymbolicTerm``.""" from qibo.symbols import X, Y, Z expression = Y(2) * Z(3) * X(2) * X(3) term = terms.SymbolicTerm(1, expression) assert term.target_qubits == (2, 3) target_matrix = np.kron(matrices.Y @ matrices.X, matrices.Z @ matrices.X) K.assert_allclose(term.matrix, target_matrix) K.assert_allclose((2 * term).matrix, 2 * target_matrix) K.assert_allclose((term * 3).matrix, 3 * target_matrix)
def test_symbolic_term_with_power_creation(): """Test creating ``SymbolicTerm`` from sympy expression that contains powers.""" from qibo.symbols import X, Z expression = X(0)**4 * Z(1)**2 * X(2) term = terms.SymbolicTerm(2, expression) assert term.target_qubits == (0, 1, 2) assert len(term.matrix_map) == 3 assert term.coefficient == 2 K.assert_allclose(term.matrix_map.get(0), 4 * [matrices.X]) K.assert_allclose(term.matrix_map.get(1), 2 * [matrices.Z]) K.assert_allclose(term.matrix_map.get(2), [matrices.X])
def test_three_qubit_term_hamiltonian_from_symbols(hamtype, calcterms): """Check creating Hamiltonian with three-qubit interaction using sympy.""" if hamtype == "symbolic": from qibo.symbols import X, Y, Z symham = X(0) * Y(1) * Z(2) + 0.5 * Y(0) * Z(1) * X(3) + Z(0) * X(2) symham += Y(2) + 1.5 * Z(1) - 2 - 3 * X(1) * Y(3) ham = hamiltonians.SymbolicHamiltonian(symham) else: x_symbols = sympy.symbols(" ".join((f"X{i}" for i in range(4)))) y_symbols = sympy.symbols(" ".join((f"Y{i}" for i in range(4)))) z_symbols = sympy.symbols(" ".join((f"Z{i}" for i in range(4)))) symmap = {x: (i, matrices.X) for i, x in enumerate(x_symbols)} symmap.update({x: (i, matrices.Y) for i, x in enumerate(y_symbols)}) symmap.update({x: (i, matrices.Z) for i, x in enumerate(z_symbols)}) symham = x_symbols[0] * y_symbols[1] * z_symbols[2] symham += 0.5 * y_symbols[0] * z_symbols[1] * x_symbols[3] symham += z_symbols[0] * x_symbols[2] symham += -3 * x_symbols[1] * y_symbols[3] symham += y_symbols[2] symham += 1.5 * z_symbols[1] symham -= 2 ham = hamiltonians.Hamiltonian.from_symbolic(symham, symmap) if calcterms: _ = ham.terms final_matrix = ham.matrix target_matrix = np.kron(np.kron(matrices.X, matrices.Y), np.kron(matrices.Z, matrices.I)) target_matrix += 0.5 * np.kron(np.kron(matrices.Y, matrices.Z), np.kron(matrices.I, matrices.X)) target_matrix += np.kron(np.kron(matrices.Z, matrices.I), np.kron(matrices.X, matrices.I)) target_matrix += -3 * np.kron(np.kron(matrices.I, matrices.X), np.kron(matrices.I, matrices.Y)) target_matrix += np.kron(np.kron(matrices.I, matrices.I), np.kron(matrices.Y, matrices.I)) target_matrix += 1.5 * np.kron(np.kron(matrices.I, matrices.Z), np.kron(matrices.I, matrices.I)) target_matrix -= 2 * np.eye(2**4, dtype=target_matrix.dtype) K.assert_allclose(final_matrix, target_matrix)
def test_term_group_to_term(backend): """Test ``GroupTerm.term`` property.""" from qibo.symbols import X, Z matrix = np.random.random((8, 8)) term1 = terms.HamiltonianTerm(matrix, 0, 1, 3) term2 = terms.SymbolicTerm(1, X(0) * Z(3)) term3 = terms.SymbolicTerm(2, X(1)) group = terms.TermGroup(term1) group.append(term2) group.append(term3) matrix2 = np.kron(np.kron(matrices.X, np.eye(2)), matrices.Z) matrix3 = np.kron(np.kron(np.eye(2), matrices.X), np.eye(2)) target_matrix = matrix + matrix2 + 2 * matrix3 K.assert_allclose(group.term.matrix, target_matrix)
def test_symbolic_term_call(backend, density_matrix): """Test applying ``SymbolicTerm`` to state.""" from qibo.symbols import X, Y, Z expression = Z(0) * X(1) * Y(2) term = terms.SymbolicTerm(2, expression) matrixlist = [ np.kron(matrices.Z, np.eye(4)), np.kron(np.kron(np.eye(2), matrices.X), np.eye(2)), np.kron(np.eye(4), matrices.Y) ] initial_state = random_density_matrix( 3) if density_matrix else random_state(3) final_state = term(np.copy(initial_state), density_matrix=density_matrix) target_state = 2 * np.copy(initial_state) for matrix in matrixlist: target_state = matrix @ target_state K.assert_allclose(final_state, target_state)
def test_from_symbolic_application_hamiltonian(calcterms): """Check ``from_symbolic`` for a specific four-qubit Hamiltonian.""" 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 = hamiltonians.Hamiltonian.from_symbolic(symham, symmap) from qibo.symbols import Z symham = (Z(0) * Z(1) - 0.5 * Z(0) * Z(2) + 2 * Z(1) * Z(2) + 0.35 * Z(1) + 0.25 * Z(2) * Z(3) + 0.5 * Z(2) + Z(3) - Z(0)) sham = hamiltonians.SymbolicHamiltonian(symham) if calcterms: _ = sham.terms K.assert_allclose(sham.matrix, fham.matrix)