Grover’s Algorithm (My Lab)
Cahyati Supriyati Sangaji (My Note)
You will implement Grover’s algorithm in Qiskit.
You might find this chapter of the Qiskit Textbook useful:
Remember, to run a cell in Jupyter notebooks, you press Shift
+ Return/Enter
on your keyboard.
Installing necessary packages
Before we begin, you will need to install some prerequisites into your environment. Run the cell below to complete these installations. At the end, the cell outputs will be cleared.
!pip install -U seaborn==0.10
!pip install -U qiskit==0.19
!pip install -U ipywidgets==7.5.1from IPython.display import clear_output
clear_output()
Review of Grover’s Algorithm
Grover’s algorithm has three main components.
Graded Exercise 1: Implementing Grover’s Algorithm
It is not hard to implement Grover’s algorithm using Qiskit
. The goal of this lab is to implement Grover's algorithm by creating a quantum circuit that has the marked elements 000001
and 101010
. You will see that the algorithm outputs one of these two marked elements with probability greater than 99%.
Let us build each block step by step.
1) Phase Oracle
We start with the phase oracle. You might find it helpful to have a look at the corresponding chapter in the Qiskit textbook: https://qiskit.org/textbook/ch-algorithms/grover.html. However, note that the implementation in the textbook is done on 2 and 3 qubits only, while here we need to apply it to 6 qubits.
Once you complete these steps, apply the unitary operator to the quantum circuit.
from qiskit.quantum_info import Operator
from qiskit import QuantumCircuit
import numpy as npdef phase_oracle(n, indices_to_mark, name = 'Oracle'):
# create a quantum circuit on n qubits
qc = QuantumCircuit(n, name=name)### WRITE YOUR CODE BETWEEN THESE LINES - START
oracle_matrix = np.identity(2**n)
for index_to_mark in indices_to_mark:
oracle_matrix[index_to_mark, index_to_mark] = -1
### WRITE YOUR CODE BETWEEN THESE LINES - END# convert your matrix (called oracle_matrix) into an operator, and
# add it to the quantum circuit
qc.unitary(Operator(oracle_matrix), range(n))
return qc
2.) Diffusion Operator 𝑉
def diffuser(n):
# create a quantum circuit on n qubits
qc = QuantumCircuit(n, name='Diffuser')
### WRITE YOUR CODE BETWEEN THESE LINES - START
qc.h(range(n))
qc.append(phase_oracle(n,[0]),range(n))
qc.h(range(n))
### WRITE YOUR CODE BETWEEN THESE LINES - END
return qc
3.) Putting it all together
Finally, we combine the functions to construct Grover’s algorithm. We need to determine the optimal number of rounds 𝑟. This was given by
We have also seen a lower bound on the success probability when using 𝑛 qubits. In this exercise, the success probability should be higher than 99%.
Let’s construct a quantum program that finds the marked elements 000001
and 101010
using Grover's algorithm. To do this, we will need to do the following:
- We start with a Hadamard gate on all qubits.
- Next, we apply 𝑟r rounds of Grover’s algorithm, where each round consists of the application of the phase oracle with the marked elements and the diffuser. The indices for the two marked elements
000001
and101010
are 1 and 42. - Finally, we need to measure all qubits.
The next lines of code put everything together.
def Grover(n, indices_of_marked_elements):
# Create a quantum circuit on n qubits
qc = QuantumCircuit(n, n)
# Determine r
r=int(np.floor(np.pi/4*np.sqrt(2**n/len
(indices_of_marked_elements))))
print(f'{n} qubits, basis states {indices_of_marked_elements}
marked, {r} rounds')
# step 1: apply Hadamard gates on all qubits
qc.h(range(n))
# step 2: apply r rounds of the phase oracle and the diffuser
for _ in range(r):
qc.append(phase_oracle(n, indices_of_marked_elements),
range(n))
qc.append(diffuser(n), range(n))
# step 3: measure all qubits
qc.measure(range(n), range(n))
return qcmycircuit = Grover(6, [1, 42])
mycircuit.draw(output='text')
That’s it! You might find it useful to run your quantum circuit and see the measurement outcomes, as well as visualize the statevector at the end.
In order to run your quantum circuit and get the measurement outcomes, you simply need to run Qiskit
's execute
function as follows.
from qiskit import Aer, execute
simulator = Aer.get_backend('qasm_simulator')
counts = execute(mycircuit, backend=simulator, shots=1000).result().get_counts(mycircuit)
from qiskit.visualization import plot_histogram
plot_histogram(counts)
Additional reading
- In the exercise above, we implemented the phase oracle and diffuser as matrices without decomposing them into single- and two-qubit gates. To run on real hardware, one will also need to consider how to build these oracles using gates. You can find examples of how the oracles can be built in the Grover’s algorithm section of the Qiskit Textbook here: https://qiskit.org/textbook/ch-algorithms/grover.html
References:
Qiskit (Global Summer School), Introduction to Quantum Computing and Quantum Hardware — Lab 2.