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
@@ -4,9 +4,9 @@ from scipy.sparse import csc_matrix
4
4
  from itertools import combinations
5
5
  from tequila import TequilaException
6
6
 
7
+
7
8
  def get_pauli_word_tuple(P: QubitOperator):
8
- """Given a single pauli word P, extract the tuple representing the word.
9
- """
9
+ """Given a single pauli word P, extract the tuple representing the word."""
10
10
  words = list(P.terms.keys())
11
11
  if len(words) != 1:
12
12
  raise TequilaException("P given is not a single pauli word")
@@ -14,8 +14,7 @@ def get_pauli_word_tuple(P: QubitOperator):
14
14
 
15
15
 
16
16
  def get_pauli_word(P: QubitOperator):
17
- """Given a single pauli word P, extract the same word with coefficient 1.
18
- """
17
+ """Given a single pauli word P, extract the same word with coefficient 1."""
19
18
  words = list(P.terms.keys())
20
19
  if len(words) != 1:
21
20
  raise TequilaException("P given is not a single pauli word")
@@ -23,11 +22,11 @@ def get_pauli_word(P: QubitOperator):
23
22
 
24
23
 
25
24
  def get_pauli_word_coefficient(P: QubitOperator):
26
- """Given a single pauli word P, extract its coefficient.
27
- """
25
+ """Given a single pauli word P, extract its coefficient."""
28
26
  coeffs = list(P.terms.values())
29
27
  return coeffs[0]
30
28
 
29
+
31
30
  def get_occ_no(mol, n_qubits):
32
31
  """
33
32
  Given some molecule, find the reference occupation number state.
@@ -36,11 +35,28 @@ def get_occ_no(mol, n_qubits):
36
35
  Returns:
37
36
  occ_no (str): Occupation no. vector.
38
37
  """
39
- n_electrons = {'h2': 2, 'lih': 4, 'beh2': 6, 'h2o': 10, 'nh3': 10, 'n2': 14, 'hf':10, 'ch4':10, 'co':14, 'h4':4, 'ch2':8, 'heh':2, 'h6':6, 'nh':8, 'h3':2}
40
- occ_no = '1'*n_electrons[mol.lower()] + '0'*(n_qubits - n_electrons[mol.lower()])
38
+ n_electrons = {
39
+ "h2": 2,
40
+ "lih": 4,
41
+ "beh2": 6,
42
+ "h2o": 10,
43
+ "nh3": 10,
44
+ "n2": 14,
45
+ "hf": 10,
46
+ "ch4": 10,
47
+ "co": 14,
48
+ "h4": 4,
49
+ "ch2": 8,
50
+ "heh": 2,
51
+ "h6": 6,
52
+ "nh": 8,
53
+ "h3": 2,
54
+ }
55
+ occ_no = "1" * n_electrons[mol.lower()] + "0" * (n_qubits - n_electrons[mol.lower()])
41
56
 
42
57
  return occ_no
43
58
 
59
+
44
60
  def partial_order(x, y):
45
61
  """
46
62
  As described in arXiv:quant-ph/0003137 pg.10, computes the if x <= y where <= is a partial order and x and y are binary strings (but inputted as integers).
@@ -55,22 +71,23 @@ def partial_order(x, y):
55
71
  return False
56
72
 
57
73
  else:
58
- x_b, y_b = format(x, 'b'), format(y, 'b')
74
+ x_b, y_b = format(x, "b"), format(y, "b")
59
75
 
60
76
  if len(x_b) != len(y_b):
61
77
  while len(x_b) != len(y_b):
62
- x_b = '0' + x_b
78
+ x_b = "0" + x_b
63
79
 
64
80
  length = len(x_b)
65
81
 
66
82
  partial_order = False
67
83
  for l0 in range(length):
68
- if x_b[0:l0] == y_b[0:l0] and y_b[l0:length] == (length - l0)*'1':
84
+ if x_b[0:l0] == y_b[0:l0] and y_b[l0:length] == (length - l0) * "1":
69
85
  partial_order = True
70
86
  break
71
87
 
72
88
  return partial_order
73
89
 
90
+
74
91
  def allz(pw: QubitOperator):
75
92
  """
76
93
  Checks if a Pauli word is all-z.
@@ -80,11 +97,12 @@ def allz(pw: QubitOperator):
80
97
  True/False (Bool): Whether PW is all-z
81
98
  """
82
99
  for pwt in get_pauli_word_tuple(pw):
83
- if pwt[1] != 'Z':
100
+ if pwt[1] != "Z":
84
101
  return False
85
102
 
86
103
  return True
87
104
 
105
+
88
106
  def isz(pw, qubit_no):
89
107
  """
90
108
  Checks if a Pauli word is z on the qubit_no'th qubit numner.
@@ -94,10 +112,11 @@ def isz(pw, qubit_no):
94
112
  True/False (Bool): Whether PW is z on said qubit_no
95
113
  """
96
114
  for pwt in get_pauli_word_tuple(pw):
97
- if pwt[0] == qubit_no and pwt[1] == 'Z':
115
+ if pwt[0] == qubit_no and pwt[1] == "Z":
98
116
  return True
99
117
  return False
100
118
 
119
+
101
120
  def pw_ev_single_basis_state(pw: QubitOperator, index):
102
121
  """
103
122
  Returns the EV of a single PW w.r.t. a computational basis state
@@ -118,7 +137,8 @@ def pw_ev_single_basis_state(pw: QubitOperator, index):
118
137
  else:
119
138
  return 0
120
139
 
121
- def pw_matrix_element(pw: QubitOperator, l_index, r_index, n_qubits = None):
140
+
141
+ def pw_matrix_element(pw: QubitOperator, l_index, r_index, n_qubits=None):
122
142
  """
123
143
  Returns the matrix element of a single PW = <l_index|pw|r_index>
124
144
  Args:
@@ -131,7 +151,7 @@ def pw_matrix_element(pw: QubitOperator, l_index, r_index, n_qubits = None):
131
151
  """
132
152
 
133
153
  def find_pw_basis(pw, n_qubits):
134
- basis = ['I'] * n_qubits
154
+ basis = ["I"] * n_qubits
135
155
  for pwt in get_pauli_word_tuple(pw):
136
156
  basis[pwt[0]] = pwt[1]
137
157
  return basis
@@ -144,21 +164,23 @@ def pw_matrix_element(pw: QubitOperator, l_index, r_index, n_qubits = None):
144
164
 
145
165
  for i in range(n_qubits):
146
166
  if l_index[i] == r_index[i]:
147
- if basis[i] == 'Z':
148
- if l_index[i] == 1: me *= -1
149
- elif basis[i] != 'I':
150
- return 0.
167
+ if basis[i] == "Z":
168
+ if l_index[i] == 1:
169
+ me *= -1
170
+ elif basis[i] != "I":
171
+ return 0.0
151
172
  else:
152
- if basis[i] == 'Y':
173
+ if basis[i] == "Y":
153
174
  if l_index[i] == 0:
154
175
  me *= -1j
155
176
  else:
156
177
  me *= 1j
157
- elif basis[i] != 'X':
158
- return 0.
178
+ elif basis[i] != "X":
179
+ return 0.0
159
180
  return me
160
181
 
161
- def op_matrix_element(op: QubitOperator, l_index, r_index, n_qubits = None):
182
+
183
+ def op_matrix_element(op: QubitOperator, l_index, r_index, n_qubits=None):
162
184
  """
163
185
  Returns the matrix element of a single PW = <l_index|pw|r_index>
164
186
  Args:
@@ -168,9 +190,17 @@ def op_matrix_element(op: QubitOperator, l_index, r_index, n_qubits = None):
168
190
  Returns:
169
191
  me (float): Matrix element of PW
170
192
  """
171
- return np.sum(list(map(lambda x: pw_matrix_element(QubitOperator(term=x[0], coefficient=x[1]), l_index, r_index, n_qubits), op.terms.items())))
193
+ return np.sum(
194
+ list(
195
+ map(
196
+ lambda x: pw_matrix_element(QubitOperator(term=x[0], coefficient=x[1]), l_index, r_index, n_qubits),
197
+ op.terms.items(),
198
+ )
199
+ )
200
+ )
172
201
 
173
- def truncate_wavefunction(wfs, perc = None, n_qubits = None, tol = 1e-5):
202
+
203
+ def truncate_wavefunction(wfs, perc=None, n_qubits=None, tol=1e-5):
174
204
  """
175
205
  Makes config_dict from wfs. Include the most significant slater determinants (up to perc % coeffs).
176
206
  If perc is None, return the entire wavefunction.
@@ -182,10 +212,10 @@ def truncate_wavefunction(wfs, perc = None, n_qubits = None, tol = 1e-5):
182
212
  if perc is None:
183
213
  for idx, coeff in enumerate(wfs):
184
214
  if np.abs(coeff) > tol:
185
- config = format(idx, 'b')
215
+ config = format(idx, "b")
186
216
  if len(config) < n_qubits:
187
- config = '0'*(n_qubits - len(config)) + config
188
- configs.append(np.array(list(config),dtype=int))
217
+ config = "0" * (n_qubits - len(config)) + config
218
+ configs.append(np.array(list(config), dtype=int))
189
219
  coeffs.append(coeff)
190
220
 
191
221
  elif perc > 0 and perc < 100:
@@ -194,25 +224,25 @@ def truncate_wavefunction(wfs, perc = None, n_qubits = None, tol = 1e-5):
194
224
  wfs_rd_nz = wfs_rd[wfs_rd_nz_idx]
195
225
  abs_wfs = np.abs(wfs_rd_nz)
196
226
  srt_idx = np.argsort(-abs_wfs)
197
- weight = 0.
227
+ weight = 0.0
198
228
  for i, idx in enumerate(srt_idx):
199
- weight = np.sqrt(weight ** 2 + abs_wfs[idx] ** 2)
229
+ weight = np.sqrt(weight**2 + abs_wfs[idx] ** 2)
200
230
  if weight >= (perc * 0.01):
201
231
  end = i
202
232
  break
203
233
 
204
- min_idx = srt_idx[:end+1]
234
+ min_idx = srt_idx[: end + 1]
205
235
  wfs_out = wfs_rd_nz[min_idx]
206
236
  wfs_idx_out = wfs_rd_nz_idx[min_idx]
207
237
 
208
- wfs_out = wfs_out/np.linalg.norm(wfs_out) #Renormalisation
238
+ wfs_out = wfs_out / np.linalg.norm(wfs_out) # Renormalisation
209
239
 
210
240
  for idx, coeff in enumerate(wfs_out):
211
241
  if np.abs(coeff) > tol:
212
- config = format(wfs_idx_out[idx], 'b')
242
+ config = format(wfs_idx_out[idx], "b")
213
243
  if len(config) < n_qubits:
214
- config = '0'*(n_qubits - len(config)) + config
215
- configs.append(np.array(list(config),dtype=int))
244
+ config = "0" * (n_qubits - len(config)) + config
245
+ configs.append(np.array(list(config), dtype=int))
216
246
  coeffs.append(coeff)
217
247
  else:
218
248
  raise TequilaException("The number of truncated slater determinant terms must be between 1 and 2^N_q")
@@ -229,22 +259,24 @@ def build_multiple_bases_mat(op, configs, n_qubits):
229
259
  col = row = nz_loc
230
260
  data = data[nz_loc]
231
261
  if len(configs) > 1:
232
- data_pair = np.array(list(map(lambda x: op_matrix_element(op, x[0], x[1], n_qubits), combinations(configs,2))))
262
+ data_pair = np.array(list(map(lambda x: op_matrix_element(op, x[0], x[1], n_qubits), combinations(configs, 2))))
233
263
  idx_pairs = np.array(list(combinations(range(len(configs)), 2)))
234
264
  nz_loc = np.where(np.abs(data_pair) > 1e-8)[0]
235
- col = np.concatenate( (col, idx_pairs[nz_loc, 0], idx_pairs[nz_loc, 1]) )
236
- row = np.concatenate( (row, idx_pairs[nz_loc, 1], idx_pairs[nz_loc, 0]) )
237
- data = np.concatenate( (data, data_pair[nz_loc], np.conjugate(data_pair[nz_loc])) )
265
+ col = np.concatenate((col, idx_pairs[nz_loc, 0], idx_pairs[nz_loc, 1]))
266
+ row = np.concatenate((row, idx_pairs[nz_loc, 1], idx_pairs[nz_loc, 0]))
267
+ data = np.concatenate((data, data_pair[nz_loc], np.conjugate(data_pair[nz_loc])))
238
268
  return csc_matrix((data, (row, col)), shape=(len(configs), len(configs)))
239
269
 
270
+
240
271
  def op_ev_multiple_bases(op: QubitOperator, configs, coeffs, n_qubits):
241
272
  """
242
273
  Returns the EV of operator w.r.t. config_dict.
243
274
  """
244
275
  mat = build_multiple_bases_mat(op, configs, n_qubits)
245
- ev = np.dot( np.conjugate(coeffs), mat * coeffs )
276
+ ev = np.dot(np.conjugate(coeffs), mat * coeffs)
246
277
  return ev
247
278
 
279
+
248
280
  def qubit_op_ev_single_basis_state(op: QubitOperator, index):
249
281
  """
250
282
  Returns the EV of an arbitrary QubitOperator w.r.t. a computational basis state
@@ -255,4 +287,8 @@ def qubit_op_ev_single_basis_state(op: QubitOperator, index):
255
287
  Returns:
256
288
  ev (float): Expectation value of Operator
257
289
  """
258
- return np.sum(list(map(lambda x: pw_ev_single_basis_state(QubitOperator(term=x[0], coefficient=x[1]), index), op.terms.items())))
290
+ return np.sum(
291
+ list(
292
+ map(lambda x: pw_ev_single_basis_state(QubitOperator(term=x[0], coefficient=x[1]), index), op.terms.items())
293
+ )
294
+ )