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
@@ -17,6 +17,7 @@ class TequilaQiboException(TequilaException):
|
|
17
17
|
def __str__(self):
|
18
18
|
return "Error in qibo backend:" + self.message
|
19
19
|
|
20
|
+
|
20
21
|
def kraus_tensor(klist, n):
|
21
22
|
"""
|
22
23
|
Recursive function that produces every (n-fold) tensor product of a list of kraus operators.
|
@@ -39,9 +40,10 @@ def kraus_tensor(klist, n):
|
|
39
40
|
elif n >= 3:
|
40
41
|
return [np.kron(k1, k2) for k1 in kraus_tensor(klist, n - 1) for k2 in klist]
|
41
42
|
else:
|
42
|
-
raise TequilaQiboException(
|
43
|
+
raise TequilaQiboException("wtf, you gave me n={}".format(str(n)))
|
44
|
+
|
43
45
|
|
44
|
-
def bit_flip_map(qs,p):
|
46
|
+
def bit_flip_map(qs, p):
|
45
47
|
"""
|
46
48
|
returns the kraus operators for bit flip with probability p
|
47
49
|
Parameters
|
@@ -56,16 +58,16 @@ def bit_flip_map(qs,p):
|
|
56
58
|
"""
|
57
59
|
mat1 = np.array([[np.sqrt(1 - p), 0], [0, np.sqrt(1 - p)]])
|
58
60
|
mat2 = np.array([[0, np.sqrt(p)], [np.sqrt(p), 0]])
|
59
|
-
back= []
|
61
|
+
back = []
|
60
62
|
matlist = [mat1, mat2]
|
61
|
-
newmats = kraus_tensor(matlist,len(qs))
|
63
|
+
newmats = kraus_tensor(matlist, len(qs))
|
62
64
|
for mat in newmats:
|
63
65
|
back.append((tuple(qs), mat))
|
64
66
|
|
65
67
|
return back
|
66
68
|
|
67
69
|
|
68
|
-
def phase_flip_map(qs,p):
|
70
|
+
def phase_flip_map(qs, p):
|
69
71
|
"""
|
70
72
|
returns the kraus operators for phase flip with probability p
|
71
73
|
Parameters
|
@@ -80,7 +82,7 @@ def phase_flip_map(qs,p):
|
|
80
82
|
"""
|
81
83
|
mat1 = np.array([[np.sqrt(1 - p), 0], [0, np.sqrt(1 - p)]])
|
82
84
|
mat2 = np.array([[np.sqrt(p), 0], [0, -np.sqrt(p)]])
|
83
|
-
back= []
|
85
|
+
back = []
|
84
86
|
matlist = [mat1, mat2]
|
85
87
|
newmats = kraus_tensor(matlist, len(qs))
|
86
88
|
for mat in newmats:
|
@@ -88,7 +90,7 @@ def phase_flip_map(qs,p):
|
|
88
90
|
return back
|
89
91
|
|
90
92
|
|
91
|
-
def amp_damp_map(qs,p):
|
93
|
+
def amp_damp_map(qs, p):
|
92
94
|
"""
|
93
95
|
Generate the Kraus operators corresponding to an amplitude damping
|
94
96
|
noise channel.
|
@@ -97,10 +99,9 @@ def amp_damp_map(qs,p):
|
|
97
99
|
:return: A list [k1, k2] of the Kraus operators that parametrize the map.
|
98
100
|
:rtype: list
|
99
101
|
"""
|
100
|
-
mat1 = np.sqrt(p) * np.array([[0, 1],
|
101
|
-
[0, 0]])
|
102
|
+
mat1 = np.sqrt(p) * np.array([[0, 1], [0, 0]])
|
102
103
|
mat2 = np.diag([1, np.sqrt(1 - p)])
|
103
|
-
back= []
|
104
|
+
back = []
|
104
105
|
matlist = [mat1, mat2]
|
105
106
|
newmats = kraus_tensor(matlist, len(qs))
|
106
107
|
for mat in newmats:
|
@@ -108,7 +109,7 @@ def amp_damp_map(qs,p):
|
|
108
109
|
return back
|
109
110
|
|
110
111
|
|
111
|
-
def phase_damp_map(qs,p):
|
112
|
+
def phase_damp_map(qs, p):
|
112
113
|
"""
|
113
114
|
returns the kraus operators for phase damping with probability p
|
114
115
|
Parameters
|
@@ -131,6 +132,7 @@ def phase_damp_map(qs,p):
|
|
131
132
|
back.append((tuple(qs), mat))
|
132
133
|
return back
|
133
134
|
|
135
|
+
|
134
136
|
def phase_amp_damp_map(qs, a, b):
|
135
137
|
"""
|
136
138
|
the kraus maps for combined phase amplitude damping
|
@@ -153,12 +155,13 @@ def phase_amp_damp_map(qs, a, b):
|
|
153
155
|
|
154
156
|
back = []
|
155
157
|
matlist = [np.array(k) for k in [A0, A1, A2]]
|
156
|
-
newmats = kraus_tensor(matlist,len(qs))
|
158
|
+
newmats = kraus_tensor(matlist, len(qs))
|
157
159
|
for mat in newmats:
|
158
160
|
back.append((tuple(qs), mat))
|
159
161
|
return back
|
160
162
|
|
161
|
-
|
163
|
+
|
164
|
+
def depolarizing_map(qs, p):
|
162
165
|
"""
|
163
166
|
the kraus maps for symmetric depolarizing
|
164
167
|
Parameters
|
@@ -175,14 +178,15 @@ def depolarizing_map(qs,p):
|
|
175
178
|
mat1 = np.array([[np.sqrt(1 - 3 * p / 4), 0], [0, np.sqrt(1 - 3 * p / 4)]])
|
176
179
|
mat2 = np.array([[np.sqrt(p / 4), 0], [0, -np.sqrt(p / 4)]])
|
177
180
|
mat3 = np.array([[0, np.sqrt(p / 4)], [np.sqrt(p / 4), 0]])
|
178
|
-
mat4 = np.array([[0
|
181
|
+
mat4 = np.array([[0.0, -1.0j * np.sqrt(p / 4)], [1.0j * np.sqrt(p / 4), 0.0]])
|
179
182
|
back = []
|
180
|
-
matlist= [mat1,mat2,mat3,mat4]
|
183
|
+
matlist = [mat1, mat2, mat3, mat4]
|
181
184
|
newmats = kraus_tensor(matlist, len(qs))
|
182
185
|
for mat in newmats:
|
183
186
|
back.append((tuple(qs), mat))
|
184
187
|
return back
|
185
188
|
|
189
|
+
|
186
190
|
class BackendCircuitQibo(BackendCircuit):
|
187
191
|
"""
|
188
192
|
Class representing circuits compiled to qibo.
|
@@ -222,12 +226,11 @@ class BackendCircuitQibo(BackendCircuit):
|
|
222
226
|
"controlled_phase": False,
|
223
227
|
"toffoli": False,
|
224
228
|
"phase_to_z": False,
|
225
|
-
"cc_max": True
|
229
|
+
"cc_max": True,
|
226
230
|
}
|
227
231
|
numbering: BitNumbering = BitNumbering.MSB
|
228
232
|
|
229
|
-
|
230
|
-
def __init__(self, abstract_circuit, noise=None, device=None,highest_qubit=None, *args, **kwargs):
|
233
|
+
def __init__(self, abstract_circuit, noise=None, device=None, highest_qubit=None, *args, **kwargs):
|
231
234
|
"""
|
232
235
|
|
233
236
|
Parameters
|
@@ -242,17 +245,17 @@ class BackendCircuitQibo(BackendCircuit):
|
|
242
245
|
kwargs
|
243
246
|
"""
|
244
247
|
self.op_lookup = {
|
245
|
-
|
246
|
-
|
247
|
-
|
248
|
-
|
249
|
-
|
250
|
-
|
251
|
-
|
252
|
-
|
253
|
-
|
254
|
-
|
255
|
-
|
248
|
+
"I": gates.I,
|
249
|
+
"X": gates.X,
|
250
|
+
"Y": gates.Y,
|
251
|
+
"Z": gates.Z,
|
252
|
+
"H": gates.H,
|
253
|
+
"Rx": gates.RX,
|
254
|
+
"Ry": gates.RY,
|
255
|
+
"Rz": gates.RZ,
|
256
|
+
"SWAP": gates.SWAP,
|
257
|
+
"Measure": gates.M,
|
258
|
+
"Phase": gates.ZPow,
|
256
259
|
}
|
257
260
|
self.counter = 0 # keeps track of how many parameters are in the circuit
|
258
261
|
self.variables = [] # will map position to parameter better
|
@@ -261,59 +264,59 @@ class BackendCircuitQibo(BackendCircuit):
|
|
261
264
|
if noise is not None:
|
262
265
|
qibo.set_backend("defaulteinsum") # necessary for Qibo to do density matrices!
|
263
266
|
else:
|
264
|
-
qibo.set_backend(
|
267
|
+
qibo.set_backend("custom")
|
265
268
|
if highest_qubit is None:
|
266
|
-
self.highest_qubit=0
|
269
|
+
self.highest_qubit = 0
|
267
270
|
else:
|
268
|
-
self.highest_qubit=highest_qubit
|
269
|
-
super().__init__(abstract_circuit=abstract_circuit, noise=noise,device=device, *args, **kwargs)
|
271
|
+
self.highest_qubit = highest_qubit
|
272
|
+
super().__init__(abstract_circuit=abstract_circuit, noise=noise, device=device, *args, **kwargs)
|
270
273
|
|
271
274
|
if noise is not None:
|
272
275
|
# a lookup table from tequila QuantumNoise to NoiseChannel qibo objects. See each function
|
273
276
|
# for reference
|
274
277
|
self.noise_lookup = {
|
275
|
-
|
276
|
-
|
277
|
-
|
278
|
-
|
279
|
-
|
280
|
-
|
278
|
+
"bit flip": lambda qs, px: gates.GeneralChannel(bit_flip_map(qs, px)),
|
279
|
+
"phase flip": lambda qs, px: gates.GeneralChannel(phase_flip_map(qs, px)),
|
280
|
+
"phase damp": lambda qs, p: gates.GeneralChannel(phase_damp_map(qs, p)),
|
281
|
+
"amplitude damp": lambda qs, p: gates.GeneralChannel(amp_damp_map(qs, p)),
|
282
|
+
"phase-amplitude damp": lambda qs, a, b: gates.GeneralChannel(phase_amp_damp_map(qs, a, b)),
|
283
|
+
"depolarizing": lambda qs, p: gates.GeneralChannel(depolarizing_map(qs, p)),
|
281
284
|
}
|
282
|
-
self.circuit = self.add_noise_to_circuit(noise)
|
285
|
+
self.circuit = self.add_noise_to_circuit(noise) # see this function for details
|
283
286
|
self.baseline_variables = self.variables
|
284
287
|
|
285
288
|
def check_device(self, device):
|
286
|
-
assert type(device) in [str,dict] or device is None
|
287
|
-
if isinstance(device,str):
|
288
|
-
d=device.upper()
|
289
|
-
if d[:5] not in ["/GPU:","/CPU:"]:
|
289
|
+
assert type(device) in [str, dict] or device is None
|
290
|
+
if isinstance(device, str):
|
291
|
+
d = device.upper()
|
292
|
+
if d[:5] not in ["/GPU:", "/CPU:"]:
|
290
293
|
raise TequilaQiboException("Device names must begin with either /GPU: or /CPU:; received {}".format(d))
|
291
|
-
elif isinstance(device,dict):
|
292
|
-
if
|
293
|
-
md = device[
|
294
|
+
elif isinstance(device, dict):
|
295
|
+
if "memory_device" in device.keys(): # full spec paralellism
|
296
|
+
md = device["memory_device"].upper()
|
294
297
|
self.check_device(md)
|
295
|
-
if
|
296
|
-
for k in device[
|
298
|
+
if "accelerators" in list(device.keys()):
|
299
|
+
for k in device["accelerators"].keys():
|
297
300
|
self.check_device(k)
|
298
301
|
else:
|
299
|
-
raise TequilaQiboException(
|
302
|
+
raise TequilaQiboException("device dictionary formatted improperly!")
|
300
303
|
else:
|
301
|
-
for k in device[
|
304
|
+
for k in device["accelerators"].keys():
|
302
305
|
self.check_device(k)
|
303
306
|
return
|
304
307
|
|
305
308
|
def retrieve_device(self, device):
|
306
309
|
if device is None:
|
307
310
|
return device
|
308
|
-
elif isinstance(device,str):
|
311
|
+
elif isinstance(device, str):
|
309
312
|
return device
|
310
|
-
elif isinstance(device,dict):
|
311
|
-
if
|
313
|
+
elif isinstance(device, dict):
|
314
|
+
if "memory_device" in device.keys(): # full spec paralellism
|
312
315
|
return device
|
313
316
|
else:
|
314
|
-
return {
|
317
|
+
return {"accelerators": device, "memory_device": "/CPU:0"}
|
315
318
|
else:
|
316
|
-
raise TequilaQiboException(
|
319
|
+
raise TequilaQiboException("Invalid device of type {}".format(type(device)))
|
317
320
|
|
318
321
|
def update_variables(self, variables, circuit=None):
|
319
322
|
"""
|
@@ -361,15 +364,15 @@ class BackendCircuitQibo(BackendCircuit):
|
|
361
364
|
wave = QubitWaveFunction.from_string(initial_state, self.numbering).to_array()
|
362
365
|
elif isinstance(initial_state, QubitWaveFunction):
|
363
366
|
wave = initial_state
|
364
|
-
elif isinstance(initial_state,np.ndarray):
|
367
|
+
elif isinstance(initial_state, np.ndarray):
|
365
368
|
wave = QubitWaveFunction.from_array(initial_state, self.numbering)
|
366
369
|
else:
|
367
|
-
raise TequilaQiboException(
|
370
|
+
raise TequilaQiboException("could not understand initial state of type {}".format(type(initial_state)))
|
368
371
|
state = wave.to_array()
|
369
372
|
result = self.circuit(state)
|
370
373
|
else:
|
371
374
|
result = self.circuit()
|
372
|
-
back= QubitWaveFunction.from_array(result.numpy(), self.numbering)
|
375
|
+
back = QubitWaveFunction.from_array(result.numpy(), self.numbering)
|
373
376
|
return back
|
374
377
|
|
375
378
|
def simulate(self, variables, initial_state=0, *args, **kwargs) -> QubitWaveFunction:
|
@@ -393,23 +396,23 @@ class BackendCircuitQibo(BackendCircuit):
|
|
393
396
|
|
394
397
|
"""
|
395
398
|
|
396
|
-
|
397
399
|
self.update_variables(variables)
|
398
400
|
if isinstance(initial_state, BitString):
|
399
401
|
initial_state = initial_state.integer
|
400
402
|
if isinstance(initial_state, QubitWaveFunction):
|
401
403
|
if initial_state.length() != 1:
|
402
|
-
return self.do_simulate(variables=variables,initial_state=initial_state, *args, **kwargs)
|
404
|
+
return self.do_simulate(variables=variables, initial_state=initial_state, *args, **kwargs)
|
403
405
|
initial_state = list(initial_state.keys())[0].integer
|
404
|
-
if isinstance(initial_state,np.ndarray):
|
406
|
+
if isinstance(initial_state, np.ndarray):
|
405
407
|
return self.do_simulate(variables=variables, initial_state=initial_state, *args, **kwargs)
|
406
408
|
all_qubits = [i for i in range(self.abstract_circuit.n_qubits)]
|
407
409
|
active_qubits = self.abstract_circuit.qubits
|
408
410
|
# maps from reduced register to full register
|
409
411
|
keymap = KeyMapSubregisterToRegister(subregister=active_qubits, register=all_qubits)
|
410
412
|
|
411
|
-
result = self.do_simulate(
|
412
|
-
|
413
|
+
result = self.do_simulate(
|
414
|
+
variables=variables, initial_state=keymap.inverted(initial_state).integer, *args, **kwargs
|
415
|
+
)
|
413
416
|
return result
|
414
417
|
|
415
418
|
def convert_measurements(self, backend_result, target_qubits=None) -> QubitWaveFunction:
|
@@ -441,8 +444,7 @@ class BackendCircuitQibo(BackendCircuit):
|
|
441
444
|
|
442
445
|
return result
|
443
446
|
|
444
|
-
def sample_paulistring(self, samples: int, paulistring, variables, *args,
|
445
|
-
**kwargs):
|
447
|
+
def sample_paulistring(self, samples: int, paulistring, variables, *args, **kwargs):
|
446
448
|
"""
|
447
449
|
Has to be rewritten because of the pro-scription in qibo against calling already executed circuits.
|
448
450
|
|
@@ -476,16 +478,17 @@ class BackendCircuitQibo(BackendCircuit):
|
|
476
478
|
basis_change += change_basis(target=idx, axis=p)
|
477
479
|
|
478
480
|
highest_qubit = max(paulistring.qubits)
|
479
|
-
new=self.rebuild_for_sample(abstract_circuit=basis_change,variables=variables,highest_qubit=highest_qubit)
|
481
|
+
new = self.rebuild_for_sample(abstract_circuit=basis_change, variables=variables, highest_qubit=highest_qubit)
|
480
482
|
|
481
483
|
# run simulators
|
482
|
-
counts = new.sample(
|
483
|
-
|
484
|
+
counts = new.sample(
|
485
|
+
samples=samples, circuit=new.circuit, read_out_qubits=qubits, variables=variables, *args, **kwargs
|
486
|
+
)
|
484
487
|
# compute energy
|
485
488
|
E = 0.0
|
486
489
|
n_samples = 0
|
487
|
-
#print('printing the counts')
|
488
|
-
#print(counts)
|
490
|
+
# print('printing the counts')
|
491
|
+
# print(counts)
|
489
492
|
for key, count in counts.items():
|
490
493
|
parity = key.array.count(1)
|
491
494
|
sign = (-1) ** parity
|
@@ -528,7 +531,7 @@ class BackendCircuitQibo(BackendCircuit):
|
|
528
531
|
elif isinstance(initial_state, np.ndarray):
|
529
532
|
wave = QubitWaveFunction.from_array(initial_state, self.numbering) # silly but necessary
|
530
533
|
else:
|
531
|
-
raise TequilaQiboException(
|
534
|
+
raise TequilaQiboException("received an unusable initial state of type {}".format(type(initial_state)))
|
532
535
|
state = wave.to_array()
|
533
536
|
result = circuit(state, nshots=samples)
|
534
537
|
else:
|
@@ -585,7 +588,7 @@ class BackendCircuitQibo(BackendCircuit):
|
|
585
588
|
qibo.tensorflow.circuit.TensorflowCircuit
|
586
589
|
an empty, though initialized, circuit that can be executed or manipulated.
|
587
590
|
"""
|
588
|
-
n_qubits=max(self.highest_qubit+1,self.n_qubits,self.abstract_circuit.max_qubit()+1)
|
591
|
+
n_qubits = max(self.highest_qubit + 1, self.n_qubits, self.abstract_circuit.max_qubit() + 1)
|
589
592
|
if self.device is None:
|
590
593
|
return Circuit(n_qubits)
|
591
594
|
else:
|
@@ -595,8 +598,8 @@ class BackendCircuitQibo(BackendCircuit):
|
|
595
598
|
self.flag = True # don't reset the device every time; such as during measurement.
|
596
599
|
return Circuit(n_qubits)
|
597
600
|
elif isinstance(self.device, dict):
|
598
|
-
acc = self.device[
|
599
|
-
mem = self.device[
|
601
|
+
acc = self.device["accelerators"]
|
602
|
+
mem = self.device["memory device"]
|
600
603
|
return Circuit(n_qubits, accelerators=acc, memory_device=mem)
|
601
604
|
|
602
605
|
def add_parametrized_gate(self, gate, circuit, variables, *args, **kwargs):
|
@@ -623,9 +626,9 @@ class BackendCircuitQibo(BackendCircuit):
|
|
623
626
|
self.variables.append(gate.parameter)
|
624
627
|
value = gate.parameter(variables)
|
625
628
|
if gate.is_controlled():
|
626
|
-
inst= op(t[0], theta=value).controlled_by(c[0])
|
629
|
+
inst = op(t[0], theta=value).controlled_by(c[0])
|
627
630
|
else:
|
628
|
-
inst = op(t[0],theta=value)
|
631
|
+
inst = op(t[0], theta=value)
|
629
632
|
self.inst_list.append(copy.deepcopy(inst))
|
630
633
|
circuit.add(inst)
|
631
634
|
return circuit
|
@@ -650,9 +653,9 @@ class BackendCircuitQibo(BackendCircuit):
|
|
650
653
|
t = gate.target
|
651
654
|
c = gate.control
|
652
655
|
if gate.is_controlled():
|
653
|
-
inst= op(t[0]).controlled_by(c[0])
|
656
|
+
inst = op(t[0]).controlled_by(c[0])
|
654
657
|
else:
|
655
|
-
if gate.name is [
|
658
|
+
if gate.name is ["Swap"]:
|
656
659
|
inst = op(t[0], t[1])
|
657
660
|
else:
|
658
661
|
inst = op(t[0])
|
@@ -677,14 +680,14 @@ class BackendCircuitQibo(BackendCircuit):
|
|
677
680
|
None
|
678
681
|
"""
|
679
682
|
target_qubits = sorted(target_qubits)
|
680
|
-
added=[]
|
683
|
+
added = []
|
681
684
|
for t in target_qubits:
|
682
685
|
circuit.add(gates.M(t))
|
683
686
|
added.append(copy.deepcopy(gates.M(t)))
|
684
687
|
self.inst_list.extend(added)
|
685
688
|
return circuit
|
686
689
|
|
687
|
-
def add_noise_to_circuit(self,noise_model):
|
690
|
+
def add_noise_to_circuit(self, noise_model):
|
688
691
|
"""
|
689
692
|
Apply noise from a NoiseModel to a circuit.
|
690
693
|
Parameters
|
@@ -698,14 +701,14 @@ class BackendCircuitQibo(BackendCircuit):
|
|
698
701
|
self.circuit, with noise added on.
|
699
702
|
"""
|
700
703
|
n = noise_model
|
701
|
-
new=self.initialize_circuit()
|
704
|
+
new = self.initialize_circuit()
|
702
705
|
temp_list = []
|
703
706
|
for g in self.inst_list:
|
704
707
|
new.add(g)
|
705
|
-
qubits=g.qubits
|
708
|
+
qubits = g.qubits
|
706
709
|
for noise in n.noises:
|
707
710
|
if len(qubits) == noise.level:
|
708
|
-
ch =
|
711
|
+
ch = self.noise_lookup[noise.name]
|
709
712
|
chargs = [qubits]
|
710
713
|
for p in noise.probs:
|
711
714
|
chargs.append(p)
|
@@ -715,7 +718,7 @@ class BackendCircuitQibo(BackendCircuit):
|
|
715
718
|
self.inst_list.extend(temp_list)
|
716
719
|
return new
|
717
720
|
|
718
|
-
def rebuild_for_sample(self,abstract_circuit=None,variables=None,highest_qubit=None):
|
721
|
+
def rebuild_for_sample(self, abstract_circuit=None, variables=None, highest_qubit=None):
|
719
722
|
"""
|
720
723
|
restructures the compiled circuit to that necessary for sampling
|
721
724
|
Parameters
|
@@ -728,8 +731,13 @@ class BackendCircuitQibo(BackendCircuit):
|
|
728
731
|
"""
|
729
732
|
if abstract_circuit is None:
|
730
733
|
abstract_circuit = QCircuit()
|
731
|
-
new = BackendCircuitQibo(
|
732
|
-
|
734
|
+
new = BackendCircuitQibo(
|
735
|
+
self.abstract_circuit + abstract_circuit,
|
736
|
+
variables=variables,
|
737
|
+
noise=self.noise,
|
738
|
+
device=self.device,
|
739
|
+
highest_qubit=highest_qubit,
|
740
|
+
)
|
733
741
|
return new
|
734
742
|
|
735
743
|
|