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_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_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 tsp_mixer(num_cities): two_to_one = calculate_two_to_one(num_cities) splus = lambda u, i: X(int(two_to_one[u, i])) + 1j * Y(int(two_to_one[u, i])) sminus = lambda u, i: X(int(two_to_one[u, i])) - 1j * Y(int(two_to_one[u, i])) form = 0 for i in range(num_cities): for u in range(num_cities): for v in range(num_cities): if u != v: form += splus(u, i) * splus(v, (i + 1) % num_cities) * sminus(u, ( i + 1) % num_cities) * sminus(v, i) + sminus(u, i) * sminus(v, ( i + 1) % num_cities) * splus(u, (i + 1) % num_cities) * splus( v, i) ham = SymbolicHamiltonian(form) return ham
def test_symbolic_hamiltonian_abstract_symbol_ev(backend, density_matrix, calcterms): from qibo.symbols import X, Symbol matrix = np.random.random((2, 2)) form = X(0) * Symbol(1, matrix) + Symbol(0, matrix) * X(1) local_ham = hamiltonians.SymbolicHamiltonian(form) if calcterms: _ = local_ham.terms if density_matrix: state = K.cast(random_complex((4, 4))) else: state = K.cast(random_complex((4, ))) local_ev = local_ham.expectation(state) target_ev = local_ham.dense.expectation(state) K.assert_allclose(local_ev, target_ev)
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_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 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_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_symbolic_term_creation(use_symbols): """Test creating ``SymbolicTerm`` from sympy expression.""" if use_symbols: from qibo.symbols import X, Y expression = X(0) * Y(1) * X(1) symbol_map = {} else: import sympy x0, x1, y1 = sympy.symbols("X0 X1 Y1", commutative=False) expression = x0 * y1 * x1 symbol_map = { x0: (0, matrices.X), x1: (1, matrices.X), y1: (1, matrices.Y) } term = terms.SymbolicTerm(2, expression, symbol_map) assert term.target_qubits == (0, 1) assert len(term.matrix_map) == 2 K.assert_allclose(term.matrix_map.get(0)[0], matrices.X) K.assert_allclose(term.matrix_map.get(1)[0], matrices.Y) K.assert_allclose(term.matrix_map.get(1)[1], matrices.X)
def test_from_symbolic_with_complex_numbers(hamtype, calcterms): """Check ``from_symbolic`` when the expression contains imaginary unit.""" if hamtype == "symbolic": from qibo.symbols import X, Y symham = (1 + 2j) * X(0) * X(1) + 2 * Y(0) * Y(1) - 3j * X(0) * Y(1) + 1j * Y(0) * X(1) ham = hamiltonians.SymbolicHamiltonian(symham) else: x = sympy.symbols(" ".join((f"X{i}" for i in range(2)))) y = sympy.symbols(" ".join((f"Y{i}" for i in range(2)))) symham = (1 + 2j) * x[0] * x[1] + 2 * y[0] * y[1] - 3j * x[0] * y[1] + 1j * y[0] * x[1] symmap = {s: (i, matrices.X) for i, s in enumerate(x)} symmap.update({s: (i, matrices.Y) for i, s in enumerate(y)}) ham = hamiltonians.Hamiltonian.from_symbolic(symham, symmap) if calcterms: _ = ham.terms final_matrix = ham.matrix target_matrix = (1 + 2j) * np.kron(matrices.X, matrices.X) target_matrix += 2 * np.kron(matrices.Y, matrices.Y) target_matrix -= 3j * np.kron(matrices.X, matrices.Y) target_matrix += 1j * np.kron(matrices.Y, matrices.X) K.assert_allclose(final_matrix, target_matrix)
def test_x_hamiltonian_from_symbols(nqubits, hamtype, calcterms): """Check creating sum(X) Hamiltonian using sympy.""" if hamtype == "symbolic": from qibo.symbols import X symham = -sum(X(i) for i in range(nqubits)) ham = hamiltonians.SymbolicHamiltonian(symham) else: 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)} ham = hamiltonians.Hamiltonian.from_symbolic(symham, symmap) if calcterms: _ = ham.terms final_matrix = ham.matrix target_matrix = hamiltonians.X(nqubits).matrix K.assert_allclose(final_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)