def interference(repeat_count: int, starting_state: int) -> dict[tuple[int, ...], int]: """Creates a superposition and applies interference on a qubit in a specified state a specified number of times. Args: repeat_count (int): The number of times to repeat the quantum circuit. starting_state (int): The state to set the qubit to prior to running the quantum circuit. Returns: dict[tuple[int, ...], int]: The measurement result counts. """ # Set up quantum circuit with 1 qubit and 1 bit. # Set qubit to desired starting state. # If the starting state should be 1, apply the X gate. circuit = Circuit(1, 1) if starting_state == 1: circuit.X(0) # Apply Hadamard gate to create a superposition. circuit.H(0) # Apply Hadamard gate to cause interference to restore qubit to its starting state. circuit.H(0) # Measure the qubit and save the result into a classical bit. circuit.Measure(0, 0) # Initialise backend and run circuit a specified number of times. backend.compile_circuit(circuit) job = backend.process_circuit(circuit, n_shots=repeat_count) # Get counts of qubit measurement results. result_counts = backend.get_result(job).get_counts() return result_counts
def test_expectation_value() -> None: c = Circuit(2) c.H(0) c.CX(0, 1) op = QubitPauliOperator({ QubitPauliString({ Qubit(0): Pauli.Z, Qubit(1): Pauli.Z }): 1.0, QubitPauliString({ Qubit(0): Pauli.X, Qubit(1): Pauli.X }): 0.3, QubitPauliString({ Qubit(0): Pauli.Z, Qubit(1): Pauli.Y }): 0.8j, QubitPauliString({Qubit(0): Pauli.Y}): -0.4j, }) b = MyBackend() b.compile_circuit(c) assert get_operator_expectation_value(c, op, b) == pytest.approx(1.3)
def test_sampler_expectation_value() -> None: c = Circuit(2) c.H(0) c.CX(0, 1) op = QubitPauliOperator({ QubitPauliString({ Qubit(0): Pauli.Z, Qubit(1): Pauli.Z }): 1.0, QubitPauliString({ Qubit(0): Pauli.X, Qubit(1): Pauli.X }): 0.3, QubitPauliString({ Qubit(0): Pauli.Z, Qubit(1): Pauli.Y }): 0.8j, QubitPauliString({Qubit(0): Pauli.Y}): -0.4j, }) b = MySampler() b.compile_circuit(c) expectation = get_operator_expectation_value(c, op, b, n_shots=2000, seed=0) assert (np.real(expectation), np.imag(expectation)) == pytest.approx( (1.3, 0.0), abs=0.1)
def test_sampler_invalid_conditions() -> None: c = Circuit(2, 2) c.H(0) c.CX(0, 1, condition_bits=[0, 1], condition_value=3) c.measure_all() b = MySampler() b.compile_circuit(c) assert not (b.valid_circuit(c))
def test_bell() -> None: c = Circuit(2) c.H(0) c.CX(0, 1) b = MyBackend() b.compile_circuit(c) assert np.allclose(b.get_state(c), np.asarray([1, 0, 0, 1]) * 1 / np.sqrt(2))
def test_sampler_bell() -> None: c = Circuit(2, 2) c.H(0) c.CX(0, 1) c.measure_all() b = MySampler() b.compile_circuit(c) assert b.get_shots(c, n_shots=10, seed=3).shape == (10, 2) assert b.get_counts(c, n_shots=10, seed=3) == {(0, 0): 5, (1, 1): 5}
def U(s, n_qubits): c = Circuit(n_qubits) for i in range(len(s)): if s[i] == "X": c.H(i) elif s[i] == "Y": c.Rx(i, 0.5) elif s[i] == "Z": pass return c
def add_operator_term(circuit: Circuit, term: QubitPauliString, angle: float): qubits = [] for q, p in term.to_dict().items(): if p != Pauli.I: qubits.append(q) if p == Pauli.X: circuit.H(q) elif p == Pauli.Y: circuit.V(q) for i in range(len(qubits) - 1): circuit.CX(i, i + 1) circuit.Rz(angle, len(qubits) - 1) for i in reversed(range(len(qubits) - 1)): circuit.CX(i, i + 1) for q, p in term.to_dict().items(): if p == Pauli.X: circuit.H(q) elif p == Pauli.Y: circuit.Vdg(q)
def pauli_measurement(pauli_string:Iterable[Tuple[int,str]], circ:Circuit) : """Appends measurement instructions to a given circuit, measuring each qubit in a given basis :param pauli_string: The pauli operator to measure, as tuples of pauli name and qubit. :type pauli_string: Iterable[Tuple[int,str]] :param circ: Circuit to add measurement to. :type circ: Circuit """ measured_qbs = [] for qb_idx, p in pauli_string: measured_qbs.append(qb_idx) if p=='X': circ.H(qb_idx) elif p=='Y': circ.Sdg(qb_idx) circ.H(qb_idx) for idx in measured_qbs: circ.Measure(idx, idx)
def measure_x(quantum_circuit: Circuit, qubit: int, bit: int) -> None: """Measures a specified qubit in the Hadamard (X) basis. Args: quantum_circuit (pytket.circuit.Circuit): The quantum circuit to apply the measurement to. qubit (int): The qubit to measure. bit (int): The bit to save the qubit measurement result into. """ # Apply Hadamard gate to the qubit. # Measure the qubit into the bit. quantum_circuit.H(qubit) quantum_circuit.Measure(qubit, bit)
def pauli_evolution(pauli: List[Tuple[int, str]], coeff: complex, circ: Circuit): """Appends the evolution circuit corresponding to a given Pauli tensor Args: pauli: coeff (complex): circ (Circuit): """ # set up the correct basis all_qbs = list(zip(*pauli))[0] for qb_idx, p in pauli: if p == 'X': circ.H(qb_idx) elif p == 'Y': # angles in half-turns circ.Rx(qb_idx, 0.5) # cnot cascade cx_qb_pairs = list(zip(sorted(all_qbs)[:-1], sorted(all_qbs)[1:])) for pair in cx_qb_pairs: circ.CX(pair[0], pair[1]) # rotation (convert angle from radians to half-turns) circ.Rz(all_qbs[-1], (2 * coeff.imag) / PI) # reverse cascade and revert basis cx_qb_pairs = list(zip(sorted(all_qbs)[:-1], sorted(all_qbs)[1:])) for pair in reversed(cx_qb_pairs): circ.CX(pair[0], pair[1]) all_qbs = list(zip(*pauli))[0] for qb_idx, p in pauli: if p == 'X': circ.H(qb_idx) elif p == 'Y': circ.Rx(qb_idx, -0.5)
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 generate_random_number() -> int: """Generates a random number between 0-15. Returns: int: A random number between 0-15. """ # Set up quantum circuit with 4 qubits. circuit = Circuit(4, 4) # Apply Hadamard gate to all qubits. for qubit in range(4): circuit.H(qubit) # Measure all qubits. circuit.measure_all() # Initialise simulator and run circuit. job = backend.process_circuit(circuit, n_shots=1) shots = backend.get_result(job).get_shots() # Get shot measurement results and convert result as binary digits into integer. random_number_bitstring = ''.join(list(map(str, shots[0]))) random_number = int(f'0b{random_number_bitstring}', 2) return random_number
def superposition(repeat_count: int, basis_measurement: Callable[[Circuit, int, int], None]) -> dict[tuple[int, ...], int]: """Creates a superposition and measures it using a specified basis a specified number of times. Args: repeat_count (int): The number of times to repeat the quantum circuit. basis_measurement (Callable[[Circuit, int, int], None]): The function to perform the specified basis measurement with. Returns: dict[tuple[int, ...], int]: The measurement result counts. """ # Set up quantum circuit with 1 qubit and 1 bit. # Apply Hadamard gate to qubit 0. # Measure qubit 0 into bit 0 using the specified measurement basis. circuit = Circuit(1, 1) circuit.H(0) basis_measurement(circuit, 0, 0) # Initialise backend and run circuit a specified number of times. backend.compile_circuit(circuit) job = backend.process_circuit(circuit, n_shots=repeat_count) # Get counts of qubit measurement results. result_counts = backend.get_result(job).get_counts() return result_counts
def iterated_entanglement_swap(n_iter): # Iterate the entanglement swapping protocol n_iter times it_es = Circuit() ava = it_es.add_q_register("a", 1) bella = it_es.add_q_register("b", 2) charlie = it_es.add_q_register("c", 1) data = it_es.add_c_register("d", 2) # Start with an initial Bell state it_es.H(ava[0]) it_es.CX(ava[0], bella[0]) for i in range(n_iter): if i % 2 == 0: # Teleport bella[0] to charlie[0] to give a Bell pair between ava[0] and charlier[0] tel_to_c = qtel.copy() tel_to_c.rename_units( {alice[0]: bella[0], alice[1]: bella[1], bob[0]: charlie[0]} ) it_es.append(tel_to_c) it_es.add_gate(OpType.Reset, [bella[0]]) it_es.add_gate(OpType.Reset, [bella[1]]) else: # Teleport charlie[0] to bella[0] to give a Bell pair between ava[0] and bella[0] tel_to_b = qtel.copy() tel_to_b.rename_units( {alice[0]: charlie[0], alice[1]: bella[1], bob[0]: bella[0]} ) it_es.append(tel_to_b) it_es.add_gate(OpType.Reset, [bella[1]]) it_es.add_gate(OpType.Reset, [charlie[0]]) # Return the circuit and the qubits expected to share a Bell pair if n_iter % 2 == 0: return it_es, [ava[0], bella[0]] else: return it_es, [ava[0], charlie[0]]
# Apply Hadamard gate to the qubit. # Measure the qubit into the bit. quantum_circuit.H(qubit) quantum_circuit.Measure(qubit, bit) print('*** Hello, Quantum! - Phase Kickback (tket) ***') repeat_count = 1000 # Set up cirbuit with 2 qubits and 2 classical bits. circuit = Circuit(2, 2) # Apply Hadamard gate to control qubit to create a superposition in the # (+)-superposition state. circuit.H(0) # Apply X gate to target qubit to set it to the 1 state. # Apply Hadamard gate to target qubit to create a superposition in the # (-)-superposition state. circuit.X(1) circuit.H(1) # Apply CNOT gate to target qubit using the control qubit to trigger phase # kickback onto the control qubit. circuit.CX(0, 1) # Measure qubits in the Hadamard (X) basis. measure_x(circuit, 0, 0) measure_x(circuit, 1, 1)
sys.path.append('../../../libraries') from tket_backend_factory import get_tket_backend # Get quantum backend from command-line arguments. backend = get_tket_backend() print('*** Hello, Quantum! - Entanglement (tket) ***') repeat_count = 1000 # Set up cirbuit with 2 qubits and 2 classical bits. # Apply Hadamard gate to the control qubit 0. # Apply Controlled NOT gate to the target qubit 1 using qubit 0 as control. # Measure the qubits and save the result into classical bits. circuit = Circuit(2, 2) circuit.H(0) circuit.CX(0, 1) circuit.Measure(0, 0) circuit.Measure(1, 1) # Initialise backend and run circuit a specified number of times. backend.compile_circuit(circuit) job = backend.process_circuit(circuit, n_shots=repeat_count) # Get counts of qubit measurement results. result_counts = backend.get_result(job).get_counts() # Print results. print(f"Counts for {repeat_count} repeats:") print(f"\t00: {result_counts[(0, 0)]}") print(f"\t01: {result_counts[(0, 1)]}")
# `if(c==3) z b[0];` # `if(c==2) x b[0];` # `if(c==3) x b[0];` # # This corresponds to the following `pytket` code: from pytket import Circuit qtel = Circuit() alice = qtel.add_q_register("a", 2) bob = qtel.add_q_register("b", 1) data = qtel.add_c_register("d", 2) # Bell state between Alice and Bob: qtel.H(alice[1]) qtel.CX(alice[1], bob[0]) # Bell measurement of Alice's qubits: qtel.CX(alice[0], alice[1]) qtel.H(alice[0]) qtel.Measure(alice[0], data[0]) qtel.Measure(alice[1], data[1]) # Correction of Bob's qubit: qtel.X(bob[0], condition_bits=[data[0], data[1]], condition_value=2) qtel.X(bob[0], condition_bits=[data[0], data[1]], condition_value=3) qtel.Z(bob[0], condition_bits=[data[0], data[1]], condition_value=1) qtel.Z(bob[0], condition_bits=[data[0], data[1]], condition_value=3)
def test_invalid_measures() -> None: c = Circuit(2) c.H(0).CX(0, 1).measure_all() b = MyBackend() b.compile_circuit(c) assert not (b.valid_circuit(c))
backend = AerBackend() backend.compile_circuit(c) handle = backend.process_circuit(c, n_shots=2000) counts = backend.get_result(handle).get_counts() print(counts) # ## Statevector simulator usage from pytket import Circuit from pytket.extensions.qiskit import AerStateBackend # Build a quantum state: c = Circuit(3) c.H(0).CX(0, 1) c.Rz(0.3, 0) c.Rz(-0.3, 1) c.Ry(0.8, 2) # Examine the statevector: backend = AerStateBackend() backend.compile_circuit(c) handle = backend.process_circuit(c) state = backend.get_result(handle).get_state() print(state) # ## Expectation value usage from pytket import Circuit, Qubit