import math
from qiskit import QuantumCircuit
from qiskit import Aer, execute
from qiskit.visualization import plot_histogram
Approximating pi has roots in QFT and QPE, a good application for both the concepts.
Resources used : https://www.youtube.com/watch?v=5kcoaanYyZw&t=622s; and https://www.youtube.com/watch?v=YpcT8u2a2jcm
The basic step by step process
Build the first part of QPE before the Inverse QFT, it involves a series of Hadamard and Unitary
= 4
n = QuantumCircuit(n + 1, n) circuit
def qpe_initial(circuit, n):
range(n))
circuit.h(
circuit.x(n)
for x in reversed(range(n)):
for a in range(2**(n-1-x)):
1, n-1-x, n)
circuit.cp(return circuit
= qpe_initial(circuit, n)
test 'mpl') test.draw(
Inverse QFT
def iqft(circuit, n):
for q in range(int(n/2)):
-q-1)
circuit.swap(q, nfor j in range(0,n):
for m in range(j):
-math.pi/float(2**(j-m)), m, j)
circuit.cp(
circuit.h(j)return circuit
= iqft(test, n)
test 'mpl') test.draw(
range(n), range(n)) test.measure(
<qiskit.circuit.instructionset.InstructionSet at 0x7fbdab490e20>
'mpl') test.draw(
= Aer.get_backend('qasm_simulator')
simulator = execute(test, backend=simulator, shots=10000).result().get_counts() counts
counts
{'1011': 46,
'1001': 44,
'0101': 166,
'1110': 71,
'0000': 175,
'1111': 93,
'1101': 50,
'1010': 45,
'1000': 39,
'0100': 478,
'1100': 58,
'0111': 63,
'0011': 4926,
'0001': 453,
'0110': 102,
'0010': 3191}
= max(counts, key=counts.get)
max_counts_result max_counts_result
'0011'
= int(max_counts_result, 2)
max_counts_result max_counts_result
3
= max_counts_result/2**n
theta = 1./(2*theta)
val val
2.6666666666666665
This seems ok, putting it all together
def estimate_pi(n):
print("estimating for qubit", n)
= QuantumCircuit(n + 1, n)
circuit = qpe_initial(circuit, n)
circuit = iqft(circuit, n)
circuit range(n), range(n))
circuit.measure(= execute(circuit, backend=simulator, shots=10000).result().get_counts()
counts = max(counts, key=counts.get)
max_counts_result = int(max_counts_result, 2)
max_counts_result = max_counts_result/2**n
theta = 1/(2*theta)
val return val
Kernel dies on 14th iteration, so restrict number of qubits to 14
= []
pi_values = 14
range_n for i in range(2, range_n):
pi_values.append(estimate_pi(i))
estimating for qubit 2
estimating for qubit 3
estimating for qubit 4
estimating for qubit 5
estimating for qubit 6
estimating for qubit 7
estimating for qubit 8
estimating for qubit 9
estimating for qubit 10
estimating for qubit 11
estimating for qubit 12
estimating for qubit 13
pi_values
[2.0,
4.0,
2.6666666666666665,
3.2,
3.2,
3.2,
3.1219512195121952,
3.1604938271604937,
3.1411042944785277,
3.1411042944785277,
3.1411042944785277,
3.1411042944785277]
Plot
import matplotlib.pyplot as plt
list(range(2,14)), pi_values)
plt.plot(list(range(2,14)), [math.pi]*len(list(range(2,14))), '--y')
plt.plot('Number of qubits', fontdict={'size':10})
plt.xlabel('$\pi$ and estimate of $\pi$', fontdict={'size':10}) plt.ylabel(
Text(0, 0.5, '$\\pi$ and estimate of $\\pi$')