Quantum Phase Estimation (My Lab)

cahyati sangaji (cahya)
6 min readDec 7, 2020

--

Cahyati Supriyati Sangaji (My Note)

In this lab, you will implement a quantum program to determine the global phase applied by a unitary operator on its eigenstate. In order to do this, you will write Qiskit code for the quantum phase estimation algorithm.

You might find the following chapters 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 qiskit==0.19
!pip install -U qiskit-ibmq-provider==0.7
from IPython.display import clear_output
clear_output()

Review of Quantum Phase Estimation

The goal of quantum phase estimation is to determine the phase πœƒ applied by a unitary operator π‘ˆ on its eigenstate |πœ“βŸ© such that

This is done in four main steps.

Graded Exercise 1: Implementing Quantum Phase Estimation

In this lab, we will implement the unitary operator π‘ˆ of a single qubit given by

for which an eigenstate is the single-qubit state |1⟩. The operator applies a phase

Our objective is to determine theta using quantum phase estimation. We will use πœƒ=0.5 and 𝑛=5 measurement qubits.

1. Initializing the qubits

We will need to initialize our qubits as described above by applying a Hadamard gate on each of the 𝑛n measurement qubits. We will also set the target qubit to |1⟩, since that is the eigenstate onto which the unitary operator π‘ˆ will be applied.

We have created a function below called initialize_qubits which takes in three arguments. The first argument is the quantum circuit onto which the gates will be applied. The second argument, measurement_qubits, is the list of measurement qubits. The third argument, target_qubit, is the target qubit for the unitary operator.

def initialize_qubits(given_circuit, measurement_qubits, target_qubit):

### WRITE YOUR CODE BETWEEN THESE LINES - START
#for measurement_qubits in range(target_qubit):
given_circuit.h(measurement_qubits)
given_circuit.x(target_qubit)
return given_circuit
### WRITE YOUR CODE BETWEEN THESE LINES - END

2. Implementing the unitary operator

We have created a function below called unitary_operator which takes in three arguments. The first argument is the quantum circuit onto which the operator will be applied. The second argument, control_qubit, is the control qubit for the unitary operator. The third argument, target_qubit, is the target qubit for the unitary operator. Finally, the fourth argument, theta, sets the value of πœƒ.

import numpy as np
pi = np.pi
def unitary_operator(given_circuit, control_qubit, target_qubit, theta):
#print(control_qubit)
given_circuit.cu1(theta*2*pi , control_qubit , target_qubit)
# This is C-U
return given_circuit
### WRITE YOUR CODE BETWEEN THESE LINES - END

We have created a function below called unitary_operator_exponent which takes in four arguments. The first argument is the quantum circuit onto which the operator will be applied. The second argument, control_qubit, is the control qubit for the unitary operator. The third argument, target_qubit, is the target qubit for the unitary operator. Finally, the fourth argument, theta, sets the value of πœƒΞΈ. The fourth argument, exponent is the number of times that the unitary operator needs to be applied.

def unitary_operator_exponent(given_circuit, control_qubit, target_qubit, theta, exponent):
#for control_qubit in range(target_qubit):
for _ in range(exponent):
given_circuit = unitary_operator(given_circuit,
control_qubit,
target_qubit,
theta*exponent)
return given_circuit
### WRITE YOUR CODE BETWEEN THESE LINES - END

3. Implementing an inverse quantum Fourier transform

You will also need to implement an inverse quantum Fourier transform as part of the quantum phase estimation algorithm. You can do this using two methods.

β€” Method 1 (easier) is to use Qiskit's circuit library to give you a box that implements the inverse quantum fourier transform. You can do this using qiskit.circuit.library.qft(num_qubits).inverse(). The documentation for this is here: https://qiskit.org/documentation/stubs/qiskit.circuit.library.QFT.html

β€” Method 2 (harder) is to implement the gates of the inverse quantum Fourier transform by hand. We strongly recommend following the detailed discussion in the Qiskit textbook for examples.

We have created a function below called apply_iqft which takes in three arguments. The first argument is the quantum circuit onto which the operator will be applied. The second argument, measurement_qubits, is the set of qubits onto which the inverse quantum Fourier transform will be applied. The third argument, n, is the number of measurement qubits for which the inverse quantum Fourier transform needs to be created.

from qiskit.circuit.library import QFTdef apply_iqft(given_circuit, measurement_qubits, n):
### WRITE YOUR CODE BETWEEN THESE LINES - START
# Apply inverse QFT
myQFT = QFT(num_qubits=n, approximation_degree=n, do_swaps=True,
inverse=True, insert_barriers=False, name='iqft')
# Measure
given_circuit.append(measurement_qubits,measurement_qubits)
### WRITE YOUR CODE BETWEEN THESE LINES - END

4. Putting it all together

Finally, we combine the functions to construct the quantum program that implements the quantum phase estimation algorithm.

The next lines of code put everything together.

from qiskit import QuantumCircuitdef qpe_program(n, theta):
# Create a quantum circuit on n+1 qubits (
# n measurement, 1 target)
qc = QuantumCircuit(n+1, n)

# Initialize the qubits
initialize_qubits(qc, range(n), n)

# Apply the controlled unitary operators in sequence
for x in range(n):
exponent = 2**(n-x-1)
unitary_operator_exponent(qc, x, n, theta, exponent)

# Apply the inverse quantum Fourier transform
apply_iqft(qc, range(n), n)

# Measure all qubits
qc.measure(range(n), range(n))

return qc
n = 5; theta = 0.5
mycircuit = qpe_program(n, theta)
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)
import operatorhighest_probability_outcome = max(counts.items(), key=operator.itemgetter(1))[0][::-1]measured_theta = int(highest_probability_outcome, 2)/2**nprint("Using %d qubits with theta = %.2f, measured_theta = %.2f." % (n, theta, measured_theta))

Out:

Using 5 qubits with theta = 0.50, measured_theta = 0.50.

Additional reading

  • On pi day of 2020 (March 14, 2020), we added a chapter to the Qiskit textbook showing how to estimate the value of πœ‹ using the quantum phase estimation algorithm. You can find that implementation here: https://qiskit.org/textbook/ch-demos/piday-code.html

References:

Qiskit (Global Summer School), Introduction to Quantum Computing and Quantum Hardware β€” Lab 3.

--

--