def test_customgate() -> None: a = Symbol("a") def_circ = Circuit(2) def_circ.CZ(0, 1) def_circ.Rx(a, 1) gate_def = CustomGateDef.define("MyCRx", def_circ, [a]) circ = Circuit(3) circ.Rx(0.1, 0) circ.Rx(0.4, 2) circ.add_custom_gate(gate_def, [0.2], [0, 1]) qc1 = tk_to_qiskit(circ) newcirc = qiskit_to_tk(qc1) print(repr(newcirc)) qc2 = tk_to_qiskit(newcirc) correct_circ = Circuit(3).Rx(0.1, 0).Rx(0.4, 2).CZ(0, 1).Rx(0.2, 1) correct_qc = tk_to_qiskit(correct_circ) backend = Aer.get_backend("statevector_simulator") states = [] for qc in (qc1, qc2, correct_qc): job = execute([qc], backend) states.append(job.result().get_statevector(qc)) assert compare_statevectors(states[0], states[1]) assert compare_statevectors(states[1], states[2])
def test_middle_engine() -> None: # pylint: disable=pointless-statement # pylint: disable=expression-not-assigned opti = tketOptimiser() engines = [opti] eng = MainEngine(engine_list=engines) circ = Circuit(2) circ.H(0) circ.CX(0, 1) circ.CX(0, 1) circ.CX(0, 1) circ.Rx(0.2, 1) circ.Rx(-0.2, 1) qureg = eng.allocate_qureg(circ.n_qubits) tk_to_projectq(eng, qureg, circ) Rz(0.3) | qureg[0] Rz(-0.3) | qureg[0] H | qureg[1] H | qureg[1] X | qureg[1] eng.flush() p1 = eng.backend.get_probability([0, 0], qureg) p2 = eng.backend.get_probability([0, 1], qureg) p3 = eng.backend.get_probability([1, 0], qureg) p4 = eng.backend.get_probability([1, 1], qureg) assert isclose(p1, 0.0, abs_tol=eps) assert isclose(p2, 0.5, abs_tol=eps) assert isclose(p3, 0.5, abs_tol=eps) assert isclose(p4, 0.0, abs_tol=eps)
def h2_4q_circ(theta: float) -> Circuit: circ = Circuit(4).X(0).X(1) circ.Rx(0.5, 0).H(1).H(2).H(3) circ.CX(0, 1).CX(1, 2).CX(2, 3) circ.Rz((-2 / np.pi) * theta, 3) circ.CX(2, 3).CX(1, 2).CX(0, 1) circ.Rx(-0.5, 0).H(1).H(2).H(3) return circ
def h2_2q_circ(theta: float) -> Circuit: circ = Circuit(2).X(0) circ.Rx(0.5, 0).H(1) circ.CX(0, 1) circ.Rz((-2 / np.pi) * theta, 1) circ.CX(0, 1) circ.Rx(-0.5, 0).H(1) return circ
def test_estimates() -> None: """ Check that the resource estimator gives reasonable results. """ b = QsharpEstimatorBackend() c = Circuit(3) c.H(0) c.CX(0, 1) c.CCX(0, 1, 2) c.Rx(0.3, 1) c.Ry(0.4, 2) c.Rz(1.1, 0) c.S(1) c.SWAP(0, 2) c.T(1) c.X(0) c.Y(1) c.Z(2) pbox = PauliExpBox([Pauli.X, Pauli.I, Pauli.Z], 0.25) c.add_pauliexpbox(pbox, [2, 0, 1]) b.compile_circuit(c, 0) resources = b.get_resources(c) assert resources["CNOT"] >= 1 assert resources["QubitClifford"] >= 1 assert resources["R"] >= 1 assert resources["T"] >= 1 assert resources["Depth"] >= 1 assert resources["Width"] == 3 assert resources["BorrowedWidth"] == 0
def test_sym_parameterised() -> None: circ = Circuit(3, name="test") circ.Z(1) alpha = fresh_symbol("alpha") circ.Rx(alpha, 0) with pytest.raises(Exception) as excinfo: _ = tk_to_pyzx(circ) assert "as it contains symbolic parameters." in str(excinfo.value)
def test_routing_no_cx() -> None: circ = Circuit(2, 2) circ.H(1) # c.CX(1, 2) circ.Rx(0.2, 0) circ.measure_all() coupling = [[1, 0], [2, 0], [2, 1], [3, 2], [3, 4], [4, 2]] arc = Architecture(coupling) physical_c = route(circ, arc) assert len(physical_c.get_commands()) == 4
def test_convert_symbolic() -> None: c = Circuit(2) alpha = Symbol("alpha") c.Rx(alpha, 0) beta = fresh_symbol("alpha") c.Rz(beta * 2, 1) with pytest.raises(RuntimeError): qs = tk_to_qsharp(c) s_map = {alpha: 0.5, beta: 3.2} c.symbol_substitution(s_map) qs = tk_to_qsharp(c) assert "Rx" in qs
def _aqt_rebase() -> BasePass: # CX replacement c_cx = Circuit(2) c_cx.Ry(0.5, 0) c_cx.add_gate(OpType.XXPhase, 0.5, [0, 1]) c_cx.Ry(1.0, 0).Rx(-0.5, 0).Ry(0.5, 0) c_cx.Rx(-0.5, 1) # TK1 replacement c_tk1 = lambda a, b, c: Circuit(1).Rx(-0.5, 0).Ry(a, 0).Rx(b, 0).Ry( c, 0).Rx(0.5, 0) return RebaseCustom({OpType.XXPhase}, c_cx, {OpType.Rx, OpType.Ry}, c_tk1)
def test_rebase_large() -> None: circ = Circuit(3) # some arbitrary unitary circ.Rx(0.21, 0).Rz(0.12, 1).Rz(8.2, 2).X(2).CX(0, 1).CX(1, 2).Rz(0.44, 1).Rx( 0.43, 0 ) orig_circ = circ.copy() _aqt_rebase().apply(circ) # TODO use tketsim for this test once available u1 = AerUnitaryBackend().get_unitary(orig_circ) u2 = AerUnitaryBackend().get_unitary(circ) assert np.allclose(u1, u2)
def measurement_circuits(hamiltonian, n_qubits): all_circs = [] for pauli, _ in hamiltonian.terms.items(): if not pauli: continue # Ignore the constant term measure_circ = Circuit(n_qubits, n_qubits) for qb, p in pauli: if p == "I": continue # Discard I qubits elif p == "X": measure_circ.H(qb) elif p == "Y": measure_circ.Rx(0.5, qb) measure_circ.Measure(qb, qb) all_circs.append(measure_circ) return all_circs
def test_ilo(qvm: None, quilc: None) -> None: b = ForestBackend("9q-square") bs = ForestStateBackend() c = Circuit(2) c.CZ(0, 1) c.Rx(1.0, 1) assert np.allclose(bs.get_state(c), np.asarray([0, -1j, 0, 0])) assert np.allclose(bs.get_state(c, basis=BasisOrder.dlo), np.asarray([0, 0, -1j, 0])) c.rename_units({Qubit(0): Node(0), Qubit(1): Node(1)}) c.measure_all() assert (b.get_shots(c, 2) == np.asarray([[0, 1], [0, 1]])).all() assert (b.get_shots(c, 2, basis=BasisOrder.dlo) == np.asarray([[1, 0], [1, 0]])).all() assert b.get_counts(c, 2) == {(0, 1): 2} assert b.get_counts(c, 2, basis=BasisOrder.dlo) == {(1, 0): 2}
def test_statevector() -> None: b = AerStateBackend() circ = Circuit(3, name="test") circ.H(2) circ.X(0) circ.H(0) circ.CX(0, 1) circ.CZ(1, 2) circ.Sdg(0) circ.Tdg(1) circ.Z(1) circ.T(2) circ.Rx(0.3333, 1) circ.Rz(0.3333, 1) zxcirc = tk_to_pyzx(circ) assert zxcirc.name == circ.name b.compile_circuit(circ) state = b.get_state(circ) circ2 = pyzx_to_tk(zxcirc) assert circ2.name == circ.name b.compile_circuit(circ2) state2 = b.get_state(circ2) assert np.allclose(state, state2, atol=1e-10)
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.SX(3).Rz(0.125, 3).SX(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)
def _from_tk1(a: float, b: float, c: float) -> Circuit: circ = Circuit(1) circ.Rz(c, 0) circ.Rx(b, 0) circ.Rz(a, 0) return circ
arc = Architecture([[n[0], n[1]], [n[1], n[2]], [n[2], n[3]], [n[3], n[4]]]) # A `Device` is a model of a physical device, which encapsulates both its `Architecture` and its gate noise characteristics. Ignoring the latter, we can construct a 'noise-free' `Device` directly from an `Architecture`: from pytket.device import Device dev = Device(arc) # Suppose we have a circuit that we wish to run on this device: circ = Circuit(5) circ.CX(0, 1) circ.H(0) circ.Z(1) circ.CX(0, 3) circ.Rx(1.5, 3) circ.CX(2, 4) circ.X(2) circ.CX(1, 4) circ.CX(0, 4) print(tk_to_qiskit(circ)) # A mapping pass lets us rewrite this circuit for our device: from pytket.passes import DefaultMappingPass mapper = DefaultMappingPass(dev) cu = CompilationUnit(circ) mapper.apply(cu) circ1 = cu.circuit