Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
quantum-kittens
GitHub Repository: quantum-kittens/platypus
Path: blob/main/notebooks/ch-algorithms/quantum-phase-estimation.ipynb
3855 views
Kernel: Python 3

Quantum Phase Estimation

Quantum phase estimation is one of the most important subroutines in quantum computation. It serves as a central building block for many quantum algorithms. The objective of the algorithm is the following:

Given a unitary operator UU, the algorithm estimates θ\theta in Uψ=e2πiθψU\vert\psi \rangle =e^{\boldsymbol{2\pi i} \theta }|\psi \rangle. Here ψ|\psi\rangle is an eigenvector and e2πiθe^{\boldsymbol{2\pi i}\theta} is the corresponding eigenvalue. Since UU is unitary, all of its eigenvalues have a norm of 1.

1. Overview

The general quantum circuit for phase estimation is shown below. The top register contains tt 'counting' qubits, and the bottom contains qubits in the state ψ|\psi\rangle: image1

1.1 Intuition

The quantum phase estimation algorithm uses phase kickback to write the phase of UU (in the Fourier basis) to the tt qubits in the counting register. We then use the inverse QFT to translate this from the Fourier basis into the computational basis, which we can measure.

We remember (from the QFT chapter) that in the Fourier basis the topmost qubit completes one full rotation when counting between 00 and 2t2^t. To count to a number, xx between 00 and 2t2^t, we rotate this qubit by x2t\tfrac{x}{2^t} around the z-axis. For the next qubit we rotate by 2x2t\tfrac{2x}{2^t}, then 4x2t\tfrac{4x}{2^t} for the third qubit.

image2

When we use a qubit to control the UU-gate, the qubit will turn (due to kickback) proportionally to the phase e2iπθe^{2i\pi\theta}. We can use successive CUCU-gates to repeat this rotation an appropriate number of times until we have encoded the phase theta as a number between 00 and 2t2^t in the Fourier basis.

Then we simply use QFTQFT^\dagger to convert this into the computational basis.

1.2 Mathematical Foundation

As mentioned above, this circuit estimates the phase of a unitary operator UU. It estimates θ\theta in Uψ=e2πiθψU\vert\psi \rangle =e^{\boldsymbol{2\pi i} \theta }|\psi \rangle, where ψ|\psi\rangle is an eigenvector and e2πiθe^{\boldsymbol{2\pi i}\theta} is the corresponding eigenvalue. The circuit operates in the following steps:

i. Setup: ψ\vert\psi\rangle is in one set of qubit registers. An additional set of nn qubits form the counting register on which we will store the value 2nθ2^n\theta:

ψ0=0nψ|\psi_0\rangle = \lvert 0 \rangle^{\otimes n} \lvert \psi \rangle

ii. Superposition: Apply a nn-bit Hadamard gate operation HnH^{\otimes n} on the counting register:

ψ1=12n2(0+1)nψ|\psi_1\rangle = {\frac {1}{2^{\frac {n}{2}}}}\left(|0\rangle +|1\rangle \right)^{\otimes n} \lvert \psi \rangle

iii. Controlled Unitary Operations: We need to introduce the controlled unitary CUCU that applies the unitary operator UU on the target register only if its corresponding control bit is 1|1\rangle. Since UU is a unitary operator with eigenvector ψ|\psi\rangle such that Uψ=e2πiθψU|\psi \rangle =e^{\boldsymbol{2\pi i} \theta }|\psi \rangle, this means:

U2jψ=U2j1Uψ=U2j1e2πiθψ==e2πi2jθψU^{2^{j}}|\psi \rangle =U^{2^{j}-1}U|\psi \rangle =U^{2^{j}-1}e^{2\pi i\theta }|\psi \rangle =\cdots =e^{2\pi i2^{j}\theta }|\psi \rangle

Applying all the nn controlled operations CU2jCU^{2^j} with 0jn10\leq j\leq n-1, and using the relation 0ψ+1e2πiθψ=(0+e2πiθ1)ψ|0\rangle \otimes |\psi \rangle +|1\rangle \otimes e^{2\pi i\theta }|\psi \rangle =\left(|0\rangle +e^{2\pi i\theta }|1\rangle \right)\otimes |\psi \rangle:

ψ2=12n2(0+e2πiθ2n11)(0+e2πiθ211)(0+e2πiθ201)ψ=12n2k=02n1e2πiθkkψ\begin{aligned} |\psi_{2}\rangle & =\frac {1}{2^{\frac {n}{2}}} \left(|0\rangle+{e^{\boldsymbol{2\pi i} \theta 2^{n-1}}}|1\rangle \right) \otimes \cdots \otimes \left(|0\rangle+{e^{\boldsymbol{2\pi i} \theta 2^{1}}}\vert1\rangle \right) \otimes \left(|0\rangle+{e^{\boldsymbol{2\pi i} \theta 2^{0}}}\vert1\rangle \right) \otimes |\psi\rangle\\\\ & = \frac{1}{2^{\frac {n}{2}}}\sum _{k=0}^{2^{n}-1}e^{\boldsymbol{2\pi i} \theta k}|k\rangle \otimes \vert\psi\rangle \end{aligned}

where kk denotes the integer representation of n-bit binary numbers.

iv. Inverse Fourier Transform: Notice that the above expression is exactly the result of applying a quantum Fourier transform as we derived in the notebook on Quantum Fourier Transform and its Qiskit Implementation. Recall that QFT maps an n-qubit input state x\vert x\rangle into an output as

QFTx=12n2(0+e2πi2x1)(0+e2πi22x1)(0+e2πi2n1x1)(0+e2πi2nx1)QFT\vert x \rangle = \frac{1}{2^\frac{n}{2}} \left(\vert0\rangle + e^{\frac{2\pi i}{2}x} \vert1\rangle\right) \otimes \left(\vert0\rangle + e^{\frac{2\pi i}{2^2}x} \vert1\rangle\right) \otimes \ldots \otimes \left(\vert0\rangle + e^{\frac{2\pi i}{2^{n-1}}x} \vert1\rangle\right) \otimes \left(\vert0\rangle + e^{\frac{2\pi i}{2^n}x} \vert1\rangle\right)

Replacing xx by 2nθ2^n\theta in the above expression gives exactly the expression derived in step 2 above. Therefore, to recover the state 2nθ\vert2^n\theta\rangle, apply an inverse Fourier transform on the auxiliary register. Doing so, we find

ψ3=12n2k=02n1e2πiθkkψQFTn112nx=02n1k=02n1e2πik2n(x2nθ)xψ\vert\psi_3\rangle = \frac {1}{2^{\frac {n}{2}}}\sum _{k=0}^{2^{n}-1}e^{\boldsymbol{2\pi i} \theta k}|k\rangle \otimes | \psi \rangle \xrightarrow{\mathcal{QFT}_n^{-1}} \frac {1}{2^n}\sum _{x=0}^{2^{n}-1}\sum _{k=0}^{2^{n}-1} e^{-\frac{2\pi i k}{2^n}(x - 2^n \theta)} |x\rangle \otimes |\psi\rangle

v. Measurement: The above expression peaks near x=2nθx = 2^n\theta. For the case when 2nθ2^n\theta is an integer, measuring in the computational basis gives the phase in the auxiliary register with high probability:

ψ4=2nθψ|\psi_4\rangle = | 2^n \theta \rangle \otimes | \psi \rangle

For the case when 2nθ2^n\theta is not an integer, it can be shown that the above expression still peaks near x=2nθx = 2^n\theta with probability better than 4/π240%4/\pi^2 \approx 40\% [1].

2. Example: T-gate

Let’s take a gate we know well, the TT-gate, and use Quantum Phase Estimation to estimate its phase. You will remember that the TT-gate adds a phase of eiπ4e^\frac{i\pi}{4} to the state 1|1\rangle:

T1=[100eiπ4][01]=eiπ41T|1\rangle = \begin{bmatrix} 1 & 0\\ 0 & e^\frac{i\pi}{4}\\ \end{bmatrix} \begin{bmatrix} 0\\ 1\\ \end{bmatrix} = e^\frac{i\pi}{4}|1\rangle

Since QPE will give us θ\theta where:

T1=e2iπθ1T|1\rangle = e^{2i\pi\theta}|1\rangle

We expect to find:

θ=18\theta = \frac{1}{8}

In this example we will use three qubits and obtain an exact result (not an estimation!)

2.1 Creating the Circuit

Let's first prepare our environment:

#initialization import matplotlib.pyplot as plt import numpy as np import math # importing Qiskit from qiskit import IBMQ, Aer, transpile, assemble from qiskit import QuantumCircuit, ClassicalRegister, QuantumRegister # import basic plot tools and circuits from qiskit.visualization import plot_histogram from qiskit.circuit.library import QFT

Now, set up the quantum circuit. We will use four qubits -- qubits 0 to 2 as counting qubits, and qubit 3 as the eigenstate of the unitary operator (TT).

We initialize ψ=1\vert\psi\rangle = \vert1\rangle by applying an XX gate:

qpe = QuantumCircuit(4, 3) qpe.x(3) qpe.draw()
Image in a Jupyter notebook

Next, we apply Hadamard gates to the counting qubits:

for qubit in range(3): qpe.h(qubit) qpe.draw()
Image in a Jupyter notebook

Next we perform the controlled unitary operations. Remember: Qiskit orders its qubits the opposite way round to the circuit diagram in the overview.

repetitions = 1 for counting_qubit in range(3): for i in range(repetitions): qpe.cp(math.pi/4, counting_qubit, 3); # This is CU repetitions *= 2 qpe.draw()
Image in a Jupyter notebook

We apply the inverse quantum Fourier transformation to convert the state of the counting register, then measure the counting register:

qpe.barrier() # Apply inverse QFT qpe = qpe.compose(QFT(3, inverse=True), [0,1,2]) # Measure qpe.barrier() for n in range(3): qpe.measure(n,n) qpe.draw()
Image in a Jupyter notebook

2.2 Results

aer_sim = Aer.get_backend('aer_simulator') shots = 2048 t_qpe = transpile(qpe, aer_sim) results = aer_sim.run(t_qpe, shots=shots).result() answer = results.get_counts() plot_histogram(answer)
Image in a Jupyter notebook

We see we get one result (001) with certainty, which translates to the decimal: 1. We now need to divide our result (1) by 2n2^n to get θ\theta:

θ=123=18\theta = \frac{1}{2^3} = \frac{1}{8}

This is exactly the result we expected!

3. Example: Getting More Precision

3.1 The Problem

Instead of a TT-gate, let’s use a gate with θ=13\theta = \frac{1}{3}. We set up our circuit as with the last example:

# Create and set up circuit qpe2 = QuantumCircuit(4, 3) # Apply H-Gates to counting qubits: for qubit in range(3): qpe2.h(qubit) # Prepare our eigenstate |psi>: qpe2.x(3) # Do the controlled-U operations: angle = 2*math.pi/3 repetitions = 1 for counting_qubit in range(3): for i in range(repetitions): qpe2.cp(angle, counting_qubit, 3); repetitions *= 2 # Do the inverse QFT: qpe2 = qpe2.compose(QFT(3, inverse=True), [0,1,2]) # Measure of course! for n in range(3): qpe2.measure(n,n) qpe2.draw()
Image in a Jupyter notebook
# Let's see the results! aer_sim = Aer.get_backend('aer_simulator') shots = 4096 t_qpe2 = transpile(qpe2, aer_sim) results = aer_sim.run(t_qpe2, shots=shots).result() answer = results.get_counts() plot_histogram(answer)
Image in a Jupyter notebook

We are expecting the result θ=0.3333\theta = 0.3333\dots, and we see our most likely results are 010(bin) = 2(dec) and 011(bin) = 3(dec). These two results would tell us that θ=0.25\theta = 0.25 (off by 25%) and θ=0.375\theta = 0.375 (off by 13%) respectively. The true value of θ\theta lies between the values we can get from our counting bits, and this gives us uncertainty and imprecision.

3.2 The Solution

To get more precision we simply add more counting qubits. We are going to add two more counting qubits:

# Create and set up circuit qpe3 = QuantumCircuit(6, 5) # Apply H-Gates to counting qubits: for qubit in range(5): qpe3.h(qubit) # Prepare our eigenstate |psi>: qpe3.x(5) # Do the controlled-U operations: angle = 2*math.pi/3 repetitions = 1 for counting_qubit in range(5): for i in range(repetitions): qpe3.cp(angle, counting_qubit, 5); repetitions *= 2 # Do the inverse QFT: qpe3 = qpe3.compose(QFT(5, inverse=True), range(5)) # Measure of course! qpe3.barrier() for n in range(5): qpe3.measure(n,n) qpe3.draw()
Image in a Jupyter notebook
# Let's see the results! aer_sim = Aer.get_backend('aer_simulator') shots = 4096 t_qpe3 = transpile(qpe3, aer_sim) results = aer_sim.run(t_qpe3, shots=shots).result() answer = results.get_counts() plot_histogram(answer)
Image in a Jupyter notebook

The two most likely measurements are now 01011 (decimal 11) and 01010 (decimal 10). Measuring these results would tell us θ\theta is:

θ=1125=0.344,   or     θ=1025=0.313\theta = \frac{11}{2^5} = 0.344,\;\text{ or }\;\; \theta = \frac{10}{2^5} = 0.313

These two results differ from 13\frac{1}{3} by 3% and 6% respectively. A much better precision!

4. Experiment with Real Devices

4.1 Circuit from 2.1

We can run the circuit in section 2.1 on a real device, let's remind ourselves of the circuit:

qpe.draw()
Image in a Jupyter notebook
from qiskit.providers.ibmq import least_busy IBMQ.load_account() from qiskit.tools.monitor import job_monitor provider = IBMQ.get_provider(hub='ibm-q') backend = least_busy(provider.backends(filters=lambda x: x.configuration().n_qubits >= (n+1) and not x.configuration().simulator and x.status().operational==True)) print("least busy backend: ", backend)
least busy backend: ibmq_belem
# Run with 2048 shots shots = 2048 t_qpe = transpile(qpe, backend, optimization_level=3) job = backend.run(t_qpe, shots=shots) job_monitor(job)
Job Status: job has successfully run
# get the results from the computation results = job.result() answer = results.get_counts(qpe) plot_histogram(answer)
Image in a Jupyter notebook

We can hopefully see that the most likely result is 001 which is the result we would expect from the simulator. Unlike the simulator, there is a probability of measuring something other than 001, this is due to noise and gate errors in the quantum computer.

5. Exercises

  1. Try the experiments above with different gates (CNOT\text{CNOT}, Controlled-SS, Controlled-TT^\dagger), what results do you expect? What results do you get?

  2. Try the experiment with a Controlled-YY-gate, do you get the result you expected? (Hint: Remember to make sure ψ|\psi\rangle is an eigenstate of YY!)

6. Looking Forward

The quantum phase estimation algorithm may seem pointless, since we have to know θ\theta to perform the controlled-UU operations on our quantum computer. We will see in later chapters that it is possible to create circuits for which we don’t know θ\theta, and for which learning theta can tell us something very useful (most famously how to factor a number!)

7. References

[1] Michael A. Nielsen and Isaac L. Chuang. 2011. Quantum Computation and Quantum Information: 10th Anniversary Edition (10th ed.). Cambridge University Press, New York, NY, USA.

8. Contributors

03/20/2020 — Hwajung Kang (@HwajungKang) — Fixed inconsistencies with qubit ordering

import qiskit.tools.jupyter %qiskit_version_table
/usr/local/anaconda3/envs/terra-unstable/lib/python3.9/site-packages/qiskit/aqua/__init__.py:86: DeprecationWarning: The package qiskit.aqua is deprecated. It was moved/refactored to qiskit-terra For more information see <https://github.com/Qiskit/qiskit-aqua/blob/main/README.md#migration-guide> warn_package('aqua', 'qiskit-terra')