def _tk1_to_x_v_rz(a: float, b: float, c: float) -> Circuit: circ = Circuit(1) if _approx_0_mod_2(b): circ.Rz(a + c, 0) elif _approx_0_mod_2(b + 1): if _approx_0_mod_2(a - 0.5) and _approx_0_mod_2(c - 0.5): circ.X(0) else: circ.Rz(c, 0).X(0).Rz(a, 0) else: if _approx_0_mod_2(a - 0.5) and _approx_0_mod_2(c - 0.5): circ.V(0).Rz(1 - b, 0).V(0) else: circ.Rz(c + 0.5, 0).V(0).Rz(b - 1, 0).V(0).Rz(a + 0.5, 0) return circ
def test_compilation_correctness() -> None: c = Circuit(5) c.H(0).H(1).H(2) c.CX(0, 1).CX(1, 2) c.Rx(0.25, 1).Ry(0.75, 1).Rz(0.5, 2) c.CCX(2, 1, 0) c.CY(1, 0).CY(2, 1) c.H(0).H(1).H(2) c.Rz(0.125, 0) c.X(1) c.Rz(0.125, 2).X(2).Rz(0.25, 2) c.V(3).Rz(0.125, 3).V(3) c.CX(0, 3).CX(0, 4) u_backend = AerUnitaryBackend() u = u_backend.get_unitary(c) ibm_backend = IBMQBackend("ibmq_santiago", hub="ibm-q", group="open", project="main") for ol in range(3): p = ibm_backend.default_compilation_pass(optimisation_level=ol) cu = CompilationUnit(c) p.apply(cu) c1 = cu.circuit compiled_u = u_backend.get_unitary(c1) # Adjust for placement imap = cu.initial_map fmap = cu.final_map c_idx = {c.qubits[i]: i for i in range(5)} c1_idx = {c1.qubits[i]: i for i in range(5)} ini = {c_idx[qb]: c1_idx[node] for qb, node in imap.items()} inv_fin = {c1_idx[node]: c_idx[qb] for qb, node in fmap.items()} m_ini = lift_perm(ini) m_inv_fin = lift_perm(inv_fin) assert compare_unitaries(u, m_inv_fin @ compiled_u @ m_ini)
# We use the `QubitPauliOperator` class to represent the operator $H$. from pytket.circuit import Circuit, Qubit from pytket.pauli import Pauli, QubitPauliString from pytket.utils import QubitPauliOperator from pytket.utils.expectations import get_operator_expectation_value from pytket.extensions.qiskit import AerBackend, AerStateBackend # First, let's get some results on a toy circuit without using any measurement reduction: shots_backend = AerBackend() n_shots = 10000 c = Circuit(5) c.H(4) c.V(2) shots_backend.compile_circuit(c) op = QubitPauliOperator({ QubitPauliString([Qubit(0)], [Pauli.Z]): 0.1, QubitPauliString( [Qubit(0), Qubit(1), Qubit(2), Qubit(3), Qubit(4)], [Pauli.Y, Pauli.Z, Pauli.X, Pauli.X, Pauli.Y], ): 0.4, QubitPauliString([Qubit(0), Qubit(1)], [Pauli.X, Pauli.X]): 0.2, })