-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathbernsteinvazirani.py
More file actions
135 lines (105 loc) · 4.05 KB
/
bernsteinvazirani.py
File metadata and controls
135 lines (105 loc) · 4.05 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
134
135
"""
This module implements the Bernstein-Vazirani Algorithm.
"""
from qiskit import Aer
from qiskit import QuantumCircuit, assemble, transpile
from qiskit.circuit.instruction import Instruction
class BVAlgorithm:
"""This class implements the Bernstein-Vazirani Algorithm."""
@staticmethod
def create_oracle_from_number(number: int) -> Instruction:
"""This method returns a Oracle block which will be used in
the Bernstein-Vazirani Algorithm.
Parameters
----------
number_str : str
The number in binary form as string.
Returns
-------
Instruction
Oracle block to be fed into the algorithm.
"""
# Convert the integer into binary string.
number_str = format(number, "b")
inputs_count = len(number_str)
# Create a quantum circuit with the number of input qubits + 1 output qubit.
oracle = QuantumCircuit(inputs_count + 1, inputs_count)
# Apply the CNOTs to the inputs as "1"s.
for index, qubit in enumerate(reversed(number_str)):
if qubit == "1":
oracle.cx(index, inputs_count)
inst = oracle.to_instruction()
inst.name = "SecretNumberOracle"
return inst
@staticmethod
def simulate(secret_number_oracle: Instruction) -> dict:
"""_summary_
Parameters
----------
secret_no_oracle : Instruction
The secret number to look for with the algoritm.
Returns
-------
dict
A dictionary with result attribute which is the found number.
"""
# Create the circuit.
circuit = BVAlgorithm._construct_the_circuit(secret_number_oracle)
# Run the simulation.
aer_sim = Aer.get_backend("aer_simulator")
transpiled_dj_circuit = transpile(circuit, aer_sim)
qobj = assemble(transpiled_dj_circuit)
results = aer_sim.run(qobj).result()
# Get the answer.
answer = results.get_counts()
answer_as_list = list(answer.keys())
answer_int = int(answer_as_list[0], 2)
return {"result": answer_int}
@staticmethod
def _construct_the_circuit(function_block: QuantumCircuit) -> QuantumCircuit:
"""It creates the circuit for the Bernstein-Vazirani Algorithm.
Parameters
----------
function_block : QuantumCircuit
The secret number block to check with the Bernstein-Vazirani Algorithm.
Returns
-------
QuantumCircuit
The circuit for the Bernstein-Vazirani Algorithm.
"""
# Get the number of input qubits.
input_length = function_block.num_qubits - 1
_circuit = QuantumCircuit(input_length + 1, input_length)
# Apply Hadamard gates to all input qubits.
for qubit in range(input_length):
_circuit.h(qubit)
# Convert the last qubit to |-) state.
_circuit.x(input_length)
_circuit.h(input_length)
_circuit.barrier()
# Apply the oracle block.
_circuit.append(
function_block,
range(function_block.num_qubits),
range(function_block.num_clbits),
)
_circuit.barrier()
# Apply Hadamard gates to all input qubits.
for qubit in range(input_length):
_circuit.h(qubit)
_circuit.barrier()
# Measure all input qubits and put them to classical bits.
for qubit in range(input_length):
_circuit.measure(qubit, qubit)
return _circuit
if __name__ == "__main__":
print("========================================")
print("Bernstein-Vazirani Algorithm Simulation")
print("========================================")
# Get the number of input qubits.
secret_number = int(input("> Enter the secret number to search for: "))
# Get the oracle block.
block_to_test = BVAlgorithm.create_oracle_from_number(secret_number)
# Run the algorithm.
result = BVAlgorithm.simulate(block_to_test)
print(f"Result: {result['result']}")