tequila-basic 1.9.9__py3-none-any.whl → 1.9.10__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- tequila/__init__.py +29 -14
- tequila/apps/__init__.py +14 -5
- tequila/apps/_unary_state_prep_impl.py +145 -112
- tequila/apps/adapt/__init__.py +9 -1
- tequila/apps/adapt/adapt.py +154 -113
- tequila/apps/krylov/__init__.py +1 -1
- tequila/apps/krylov/krylov.py +23 -21
- tequila/apps/robustness/helpers.py +10 -6
- tequila/apps/robustness/interval.py +238 -156
- tequila/apps/unary_state_prep.py +29 -23
- tequila/autograd_imports.py +8 -5
- tequila/circuit/__init__.py +2 -1
- tequila/circuit/_gates_impl.py +135 -67
- tequila/circuit/circuit.py +163 -79
- tequila/circuit/compiler.py +114 -105
- tequila/circuit/gates.py +288 -120
- tequila/circuit/gradient.py +35 -23
- tequila/circuit/noise.py +83 -74
- tequila/circuit/postselection.py +120 -0
- tequila/circuit/pyzx.py +10 -6
- tequila/circuit/qasm.py +201 -83
- tequila/circuit/qpic.py +63 -61
- tequila/grouping/binary_rep.py +148 -146
- tequila/grouping/binary_utils.py +84 -75
- tequila/grouping/compile_groups.py +334 -230
- tequila/grouping/ev_utils.py +77 -41
- tequila/grouping/fermionic_functions.py +383 -308
- tequila/grouping/fermionic_methods.py +170 -123
- tequila/grouping/overlapping_methods.py +69 -52
- tequila/hamiltonian/paulis.py +12 -13
- tequila/hamiltonian/paulistring.py +1 -1
- tequila/hamiltonian/qubit_hamiltonian.py +45 -35
- tequila/ml/__init__.py +1 -0
- tequila/ml/interface_torch.py +19 -16
- tequila/ml/ml_api.py +11 -10
- tequila/ml/utils_ml.py +12 -11
- tequila/objective/__init__.py +8 -3
- tequila/objective/braket.py +55 -47
- tequila/objective/objective.py +87 -55
- tequila/objective/qtensor.py +36 -27
- tequila/optimizers/__init__.py +31 -23
- tequila/optimizers/_containers.py +11 -7
- tequila/optimizers/optimizer_base.py +111 -83
- tequila/optimizers/optimizer_gd.py +258 -231
- tequila/optimizers/optimizer_gpyopt.py +56 -42
- tequila/optimizers/optimizer_scipy.py +157 -112
- tequila/quantumchemistry/__init__.py +66 -38
- tequila/quantumchemistry/chemistry_tools.py +393 -209
- tequila/quantumchemistry/encodings.py +121 -13
- tequila/quantumchemistry/madness_interface.py +170 -96
- tequila/quantumchemistry/orbital_optimizer.py +86 -41
- tequila/quantumchemistry/psi4_interface.py +166 -97
- tequila/quantumchemistry/pyscf_interface.py +70 -23
- tequila/quantumchemistry/qc_base.py +866 -414
- tequila/simulators/__init__.py +0 -3
- tequila/simulators/simulator_api.py +247 -105
- tequila/simulators/simulator_aqt.py +102 -0
- tequila/simulators/simulator_base.py +147 -53
- tequila/simulators/simulator_cirq.py +58 -42
- tequila/simulators/simulator_cudaq.py +600 -0
- tequila/simulators/simulator_ddsim.py +390 -0
- tequila/simulators/simulator_mqp.py +30 -0
- tequila/simulators/simulator_pyquil.py +190 -171
- tequila/simulators/simulator_qibo.py +95 -87
- tequila/simulators/simulator_qiskit.py +119 -107
- tequila/simulators/simulator_qlm.py +52 -26
- tequila/simulators/simulator_qulacs.py +74 -52
- tequila/simulators/simulator_spex.py +95 -60
- tequila/simulators/simulator_symbolic.py +6 -5
- tequila/simulators/test_spex_simulator.py +8 -11
- tequila/tools/convenience.py +4 -4
- tequila/tools/qng.py +72 -64
- tequila/tools/random_generators.py +38 -34
- tequila/utils/bitstrings.py +7 -7
- tequila/utils/exceptions.py +19 -5
- tequila/utils/joined_transformation.py +8 -10
- tequila/utils/keymap.py +0 -5
- tequila/utils/misc.py +6 -4
- tequila/version.py +1 -1
- tequila/wavefunction/qubit_wavefunction.py +47 -28
- {tequila_basic-1.9.9.dist-info → tequila_basic-1.9.10.dist-info}/METADATA +13 -16
- tequila_basic-1.9.10.dist-info/RECORD +93 -0
- {tequila_basic-1.9.9.dist-info → tequila_basic-1.9.10.dist-info}/WHEEL +1 -1
- tequila_basic-1.9.9.dist-info/RECORD +0 -88
- {tequila_basic-1.9.9.dist-info → tequila_basic-1.9.10.dist-info}/licenses/LICENSE +0 -0
- {tequila_basic-1.9.9.dist-info → tequila_basic-1.9.10.dist-info}/top_level.txt +0 -0
@@ -1,4 +1,4 @@
|
|
1
|
-
|
1
|
+
"""
|
2
2
|
A program that can generate an arbitrary quantum state.
|
3
3
|
|
4
4
|
Some conditions: if the number of states exceed the total number of bits,
|
@@ -8,8 +8,7 @@ Code by Maha Kesebi, Toronto 2019
|
|
8
8
|
Implemented with OpenVQE structures
|
9
9
|
|
10
10
|
Needs complete re-implementation at some point
|
11
|
-
|
12
|
-
'''
|
11
|
+
"""
|
13
12
|
|
14
13
|
from tequila.circuit import QCircuit
|
15
14
|
from tequila.circuit.gates import CNOT, Ry, X
|
@@ -33,10 +32,9 @@ class SympyVariable(Variable):
|
|
33
32
|
|
34
33
|
|
35
34
|
class UnaryStatePrepImpl:
|
36
|
-
|
37
35
|
def alphabet(self, i: int) -> str:
|
38
36
|
return self.alphabets[i]
|
39
|
-
#return "angle_{i}".format(i=i)
|
37
|
+
# return "angle_{i}".format(i=i)
|
40
38
|
|
41
39
|
def __init__(self):
|
42
40
|
self.left_compressed = []
|
@@ -44,14 +42,41 @@ class UnaryStatePrepImpl:
|
|
44
42
|
|
45
43
|
# currenyly needs one-character symbols
|
46
44
|
# needs complete reimplementation
|
47
|
-
self.alphabets = [
|
45
|
+
self.alphabets = [
|
46
|
+
"a",
|
47
|
+
"b",
|
48
|
+
"c",
|
49
|
+
"d",
|
50
|
+
"e",
|
51
|
+
"f",
|
52
|
+
"g",
|
53
|
+
"h",
|
54
|
+
"i",
|
55
|
+
"j",
|
56
|
+
"k",
|
57
|
+
"l",
|
58
|
+
"m",
|
59
|
+
"n",
|
60
|
+
"o",
|
61
|
+
"p",
|
62
|
+
"q",
|
63
|
+
"r",
|
64
|
+
"s",
|
65
|
+
"t",
|
66
|
+
"u",
|
67
|
+
"v",
|
68
|
+
"w",
|
69
|
+
"x",
|
70
|
+
"y",
|
71
|
+
"z",
|
72
|
+
]
|
48
73
|
|
49
74
|
self.silenced = True
|
50
75
|
|
51
76
|
self.coefficients = []
|
52
77
|
self.c_i = 0
|
53
78
|
|
54
|
-
|
79
|
+
"""
|
55
80
|
Calculates the Hamming distance between two strings of binary numbers.
|
56
81
|
notes: if one of the strings contains a symbol (compressed) at an index
|
57
82
|
where the other string is not compressed, then the H_dist is incremented
|
@@ -65,32 +90,30 @@ class UnaryStatePrepImpl:
|
|
65
90
|
returns a list where the first element is the distance, and the second
|
66
91
|
element is a list of the different indices of which the two strings
|
67
92
|
differ.
|
68
|
-
|
93
|
+
"""
|
69
94
|
|
70
95
|
def calc_H_distance(self, s1, s2):
|
71
|
-
|
72
96
|
distance = 0
|
73
97
|
diff_indices = []
|
74
98
|
for i in range(len(s1)):
|
75
99
|
if s1[i] != s2[i]:
|
76
|
-
if (s1[i] !=
|
77
|
-
if not ((s1[i] !=
|
100
|
+
if (s1[i] != "0" and s1[i] != "1") or (s2[i] != "0" and s2[i] != "1"):
|
101
|
+
if not ((s1[i] != "0" and s1[i] != "1") and (s2[i] != "0" and s2[i] != "1")):
|
78
102
|
distance += 1
|
79
103
|
distance += 1
|
80
104
|
diff_indices.append(i)
|
81
105
|
|
82
106
|
return [distance, diff_indices] ### type [ int, list[int, int ...]]
|
83
107
|
|
84
|
-
|
108
|
+
"""
|
85
109
|
This function find the H_dist between all different combination of pairs
|
86
110
|
in s.
|
87
111
|
|
88
112
|
Returns a dictionary where the keys represent the Hamming distance, and the
|
89
113
|
values are a list containing lists of the different pairs that have that H_dist
|
90
|
-
|
114
|
+
"""
|
91
115
|
|
92
116
|
def get_pairs(self, s):
|
93
|
-
|
94
117
|
# intialize dictionary according to length of s
|
95
118
|
dt = {}
|
96
119
|
for length in range(len(s[0]) + 2):
|
@@ -108,7 +131,7 @@ class UnaryStatePrepImpl:
|
|
108
131
|
|
109
132
|
return dt
|
110
133
|
|
111
|
-
while
|
134
|
+
while i < len(s) - 1:
|
112
135
|
if j >= len(s) - 1 and i == len(s) - 2:
|
113
136
|
break
|
114
137
|
|
@@ -127,7 +150,7 @@ class UnaryStatePrepImpl:
|
|
127
150
|
|
128
151
|
return dt ### tpye dict{ key=int: value = list[ list[string, string], list[str, str], ..] }
|
129
152
|
|
130
|
-
|
153
|
+
"""
|
131
154
|
This function takes s (a list of the states) and 2 indices. It find all
|
132
155
|
possible CNOT moves to be made
|
133
156
|
|
@@ -135,7 +158,7 @@ class UnaryStatePrepImpl:
|
|
135
158
|
and the value is a list of tuples, where the tuples hold possible control bit
|
136
159
|
index for that target index, and the control type represented by '0' for anti
|
137
160
|
and '1' for a normal control.
|
138
|
-
|
161
|
+
"""
|
139
162
|
|
140
163
|
def get_CNOT_moves(self, s, i1, i2):
|
141
164
|
targets = self.calc_H_distance(s[i1], s[i2])[1]
|
@@ -150,60 +173,68 @@ class UnaryStatePrepImpl:
|
|
150
173
|
poss_moves[target] = []
|
151
174
|
|
152
175
|
for index in range(len(s[i1])): # index of a bit in the string that could possibly be a control.
|
153
|
-
if
|
154
|
-
|
155
|
-
|
176
|
+
if (
|
177
|
+
index != target
|
178
|
+
and s[i1][index] != s[i2][index]
|
179
|
+
and (s[i1][index] == "0" or s[i1][index] == "1")
|
180
|
+
and (s[i2][index] == "0" or s[i2][index] == "1")
|
181
|
+
): # control != target & != other string & != 'a'
|
156
182
|
i = 0 # use i to loop through strings to check for control
|
157
183
|
flag = True
|
158
|
-
while i < len(s_to_check) and flag
|
184
|
+
while i < len(s_to_check) and flag:
|
159
185
|
if s[i1][index] == s_to_check[i][index] or not (
|
160
|
-
|
186
|
+
s_to_check[i][index] == "0" or s_to_check[i][index] == "1"
|
187
|
+
): # making sure its a 1 or 0
|
161
188
|
flag = False # can't be used for control
|
162
189
|
i += 1
|
163
190
|
|
164
|
-
if flag
|
191
|
+
if flag:
|
165
192
|
poss_moves[target].append((index, s[i1][index]))
|
166
193
|
|
167
194
|
##check with s[i2]
|
168
195
|
flag = True
|
169
196
|
i = 0 # loop through strings and check for control
|
170
197
|
|
171
|
-
while i < len(s_to_check) and flag
|
198
|
+
while i < len(s_to_check) and flag:
|
172
199
|
if s[i2][index] == s_to_check[i][index] or not (
|
173
|
-
|
200
|
+
s_to_check[i][index] == "0" or s_to_check[i][index] == "1"
|
201
|
+
):
|
174
202
|
flag = False
|
175
203
|
i += 1
|
176
204
|
|
177
|
-
if flag
|
205
|
+
if flag:
|
178
206
|
poss_moves[target].append((index, s[i2][index]))
|
179
207
|
|
180
208
|
return poss_moves # type is dict{key = int(taget bit's index): value = list[ tuple( int(control bit index), str(control type)), .. ] }
|
181
209
|
|
182
|
-
|
210
|
+
"""
|
183
211
|
|
184
|
-
|
212
|
+
"""
|
185
213
|
|
186
214
|
def get_CNOT_move_non_opt(self, s, i1, i2, target_index): # TODO: make this more opt
|
187
|
-
|
188
215
|
for index in range(len(s[i1])):
|
189
|
-
|
190
|
-
|
191
|
-
|
216
|
+
if (
|
217
|
+
index != target_index
|
218
|
+
and s[i1][index] != s[i2][index]
|
219
|
+
and (s[i1][index] == "0" or s[i1][index] == "1")
|
220
|
+
and (s[i2][index] == "0" or s[i2][index] == "1")
|
221
|
+
):
|
192
222
|
return index
|
193
223
|
|
194
|
-
raise Exception(
|
224
|
+
raise Exception("index not found")
|
195
225
|
|
196
|
-
|
226
|
+
"""
|
197
227
|
|
198
|
-
|
228
|
+
"""
|
199
229
|
|
200
230
|
def get_a_compression(self, s, i1, i2):
|
201
|
-
global alph_index
|
202
231
|
target_index = self.calc_H_distance(s[i1], s[i2])[1][
|
203
|
-
0
|
232
|
+
0
|
233
|
+
] # collect target index, the bit where they are different
|
204
234
|
move_param = None
|
205
235
|
|
206
|
-
if not self.silenced:
|
236
|
+
if not self.silenced:
|
237
|
+
print("compression of index {} in strings {} and {}".format(target_index, s[i1], s[i2]))
|
207
238
|
|
208
239
|
string_changed = s[i1]
|
209
240
|
string = s[i1]
|
@@ -220,14 +251,14 @@ class UnaryStatePrepImpl:
|
|
220
251
|
|
221
252
|
s.remove(s[i2])
|
222
253
|
|
223
|
-
if not self.silenced:
|
254
|
+
if not self.silenced:
|
255
|
+
print(s)
|
224
256
|
|
225
257
|
return [s, move_param]
|
226
258
|
|
227
259
|
def get_0_rotation(self, s, i):
|
228
|
-
|
229
260
|
for a_index in range(len(s[i])):
|
230
|
-
if not (s[i][a_index] ==
|
261
|
+
if not (s[i][a_index] == "0" or s[i][a_index] == "1"):
|
231
262
|
break
|
232
263
|
target_index = a_index
|
233
264
|
|
@@ -240,14 +271,13 @@ class UnaryStatePrepImpl:
|
|
240
271
|
|
241
272
|
for index in range(len(s[i])):
|
242
273
|
if index != target_index:
|
243
|
-
|
244
274
|
flag = True
|
245
275
|
|
246
276
|
for string in s_to_check:
|
247
277
|
if string[index] == s[i][index]:
|
248
278
|
flag = False # not a possible control
|
249
279
|
|
250
|
-
if flag
|
280
|
+
if flag:
|
251
281
|
c_type = s[i][index]
|
252
282
|
|
253
283
|
possible_indicies.append([index, c_type]) # tpye is a list[ int(index of control, str(c_type)]
|
@@ -261,14 +291,11 @@ class UnaryStatePrepImpl:
|
|
261
291
|
return possible_indicies
|
262
292
|
|
263
293
|
def make_move(self, s, i1, i2, move, m_type):
|
264
|
-
|
265
294
|
move_param = None
|
266
|
-
if m_type ==
|
267
|
-
|
295
|
+
if m_type == "ROT":
|
268
296
|
i = 0 # will be used to loop through s
|
269
297
|
|
270
298
|
while i < len(s) and i >= 0:
|
271
|
-
|
272
299
|
control_bit_value = s[i][move[0]] # a string
|
273
300
|
control_type = move[2] # a string
|
274
301
|
|
@@ -276,10 +303,9 @@ class UnaryStatePrepImpl:
|
|
276
303
|
target_bit_index = move[1] # an int
|
277
304
|
|
278
305
|
if control_bit_value == control_type: # control matches type -> make move
|
279
|
-
|
280
306
|
string = s[i]
|
281
307
|
string = list(string)
|
282
|
-
string[target_bit_index] =
|
308
|
+
string[target_bit_index] = "0"
|
283
309
|
string = "".join(string)
|
284
310
|
s[i] = string
|
285
311
|
|
@@ -287,30 +313,28 @@ class UnaryStatePrepImpl:
|
|
287
313
|
s.remove(s[i]) # here should add coefficients
|
288
314
|
i -= 1
|
289
315
|
|
290
|
-
if control_type ==
|
291
|
-
c_type =
|
316
|
+
if control_type == "0":
|
317
|
+
c_type = "anti"
|
292
318
|
else:
|
293
|
-
c_type =
|
319
|
+
c_type = "positive"
|
294
320
|
|
295
321
|
# if not silenced: print('move: {} control rotation from control bit index = {} and target bit index = {}'.format(c_type, control_bit_index, target_bit_index))
|
296
|
-
if c_type ==
|
297
|
-
m_type =
|
322
|
+
if c_type == "anti":
|
323
|
+
m_type = "aCROT"
|
298
324
|
else:
|
299
|
-
m_type =
|
325
|
+
m_type = "CROT"
|
300
326
|
|
301
327
|
move_param = [m_type, control_bit_index, target_bit_index]
|
302
|
-
if not self.silenced:
|
328
|
+
if not self.silenced:
|
329
|
+
print(move_param)
|
303
330
|
|
304
331
|
i += 1
|
305
332
|
|
306
333
|
return [s, move_param]
|
307
334
|
|
308
|
-
|
309
|
-
elif m_type == 'CNOT':
|
310
|
-
|
335
|
+
elif m_type == "CNOT":
|
311
336
|
i = 0
|
312
337
|
while i < len(s) and i >= 0:
|
313
|
-
|
314
338
|
control_bit_value = s[i][move[0]] # a string
|
315
339
|
control_type = move[2] # a string
|
316
340
|
|
@@ -318,19 +342,17 @@ class UnaryStatePrepImpl:
|
|
318
342
|
target_bit_index = move[1] # an int
|
319
343
|
|
320
344
|
if control_bit_value == control_type: # control matches type -> make move
|
321
|
-
if s[i][target_bit_index] ==
|
322
|
-
|
345
|
+
if s[i][target_bit_index] == "0":
|
323
346
|
string = s[i]
|
324
347
|
string = list(string)
|
325
|
-
string[target_bit_index] =
|
348
|
+
string[target_bit_index] = "1"
|
326
349
|
string = "".join(string)
|
327
350
|
s[i] = string
|
328
351
|
|
329
|
-
|
330
352
|
else:
|
331
353
|
string = s[i]
|
332
354
|
string = list(string)
|
333
|
-
string[target_bit_index] =
|
355
|
+
string[target_bit_index] = "0"
|
334
356
|
string = "".join(string)
|
335
357
|
s[i] = string
|
336
358
|
|
@@ -338,34 +360,34 @@ class UnaryStatePrepImpl:
|
|
338
360
|
s.remove(s[i]) # here should add coefficients
|
339
361
|
i -= 1
|
340
362
|
|
341
|
-
if control_type ==
|
342
|
-
c_type =
|
363
|
+
if control_type == "0":
|
364
|
+
c_type = "anti"
|
343
365
|
else:
|
344
|
-
c_type =
|
366
|
+
c_type = "positive"
|
345
367
|
|
346
368
|
# if not silenced: print('move: {} control NOT from control bit index = {} and target bit index = {}'.format(c_type, control_bit_index, target_bit_index))
|
347
|
-
if c_type ==
|
348
|
-
m_type =
|
369
|
+
if c_type == "anti":
|
370
|
+
m_type = "aCNOT"
|
349
371
|
move_param = [m_type, control_bit_index, target_bit_index]
|
350
372
|
|
351
|
-
if not self.silenced:
|
373
|
+
if not self.silenced:
|
374
|
+
print(move_param)
|
352
375
|
i += 1
|
353
376
|
|
354
377
|
return [s, move_param]
|
355
378
|
|
356
379
|
def get_next_move(self, s, moves_list):
|
357
|
-
|
358
380
|
# first_key = next(iter(d))
|
359
381
|
strings = s
|
360
382
|
|
361
383
|
if len(strings) == 1: # done
|
362
|
-
|
363
384
|
# add X gates to get '0000'
|
364
385
|
for index in range(len(strings[0])):
|
365
|
-
if strings[0][index] ==
|
366
|
-
move = [
|
386
|
+
if strings[0][index] == "1":
|
387
|
+
move = ["X", None, index]
|
367
388
|
moves_list.append(move)
|
368
|
-
if not self.silenced:
|
389
|
+
if not self.silenced:
|
390
|
+
print("DONE", " s=", s)
|
369
391
|
return
|
370
392
|
|
371
393
|
d = self.get_pairs(strings) # d is a dictionary returned from get_pairs fcn call
|
@@ -377,7 +399,7 @@ class UnaryStatePrepImpl:
|
|
377
399
|
keys = list(d.keys())
|
378
400
|
first_key = keys[i]
|
379
401
|
|
380
|
-
while found
|
402
|
+
while not found and i < len(keys) - 1:
|
381
403
|
if len(d[first_key]) != 0:
|
382
404
|
found = True
|
383
405
|
else:
|
@@ -394,7 +416,6 @@ class UnaryStatePrepImpl:
|
|
394
416
|
self.get_next_move(strings) # recursive call
|
395
417
|
|
396
418
|
if first_key == 1: # need a rot move
|
397
|
-
|
398
419
|
strings = self.get_a_compression(strings, index1, index2)[0]
|
399
420
|
####TODO add moves hereeee
|
400
421
|
|
@@ -404,39 +425,41 @@ class UnaryStatePrepImpl:
|
|
404
425
|
control_bit_index = possible_rot_controls[0][0]
|
405
426
|
control_type = possible_rot_controls[0][1]
|
406
427
|
for a_index in range(len(strings[index1])):
|
407
|
-
if not (strings[index1][a_index] ==
|
428
|
+
if not (strings[index1][a_index] == "0" or strings[index1][a_index] == "1"):
|
408
429
|
break
|
409
430
|
target_bit_index = a_index
|
410
431
|
|
411
432
|
move = [control_bit_index, target_bit_index, control_type] ###Type [int, int, str]
|
412
433
|
|
413
|
-
strings_moves = self.make_move(
|
414
|
-
|
434
|
+
strings_moves = self.make_move(
|
435
|
+
strings, index1, index2, move, "ROT"
|
436
|
+
) # fcn makes move and change all strings
|
415
437
|
strings = strings_moves[0]
|
416
438
|
moves_list.append(strings_moves[1])
|
417
439
|
|
418
|
-
if not self.silenced:
|
440
|
+
if not self.silenced:
|
441
|
+
print(strings)
|
419
442
|
|
420
443
|
# recursively call fcn on new strings
|
421
444
|
self.get_next_move(strings, moves_list)
|
422
445
|
|
423
|
-
|
424
446
|
elif first_key >= 2: # needs a CNOT move
|
425
|
-
|
426
447
|
a_count1 = 0
|
427
448
|
a_count2 = 0
|
428
449
|
for index in range(len(strings[index1])):
|
429
|
-
if not (strings[index1][index] ==
|
430
|
-
|
450
|
+
if not (strings[index1][index] == "0" or strings[index1][index] == "1") and not (
|
451
|
+
strings[index2][index] == "0" or strings[index2][index] == "1"
|
452
|
+
):
|
431
453
|
a_count1 += 0
|
432
454
|
# basically do nothing
|
433
|
-
elif not (strings[index1][index] ==
|
455
|
+
elif not (strings[index1][index] == "0" or strings[index1][index] == "1"):
|
434
456
|
a_count1 += 1
|
435
|
-
elif not (strings[index2][index] ==
|
457
|
+
elif not (strings[index2][index] == "0" or strings[index2][index] == "1"):
|
436
458
|
a_count2 += 1
|
437
459
|
|
438
460
|
if (
|
439
|
-
|
461
|
+
a_count1 > 0 or a_count2 > 0
|
462
|
+
): # TODO: test if there will be problems if bth strings contain 'a' @ same position
|
440
463
|
if a_count1 > a_count2:
|
441
464
|
first_key -= a_count1
|
442
465
|
else:
|
@@ -452,34 +475,37 @@ class UnaryStatePrepImpl:
|
|
452
475
|
control_bit_index = possible_rot_controls[0][0]
|
453
476
|
control_type = possible_rot_controls[0][1]
|
454
477
|
for a_index in range(len(strings[index1])):
|
455
|
-
if not (strings[index1][a_index] ==
|
478
|
+
if not (strings[index1][a_index] == "0" or strings[index1][a_index] == "1"):
|
456
479
|
break
|
457
480
|
target_bit_index = a_index
|
458
481
|
|
459
482
|
move = [control_bit_index, target_bit_index, control_type] ###Type [int, int, str]
|
460
483
|
|
461
|
-
strings_moves = self.make_move(
|
462
|
-
|
484
|
+
strings_moves = self.make_move(
|
485
|
+
strings, index1, index2, move, "ROT"
|
486
|
+
) # fcn makes move and change all strings
|
463
487
|
strings = strings_moves[0]
|
464
488
|
moves_list.append(strings_moves[1])
|
465
489
|
|
466
|
-
if not self.silenced:
|
490
|
+
if not self.silenced:
|
491
|
+
print(strings)
|
467
492
|
|
468
493
|
# recursively call fcn on new strings
|
469
494
|
self.get_next_move(strings, moves_list)
|
470
|
-
return
|
495
|
+
return "Done"
|
471
496
|
|
472
497
|
poss_c_moves = self.get_CNOT_moves(strings, index1, index2)
|
473
498
|
first_poss_move = next(iter(poss_c_moves)) # gets first key
|
474
499
|
target_bit_index = first_poss_move
|
475
500
|
if len(poss_c_moves[target_bit_index]) == 0:
|
476
|
-
if not self.silenced:
|
501
|
+
if not self.silenced:
|
502
|
+
print(target_bit_index)
|
477
503
|
# find a c-move where u will have to change another string with it
|
478
504
|
# tlater: make this more optimal -> find the index in which the least # of states will be effected
|
479
505
|
|
480
506
|
control_bit_index = self.get_CNOT_move_non_opt(strings, index1, index2, target_bit_index)
|
481
507
|
|
482
|
-
if control_bit_index
|
508
|
+
if control_bit_index is None:
|
483
509
|
# must be something with a rotation
|
484
510
|
string_to_rotate = self.left_compressed[0]
|
485
511
|
possible_rot_controls = self.get_0_rotation(strings, strings.index(string_to_rotate))
|
@@ -487,25 +513,30 @@ class UnaryStatePrepImpl:
|
|
487
513
|
control_bit_index = possible_rot_controls[0][0]
|
488
514
|
control_type = possible_rot_controls[0][1]
|
489
515
|
for a_index in range(len(strings[index1])):
|
490
|
-
if not (strings[index1][a_index] ==
|
516
|
+
if not (strings[index1][a_index] == "0" or strings[index1][a_index] == "1"):
|
491
517
|
break
|
492
518
|
target_bit_index = a_index
|
493
519
|
|
494
520
|
move = [control_bit_index, target_bit_index, control_type] ###Type [int, int, str]
|
495
521
|
|
496
|
-
strings_moves = self.make_move(
|
497
|
-
|
522
|
+
strings_moves = self.make_move(
|
523
|
+
strings, index1, index2, move, "ROT"
|
524
|
+
) # fcn makes move and change all strings
|
498
525
|
strings = strings_moves[0]
|
499
526
|
moves_list.append(strings_moves[1])
|
500
527
|
|
501
|
-
if not self.silenced:
|
528
|
+
if not self.silenced:
|
529
|
+
print(strings)
|
502
530
|
self.left_compressed.remove(strings.index(string_to_rotate))
|
503
531
|
# recursively call fcn on new strings
|
504
532
|
self.get_next_move(strings, moves_list)
|
505
|
-
return
|
533
|
+
return "Done"
|
506
534
|
|
507
|
-
control_type = strings[
|
508
|
-
|
535
|
+
control_type = strings[
|
536
|
+
index2
|
537
|
+
][
|
538
|
+
control_bit_index
|
539
|
+
] # can choose strings[index1] or [index2] -> make more optimal by checking which one doesn't affect a lot of other strings
|
509
540
|
|
510
541
|
else:
|
511
542
|
control_bit_index = poss_c_moves[target_bit_index][0][0]
|
@@ -513,11 +544,12 @@ class UnaryStatePrepImpl:
|
|
513
544
|
|
514
545
|
move = [control_bit_index, target_bit_index, control_type] ###Type [int, int, str]
|
515
546
|
|
516
|
-
strings_moves = self.make_move(strings, index1, index2, move,
|
547
|
+
strings_moves = self.make_move(strings, index1, index2, move, "CNOT")
|
517
548
|
strings = strings_moves[0]
|
518
549
|
moves_list.append(strings_moves[1])
|
519
550
|
|
520
|
-
if not self.silenced:
|
551
|
+
if not self.silenced:
|
552
|
+
print(strings)
|
521
553
|
|
522
554
|
self.get_next_move(strings, moves_list)
|
523
555
|
|
@@ -561,12 +593,11 @@ class UnaryStatePrepImpl:
|
|
561
593
|
|
562
594
|
#####
|
563
595
|
|
564
|
-
|
596
|
+
"""
|
565
597
|
This function extracts the equations from the state and returns them
|
566
|
-
|
598
|
+
"""
|
567
599
|
|
568
600
|
def get_equations(f_state):
|
569
|
-
|
570
601
|
equations = []
|
571
602
|
|
572
603
|
for s, v in f_state.state.items():
|
@@ -577,17 +608,19 @@ class UnaryStatePrepImpl:
|
|
577
608
|
### main ###
|
578
609
|
|
579
610
|
def get_circuit(self, s):
|
580
|
-
|
611
|
+
"""
|
581
612
|
s = []
|
582
613
|
for counter in range(4):
|
583
614
|
string = input("Enter your state: ")
|
584
615
|
s.append(string)
|
585
616
|
if not silenced: print(s)
|
586
|
-
|
587
|
-
if not self.silenced:
|
617
|
+
"""
|
618
|
+
if not self.silenced:
|
619
|
+
print("s on start=", s)
|
588
620
|
moves_list = []
|
589
621
|
moves_list = self.get_next_move(s, moves_list)
|
590
|
-
if not self.silenced:
|
622
|
+
if not self.silenced:
|
623
|
+
print("last s=", s)
|
591
624
|
|
592
625
|
circuit = QCircuit()
|
593
626
|
for move in moves_list:
|
tequila/apps/adapt/__init__.py
CHANGED
@@ -1 +1,9 @@
|
|
1
|
-
from .adapt import
|
1
|
+
from .adapt import (
|
2
|
+
Adapt,
|
3
|
+
AdaptPoolBase,
|
4
|
+
ObjectiveFactoryBase,
|
5
|
+
ObjectiveFactorySequentialExcitedState,
|
6
|
+
MolecularPool,
|
7
|
+
PseudoSingletMolecularPool,
|
8
|
+
run_molecular_adapt,
|
9
|
+
)
|