-
Notifications
You must be signed in to change notification settings - Fork 14
/
qa_grover.py
67 lines (54 loc) · 2.16 KB
/
qa_grover.py
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
import numpy as np
from pyquil import Program, get_qc
from pyquil.gates import H, I
from pyquil.api import WavefunctionSimulator
#==============================================================================
# Construct quantum oracle (not a part of algorithm)
#==============================================================================
SEARCHED_STRING = "10"
N = len(SEARCHED_STRING)
oracle = np.zeros(shape=(2 ** N, 2 ** N))
for b in range(2 ** N):
if np.binary_repr(b, N) == SEARCHED_STRING:
oracle[b, b] = -1
else:
oracle[b, b] = 1
print(oracle)
#==============================================================================
# Grover's Search Algorithm
#==============================================================================
qc = get_qc('9q-qvm')
gr_prog = Program()
# \psi_0: Qubits initilization
qubits = list(reversed(range(N)))
gr_prog.inst([I(q) for q in qubits])
#print(WavefunctionSimulator().wavefunction(gr_prog))
# \psi_1: Apply Hadamard gates
gr_prog.inst([H(q) for q in qubits])
#print(WavefunctionSimulator().wavefunction(gr_prog))
# Define quantum oracle
ORACLE_GATE_NAME = "GROVER_ORACLE"
gr_prog.defgate(ORACLE_GATE_NAME, oracle)
# Define inversion around the mean
DIFFUSION_GATE_NAME = "DIFFUSION"
diffusion = 2.0 * np.full((2**N, 2**N), 1/(2**N)) - np.eye(2**N)
gr_prog.defgate(DIFFUSION_GATE_NAME, diffusion)
# Number of algorithm iterations
N_ITER = int(np.pi / 4 * np.sqrt(2**N))
# Loop
for i in range(N_ITER):
# \psi_2^i: Apply Quantum Oracle
gr_prog.inst(tuple([ORACLE_GATE_NAME] + qubits))
#print(WavefunctionSimulator().wavefunction(gr_prog))
# \psi_3^i: Apply Inversion around the mean
gr_prog.inst(tuple([DIFFUSION_GATE_NAME] + qubits))
#print(WavefunctionSimulator().wavefunction(gr_prog))
# \psi_5: Measure
ro = gr_prog.declare('ro', 'BIT', N) # Classical registry storing the results
for q in qubits:
gr_prog.measure(q, ro[q])
# Compile and run
prog_exec = qc.compile(gr_prog)
ret = qc.run(prog_exec)
ret_string = ''.join([str(q) for q in reversed(ret[0])])
print("The searched string is: {}".format(ret_string))