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.
Files changed (86) hide show
  1. tequila/__init__.py +29 -14
  2. tequila/apps/__init__.py +14 -5
  3. tequila/apps/_unary_state_prep_impl.py +145 -112
  4. tequila/apps/adapt/__init__.py +9 -1
  5. tequila/apps/adapt/adapt.py +154 -113
  6. tequila/apps/krylov/__init__.py +1 -1
  7. tequila/apps/krylov/krylov.py +23 -21
  8. tequila/apps/robustness/helpers.py +10 -6
  9. tequila/apps/robustness/interval.py +238 -156
  10. tequila/apps/unary_state_prep.py +29 -23
  11. tequila/autograd_imports.py +8 -5
  12. tequila/circuit/__init__.py +2 -1
  13. tequila/circuit/_gates_impl.py +135 -67
  14. tequila/circuit/circuit.py +163 -79
  15. tequila/circuit/compiler.py +114 -105
  16. tequila/circuit/gates.py +288 -120
  17. tequila/circuit/gradient.py +35 -23
  18. tequila/circuit/noise.py +83 -74
  19. tequila/circuit/postselection.py +120 -0
  20. tequila/circuit/pyzx.py +10 -6
  21. tequila/circuit/qasm.py +201 -83
  22. tequila/circuit/qpic.py +63 -61
  23. tequila/grouping/binary_rep.py +148 -146
  24. tequila/grouping/binary_utils.py +84 -75
  25. tequila/grouping/compile_groups.py +334 -230
  26. tequila/grouping/ev_utils.py +77 -41
  27. tequila/grouping/fermionic_functions.py +383 -308
  28. tequila/grouping/fermionic_methods.py +170 -123
  29. tequila/grouping/overlapping_methods.py +69 -52
  30. tequila/hamiltonian/paulis.py +12 -13
  31. tequila/hamiltonian/paulistring.py +1 -1
  32. tequila/hamiltonian/qubit_hamiltonian.py +45 -35
  33. tequila/ml/__init__.py +1 -0
  34. tequila/ml/interface_torch.py +19 -16
  35. tequila/ml/ml_api.py +11 -10
  36. tequila/ml/utils_ml.py +12 -11
  37. tequila/objective/__init__.py +8 -3
  38. tequila/objective/braket.py +55 -47
  39. tequila/objective/objective.py +87 -55
  40. tequila/objective/qtensor.py +36 -27
  41. tequila/optimizers/__init__.py +31 -23
  42. tequila/optimizers/_containers.py +11 -7
  43. tequila/optimizers/optimizer_base.py +111 -83
  44. tequila/optimizers/optimizer_gd.py +258 -231
  45. tequila/optimizers/optimizer_gpyopt.py +56 -42
  46. tequila/optimizers/optimizer_scipy.py +157 -112
  47. tequila/quantumchemistry/__init__.py +66 -38
  48. tequila/quantumchemistry/chemistry_tools.py +393 -209
  49. tequila/quantumchemistry/encodings.py +121 -13
  50. tequila/quantumchemistry/madness_interface.py +170 -96
  51. tequila/quantumchemistry/orbital_optimizer.py +86 -41
  52. tequila/quantumchemistry/psi4_interface.py +166 -97
  53. tequila/quantumchemistry/pyscf_interface.py +70 -23
  54. tequila/quantumchemistry/qc_base.py +866 -414
  55. tequila/simulators/__init__.py +0 -3
  56. tequila/simulators/simulator_api.py +247 -105
  57. tequila/simulators/simulator_aqt.py +102 -0
  58. tequila/simulators/simulator_base.py +147 -53
  59. tequila/simulators/simulator_cirq.py +58 -42
  60. tequila/simulators/simulator_cudaq.py +600 -0
  61. tequila/simulators/simulator_ddsim.py +390 -0
  62. tequila/simulators/simulator_mqp.py +30 -0
  63. tequila/simulators/simulator_pyquil.py +190 -171
  64. tequila/simulators/simulator_qibo.py +95 -87
  65. tequila/simulators/simulator_qiskit.py +119 -107
  66. tequila/simulators/simulator_qlm.py +52 -26
  67. tequila/simulators/simulator_qulacs.py +74 -52
  68. tequila/simulators/simulator_spex.py +95 -60
  69. tequila/simulators/simulator_symbolic.py +6 -5
  70. tequila/simulators/test_spex_simulator.py +8 -11
  71. tequila/tools/convenience.py +4 -4
  72. tequila/tools/qng.py +72 -64
  73. tequila/tools/random_generators.py +38 -34
  74. tequila/utils/bitstrings.py +7 -7
  75. tequila/utils/exceptions.py +19 -5
  76. tequila/utils/joined_transformation.py +8 -10
  77. tequila/utils/keymap.py +0 -5
  78. tequila/utils/misc.py +6 -4
  79. tequila/version.py +1 -1
  80. tequila/wavefunction/qubit_wavefunction.py +47 -28
  81. {tequila_basic-1.9.9.dist-info → tequila_basic-1.9.10.dist-info}/METADATA +13 -16
  82. tequila_basic-1.9.10.dist-info/RECORD +93 -0
  83. {tequila_basic-1.9.9.dist-info → tequila_basic-1.9.10.dist-info}/WHEEL +1 -1
  84. tequila_basic-1.9.9.dist-info/RECORD +0 -88
  85. {tequila_basic-1.9.9.dist-info → tequila_basic-1.9.10.dist-info}/licenses/LICENSE +0 -0
  86. {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 = ["a", "b", "c", "d", "e", "f", "g", "h", "i", "j", "k", "l", "m", "n", "o", "p", "q", "r", "s", "t", "u", "v", "w", "x", "y", "z"]
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] != '0' and s1[i] != '1') or (s2[i] != '0' and s2[i] != '1'):
77
- if not ((s1[i] != '0' and s1[i] != '1') and (s2[i] != '0' and s2[i] != '1')):
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 (i < len(s) - 1):
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 index != target and s[i1][index] != s[i2][index] and (
154
- s[i1][index] == '0' or s[i1][index] == '1') and (
155
- s[i2][index] == '0' or s[i2][index] == '1'): # control != target & != other string & != 'a'
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 == True:
184
+ while i < len(s_to_check) and flag:
159
185
  if s[i1][index] == s_to_check[i][index] or not (
160
- s_to_check[i][index] == '0' or s_to_check[i][index] == '1'): # making sure its a 1 or 0
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 == True:
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 == True:
198
+ while i < len(s_to_check) and flag:
172
199
  if s[i2][index] == s_to_check[i][index] or not (
173
- s_to_check[i][index] == '0' or s_to_check[i][index] == '1'):
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 == True:
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
- if index != target_index and s[i1][index] != s[i2][index] and (
191
- s[i1][index] == '0' or s[i1][index] == '1') and (s[i2][index] == '0' or s[i2][index] == '1'):
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('index not found')
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] # collect target index, the bit where they are different
232
+ 0
233
+ ] # collect target index, the bit where they are different
204
234
  move_param = None
205
235
 
206
- if not self.silenced: print("compression of index {} in strings {} and {}".format(target_index, s[i1], s[i2]))
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: print(s)
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] == '0' or s[i][a_index] == '1'):
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 == True:
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 == 'ROT':
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] = '0'
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 == '0':
291
- c_type = 'anti'
316
+ if control_type == "0":
317
+ c_type = "anti"
292
318
  else:
293
- c_type = 'positive'
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 == 'anti':
297
- m_type = 'aCROT'
322
+ if c_type == "anti":
323
+ m_type = "aCROT"
298
324
  else:
299
- m_type = 'CROT'
325
+ m_type = "CROT"
300
326
 
301
327
  move_param = [m_type, control_bit_index, target_bit_index]
302
- if not self.silenced: print(move_param)
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] == '0':
322
-
345
+ if s[i][target_bit_index] == "0":
323
346
  string = s[i]
324
347
  string = list(string)
325
- string[target_bit_index] = '1'
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] = '0'
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 == '0':
342
- c_type = 'anti'
363
+ if control_type == "0":
364
+ c_type = "anti"
343
365
  else:
344
- c_type = 'positive'
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 == 'anti':
348
- m_type = 'aCNOT'
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: print(move_param)
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] == '1':
366
- move = ['X', None, index]
386
+ if strings[0][index] == "1":
387
+ move = ["X", None, index]
367
388
  moves_list.append(move)
368
- if not self.silenced: print('DONE', ' s=', s)
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 == False and i < len(keys) - 1:
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] == '0' or strings[index1][a_index] == '1'):
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(strings, index1, index2, move,
414
- 'ROT') # fcn makes move and change all strings
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: print(strings)
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] == '0' or strings[index1][index] == '1') and not (
430
- strings[index2][index] == '0' or strings[index2][index] == '1'):
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] == '0' or strings[index1][index] == '1'):
455
+ elif not (strings[index1][index] == "0" or strings[index1][index] == "1"):
434
456
  a_count1 += 1
435
- elif not (strings[index2][index] == '0' or strings[index2][index] == '1'):
457
+ elif not (strings[index2][index] == "0" or strings[index2][index] == "1"):
436
458
  a_count2 += 1
437
459
 
438
460
  if (
439
- a_count1 > 0 or a_count2 > 0): # TODO: test if there will be problems if bth strings contain 'a' @ same position
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] == '0' or strings[index1][a_index] == '1'):
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(strings, index1, index2, move,
462
- 'ROT') # fcn makes move and change all strings
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: print(strings)
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 'Done'
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: print(target_bit_index)
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 == None:
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] == '0' or strings[index1][a_index] == '1'):
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(strings, index1, index2, move,
497
- 'ROT') # fcn makes move and change all strings
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: print(strings)
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 'Done'
533
+ return "Done"
506
534
 
507
- control_type = strings[index2][
508
- control_bit_index] # can choose strings[index1] or [index2] -> make more optimal by checking which one doesn't affect a lot of other strings
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, 'CNOT')
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: print(strings)
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: print("s on start=", s)
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: print("last s=", s)
622
+ if not self.silenced:
623
+ print("last s=", s)
591
624
 
592
625
  circuit = QCircuit()
593
626
  for move in moves_list:
@@ -1 +1,9 @@
1
- from .adapt import Adapt, AdaptPoolBase, ObjectiveFactoryBase, ObjectiveFactorySequentialExcitedState, MolecularPool, PseudoSingletMolecularPool, run_molecular_adapt
1
+ from .adapt import (
2
+ Adapt,
3
+ AdaptPoolBase,
4
+ ObjectiveFactoryBase,
5
+ ObjectiveFactorySequentialExcitedState,
6
+ MolecularPool,
7
+ PseudoSingletMolecularPool,
8
+ run_molecular_adapt,
9
+ )