def get_pauli_expectation(c: Circuit, initial_circuit: Circuit, pauli_string: str, backend, shots: int = 100) -> float: n_qubits = len(pauli_string) circuit = initial_circuit.copy() circuit.add_circuit(c.copy(), list(range(n_qubits))) black_box_exp = backend.get_pauli_expectation_value( circuit, [(i, pauli_string[i]) for i in range(len(pauli_string)) if pauli_string[i] != "I"], shots=shots).real return black_box_exp
def mnot_templates(n_controls): if n_controls == 0: return Circuit(1) c1 = Circuit(2) c1.CX(0, 1) c1.add_circuit(c1.copy(), [0, 1]) if n_controls == 1: return c1 c2 = Circuit(3) c2.CX(1, 2) c2.CX(0, 1) c2.CX(1, 2) c2.CX(0, 1) c2.CX(0, 2) circs = [c1, c2] for i in range(3, n_controls + 1): c = Circuit(i + 1) c.CX(i - 1, i) c.CX(i - 1, i) c.add_circuit(circs[-1], list(range(i))) c.CX(i - 1, i) c.CX(i - 1, i) c.add_circuit(circs[-1], list(range(i))) c.add_circuit(circs[-1], list(range(i - 1)) + [i]) c.add_circuit(circs[-1], list(range(i - 1)) + [i]) circs.append(c) return circs
def from_pytket(circuit: pytket.Circuit) -> cirq.Circuit: """Returns a Mitiq circuit equivalent to the input pytket circuit. Args: circuit: pytket circuit to convert to a Mitiq circuit. Returns: Mitiq circuit representation equivalent to the input pytket circuit. """ rebased_circuit = circuit.copy() RebaseCirq().apply(rebased_circuit) return tk_to_cirq(rebased_circuit)
def get_pauli_expectation_ibmq(circuit_string: Iterable[Any], initial_circuit: Circuit, pauli_string: str, *, shots: int = 4096, key: Dict[Any, Callable] = None) -> float: n_qubits = len(pauli_string) if pauli_string == "I" * n_qubits: return 1 circuit = initial_circuit.copy() circuit.add_circuit(circuit_from_string(circuit_string, n_qubits=n_qubits, key=key), list(range(n_qubits))) for i in range(n_qubits): circuit.add_circuit(final_circuits[pauli_string[i]].copy(), [i]) circuit.measure_all() noisy_shots = backend.get_counts(circuit, shots) return sum(v * (-1) ** sum(k) for k, v in noisy_shots.items())/shots
def test_implicit_perm() -> None: c = Circuit(2) c.CX(0, 1) c.CX(1, 0) c.Ry(0.1, 1) c1 = c.copy() CliffordSimp().apply(c1) b = MyBackend() b.compile_circuit(c) b.compile_circuit(c1) assert c.implicit_qubit_permutation() != c1.implicit_qubit_permutation() for bo in [BasisOrder.ilo, BasisOrder.dlo]: s = b.get_state(c, bo) s1 = b.get_state(c1, bo) assert np.allclose(s, s1)
def run(self, circuit: Circuit, shots: int, fit_to_constraints: bool = True) -> np.ndarray: """Run a circuit on the Rigetti QVM or a QCS device. :param circuit: The circuit to run :param shots: Number of shots (repeats) to run :param fit_to_constraints: Compile the circuit to meet the constraints of the backend, defaults to True :return: Table of shot results, each row is a shot, columns are ordered by qubit ordering. Values are 0 or 1, corresponding to qubit basis states. """ c = circuit.copy() if fit_to_constraints: phys_c = route(c, self._architecture) phys_c.decompose_SWAP_to_CX() Transform.OptimisePostRouting().apply(phys_c) Transform.RebaseToQuil().apply(c) p = tk_to_pyquil(c) p.wrap_in_numshots_loop(shots) ex = self._qc.compiler.native_quil_to_executable(p) return np.asarray(self._qc.run(ex))
# We can use the Placement objects to either modify the circuit in place, or return the mapping as a QubitMap. lp_athens = LinePlacement(athens_device) graph_athens = GraphPlacement(athens_device) noise_athens = NoiseAwarePlacement(athens_device) print("LinePlacement map:") print_qubit_mapping(lp_athens.get_placement_map(example_circuit)) print("GraphPlacement map:") print_qubit_mapping(graph_athens.get_placement_map(example_circuit)) print("NoiseAwarePlacement map:") print_qubit_mapping(noise_athens.get_placement_map(example_circuit)) # Each of these methods produces a different qubit->node mapping. Lets compare their performance: lp_ex_circ = example_circuit.copy() lp_athens.place(lp_ex_circ) gp_ex_circ = example_circuit.copy() graph_athens.place(gp_ex_circ) np_ex_circ = example_circuit.copy() noise_athens.place(np_ex_circ) line_routed_circuit = route(lp_ex_circ, athens_device) graph_routed_circuit = route(gp_ex_circ, athens_device) noise_aware_routed_circuit = route(np_ex_circ, athens_device) for c in [ line_routed_circuit, graph_routed_circuit, noise_aware_routed_circuit ]: Transform.DecomposeBRIDGE().apply(c) Transform.DecomposeSWAPtoCX().apply(c)
# So to demonstrate the Entanglement Swapping protocol, we just need to run this on one side of a Bell pair. es = Circuit() ava = es.add_q_register("a", 1) bella = es.add_q_register("b", 2) charlie = es.add_q_register("c", 1) data = es.add_c_register("d", 2) # Bell state between Ava and Bella: es.H(ava[0]) es.CX(ava[0], bella[0]) # Teleport `bella[0]` to `charlie[0]`: tel_to_c = qtel.copy() tel_to_c.rename_units({alice[0]: bella[0], alice[1]: bella[1], bob[0]: charlie[0]}) es.append(tel_to_c) print(es.get_commands()) # Let's start by running a noiseless simulation of this to verify that what we get looks like a Bell pair. from pytket.extensions.qiskit import AerBackend # Connect to a simulator: backend = AerBackend() # Make a ZZ measurement of the Bell pair: