Q Fourier Transform
A
"""
Build the quantum Fourier transform (QFT) for a desired
number of qubits using the Qiskit framework.
This circuit can be used as a building block to design
Shor's algorithm in quantum computing, as well as
quantum phase estimation, among others.
The circuit is simulated with Qiskit's built-in, pure-Python
``BasicSimulator`` (no compiled ``qiskit-aer`` backend required),
so it runs anywhere Qiskit itself installs.
References:
https://en.wikipedia.org/wiki/Quantum_Fourier_transform
https://quantum.cloud.ibm.com/docs/en/api/qiskit/qiskit.circuit.library.QFT
"""
import math
import numpy as np
import qiskit
from qiskit import ClassicalRegister, QuantumCircuit, QuantumRegister, transpile
from qiskit.providers.basic_provider import BasicSimulator
def quantum_fourier_transform(number_of_qubits: int = 3) -> qiskit.result.counts.Counts:
"""
Build and simulate the quantum Fourier transform applied to the all-zero
state ``|0...0>``. The QFT maps ``|0...0>`` to a uniform superposition, so
every computational-basis outcome is (up to shot noise) equally likely.
# quantum circuit for number_of_qubits = 3:
┌───┐
qr_0: ──────■──────────────────────■───────┤ H ├─X─
│ ┌───┐ │P(π/2) └───┘ │
qr_1: ──────┼────────■───────┤ H ├─■─────────────┼─
┌───┐ │P(π/4) │P(π/2) └───┘ │
qr_2: ┤ H ├─■────────■───────────────────────────X─
└───┘
cr: 3/═════════════════════════════════════════════
Args:
number_of_qubits : number of qubits
Returns:
qiskit.result.counts.Counts: measurement counts over 10,000 shots.
The simulation is seeded, so the set of observed outcomes is reproducible:
>>> counts = quantum_fourier_transform(2)
>>> sorted(counts)
['00', '01', '10', '11']
>>> sum(counts.values())
10000
>>> quantum_fourier_transform(-1)
Traceback (most recent call last):
...
ValueError: number of qubits must be > 0.
>>> quantum_fourier_transform('a')
Traceback (most recent call last):
...
TypeError: number of qubits must be a integer.
>>> quantum_fourier_transform(100)
Traceback (most recent call last):
...
ValueError: number of qubits too large to simulate(>10).
>>> quantum_fourier_transform(0.5)
Traceback (most recent call last):
...
ValueError: number of qubits must be an exact integer.
>>> result = quantum_fourier_transform(2)
>>> 2350<=result['10']<=2600
True
>>> 2350<=result['00']<=2600
True
>>> 2350<=result['11']<=2600
True
>>> 2350<=result['01']<=2600
True
>>> res = quantum_fourier_transform(3)
>>> 1150<=res['000']<=1350 and 1150<=res['001']<=1350
True
>>> 1150<=res['010']<=1350 and 1150<=res['100']<=1350
True
>>> 1150<=res['101']<=1350 and 1150<=res['110']<=1350
True
>>> 1150<=res['011']<=1350 and 1150<=res['111']<=1350
True
"""
if isinstance(number_of_qubits, str):
raise TypeError("number of qubits must be a integer.")
if number_of_qubits <= 0:
raise ValueError("number of qubits must be > 0.")
if math.floor(number_of_qubits) != number_of_qubits:
raise ValueError("number of qubits must be exact integer.")
if number_of_qubits > 10:
raise ValueError("number of qubits too large to simulate(>10).")
qr = QuantumRegister(number_of_qubits, "qr")
cr = ClassicalRegister(number_of_qubits, "cr")
quantum_circuit = QuantumCircuit(qr, cr)
counter = number_of_qubits
for i in range(counter):
quantum_circuit.h(number_of_qubits - i - 1)
counter -= 1
for j in range(counter):
quantum_circuit.cp(np.pi / 2 ** (counter - j), j, counter)
for k in range(number_of_qubits // 2):
quantum_circuit.swap(k, number_of_qubits - k - 1)
# measure all the qubits
quantum_circuit.measure(qr, cr)
# simulate with 10000 shots on the pure-Python BasicSimulator; seed the run
# so the observed outcomes are reproducible for the doctest above.
backend = BasicSimulator()
transpiled_circuit = transpile(quantum_circuit, backend)
job = backend.run(transpiled_circuit, shots=10_000, seed_simulator=42)
return job.result().get_counts(quantum_circuit)
if __name__ == "__main__":
import doctest
doctest.testmod()
print("Total count for quantum Fourier transform state is:")
print(f"{quantum_fourier_transform(3) = }")