-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathdj.py
186 lines (141 loc) · 4.14 KB
/
dj.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
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
# -*- coding: utf-8 -*-
"""
Created on Sat May 2 15:50:05 2020
@author: sathe
"""
#, get_qc
#from pyquil.gates import *
#import numpy as np
## construct a Bell State program
#p = Program(H(0), CNOT(0, 1))
## run the program on a QVM
#qc = get_qc('9q-square-qvm')
#result = qc.run_and_measure(p, trials=10)
#print(result[0])
#print(result[1])
## First, I want to run the DJ algorithm for f:{0,1} -> {0,1}
## Consider f(0)=f(1)=0
## Then, Uf |xy>=|xy>. or Uf = identity
from pyquil import Program, get_qc
from pyquil.quil import DefGate
from pyquil.gates import *
from itertools import combinations
import numpy as np
#%% Trial processing for constant f -- seems to work
#Uf_matrix = np.eye(4)
##print(Uf_matrix)
## Get the Quil definition for the new gate
#Uf_quil_def = DefGate("Uf", Uf_matrix)
## Get the gate constructor
#Uf_gate = Uf_quil_def.get_constructor()
#
#p = Program()
#ro = p.declare('ro', 'BIT', 1)
#p += X(1)
#p += H(0)
#p += H(1)
#p += Uf_quil_def
#p += Uf_gate(0,1)
#p += H(0)
#p += MEASURE(0, ro[0])
#print(p)
#
#qc = get_qc('2q-qvm') # You can make any 'nq-qvm' this way for any reasonable 'n'
#executable = qc.compile(p)
#
#num_runs = 10
#result = [qc.run(executable)[0,0] for i in range(num_runs)]
#print(result)
#%% Create all possible functions
def create_function(n):
"""
Takes as input an integer n, and outputs a list of functions f:{0,1}^n --> {0,1} which are either balanced or constant
"""
N = 2**n
list_of_numbers = list(range(N))
comb = combinations(list_of_numbers, int(N/2))
func_list_balanced = []
for i in list(comb):
out_list = np.zeros(N)
for j in list(i):
out_list[j] = 1
func_list_balanced.append(out_list)
func_list_constant = [np.zeros(N), np.ones(N)]
return func_list_balanced, func_list_constant
n = 3
func_list_balanced, func_list_constant = create_function(3)
#print(func_list_balanced)
#print(func_list_constant)
#%% Create Uf for a given f
#n=5
#for i in range(2**n):
# bin_rep = bin(i)
# m = n + 2 - len(bin_rep)
# bin_rep = bin_rep.replace("0b", '0' * m)
# print(bin_rep)
def create_Uf(f,n):
"""
f is an array
n is an integer (number of bits on which f acts)
"""
N = 2**(n+1)
Uf = np.zeros([N,N])
for i in range(2**n):
f_val = int(f[i])
bin_rep = bin(i)
m = n + 2 - len(bin_rep)
bin_rep = bin_rep.replace("0b", '0' * m)
inp_1 = bin_rep + '0'
out_1 = bin_rep + str(f_val)
Uf[int(out_1,2),int(inp_1,2)] = 1
inp_2 = bin_rep + '1'
out_2 = bin_rep + str(int(not(f_val)))
Uf[int(out_2,2),int(inp_2,2)] = 1
return Uf
#Uf = create_Uf(func_list_balanced[6], n)
#print(Uf)
#%% Define DJ algorithm which predicts whether the function is balanced or constant
n = 1
func_list_balanced, func_list_constant = create_function(n)
Uf_matrix = create_Uf(func_list_balanced[0], n)
print("Done creating Uf matrix")
Uf_quil_def = DefGate("Uf", Uf_matrix)
# Get the gate constructor
Uf_gate = Uf_quil_def.get_constructor()
def DJ(Uf_quil_def, Uf_gate, n):
"""
Deutsch-Jozsa algorithm
Input:
Uf_gate object: which acts on n+1 qubits
n: Integer, the length on input bit strings which f takes.
Output:
Integer: 0 if function is balanced, and 1 if function is constant
"""
p = Program()
ro = p.declare('ro', 'BIT', n)
p += X(n)
for gate_ind in range(n+1):
p += H(gate_ind)
p += Uf_quil_def
p += Uf_gate(*tuple(range(n+1)))
for gate_ind in range(n):
p += H(gate_ind)
for gate_ind in range(n):
p += MEASURE(gate_ind, ro[gate_ind])
# print(p)
qc = get_qc(str(n+1)+'q-qvm')
executable = qc.compile(p)
result = np.reshape(qc.run(executable),n)
print("Measured state is "+str(result)[1:-1])
if np.sum(result) != 0:
print("Function is balanced")
return 0
else:
print("function is constant")
return 1
DJ_output = DJ(Uf_quil_def, Uf_gate, n)
#%%
#Trying out stuff
def func(a,b,c,d):
print(a+b+c+d)
func(*tuple(range(4)))