-
-
Notifications
You must be signed in to change notification settings - Fork 4
/
Copy pathhello.py
141 lines (106 loc) · 4.3 KB
/
hello.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
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
136
137
138
139
140
141
import random
from math import floor, log
from lib.util import execute, num_qubits, random_letters
from lib.grover import grover
from lib.oracles.logic import oracle
def init(target, n):
# Initialize an array of random letters, including the target ones in the string.
arr = random_letters(n)
# Store used indices so that we don't overwrite target letters.
indices = [-1]
# Select random indices for the target letters.
for i in range(len(target)):
index = -1
# Select a random index until we find one that hasn't been used.
while index in indices:
index = random.randint(0, n - 1)
# Set the target letter at the selected index.
arr[index] = target[i]
# Add the index to the list of used indices.
indices.append(index)
return arr
def logic(arr, target, n):
# Finds the indices within arr for each position of target letter and returns a Python function as a string to be used in an oracle.
prog = '''def oracle_func(_PARAMS_) -> Int1:
return _CLAUSE_'''
# Insert the parameters for the function, based upon the number of qubits needed for target.
qubits = floor(log(n, 2))
params = ''
for i in range(qubits):
# x1: Int1, x2: Int1, x3: Int1
params += 'x' + str(i + 1) + ': Int1, '
# Remove the trailing comma.
params = params[:-2]
prog = prog.replace('_PARAMS_', params)
# Insert the clauses for the function, based upon the bit location(s) for the target letter.
# (not x1 and not x2 and not x3) or (x1 and x2 and not x3)
clauses = ''
# Find the next index of the target letter.
index = arr.index(target, 0)
while index != -1:
# Convert the index to a binary string.
bin_str = bin(index)[2:]
# Pad the binary string with zeros to the length of the qubits.
bin_str = bin_str.zfill(qubits)
# Generate the logical string for the clause.
clause = ''
for j in range(len(bin_str)-1, -1, -1):
if bin_str[j] == '0':
clause += 'not '
clause += 'x' + str(len(bin_str) - j) + ' and '
# Trim trailing 'and ' from the clause.
clause = clause[:-5]
# Add parentheses to the clause.
clause = '(' + clause + ')'
# Insert the clause into the clauses.
clauses += clause + ' or '
# Find the next index matching the letter (if any more exist).
try:
index = arr.index(target, index + 1)
except ValueError:
# No more letters found.
index = -1
# Trim trailing 'or ' from the clauses.
clauses = clauses[:-4]
prog = prog.replace('_CLAUSE_', clauses)
return prog
def main(phrase):
execute.provider = None
# Calculate the number of qubits needed to represent the number of letters in the target.
qubits = num_qubits(len(phrase))
bits = 2 ** qubits
arr = init(phrase, bits)
print(str(qubits) + ' qubits, ' + str(bits) + ' possibilities')
print('Using random letters:')
print(arr)
# Use the oracle to find the indices of the target letters.
indices = []
for letter in phrase:
print("Finding letter '" + letter + "'")
# Generate a logical function for the oracle.
prog = logic(arr, letter, bits)
# Generate the quantum circuit.
qc = grover(oracle, prog, qubits)
#print(qc.draw())
# Execute the quantum circuit.
result = execute(qc)
# Get the resulting hit counts.
counts = result.get_counts()
print(counts)
# Find the most frequent hit count.
key = max(counts, key=counts.get)
# Since the quantum computer returns a binary string (one bit for each qubit), we need to convert it to an integer.
index = int(key, 2)
# Print the resulting letter selected by the quantum circuit.
print(arr[index])
indices.append({'binary': key, 'index': index, 'letter': letter})
print('\nRandom letters:')
print(arr)
print()
print('Final result from the quantum circuit:\n')
for i in range(len(indices)):
letter = arr[indices[i]['index']]
index = indices[i]['index']
binary = indices[i]['binary']
print(letter + ' (at index ' + str(index) + ' [' + binary + '])')
main('hello')