-
-
Notifications
You must be signed in to change notification settings - Fork 51.1k
Expand file tree
/
Copy pathq_fourier_transform.py
More file actions
133 lines (109 loc) · 4.84 KB
/
Copy pathq_fourier_transform.py
File metadata and controls
133 lines (109 loc) · 4.84 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
"""
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) = }")