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
@@ -8,19 +8,21 @@ from tequila.utils import to_float
|
|
8
8
|
from typing import Union
|
9
9
|
import warnings
|
10
10
|
import numpy as np
|
11
|
-
import qiskit
|
11
|
+
import qiskit
|
12
|
+
import qiskit_aer
|
13
|
+
import qiskit.providers.fake_provider
|
12
14
|
from qiskit import QuantumCircuit, transpile
|
13
15
|
|
14
16
|
HAS_NOISE = True
|
15
17
|
try:
|
16
18
|
from qiskit_aer import noise as qiskitnoise, AerSimulator
|
17
|
-
except:
|
19
|
+
except Exception:
|
18
20
|
HAS_NOISE = False
|
19
21
|
|
20
22
|
HAS_IBMQ = True
|
21
23
|
try:
|
22
24
|
from qiskit_ibm_runtime import IBMBackend
|
23
|
-
except:
|
25
|
+
except Exception:
|
24
26
|
HAS_IBMQ = False
|
25
27
|
|
26
28
|
|
@@ -37,7 +39,7 @@ def get_bit_flip(p):
|
|
37
39
|
type:
|
38
40
|
qiskit pauli error
|
39
41
|
"""
|
40
|
-
return qiskitnoise.pauli_error(noise_ops=[(
|
42
|
+
return qiskitnoise.pauli_error(noise_ops=[("X", p), ("I", 1 - p)])
|
41
43
|
|
42
44
|
|
43
45
|
def get_phase_flip(p):
|
@@ -53,31 +55,30 @@ def get_phase_flip(p):
|
|
53
55
|
type:
|
54
56
|
qiskit pauli error
|
55
57
|
"""
|
56
|
-
return qiskitnoise.pauli_error(noise_ops=[(
|
58
|
+
return qiskitnoise.pauli_error(noise_ops=[("Z", p), ("I", 1 - p)])
|
57
59
|
|
58
60
|
|
59
61
|
gate_qubit_lookup = {
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
|
69
|
-
|
70
|
-
|
71
|
-
|
72
|
-
|
73
|
-
|
74
|
-
|
75
|
-
|
76
|
-
|
62
|
+
"x": 1,
|
63
|
+
"y": 1,
|
64
|
+
"z": 1,
|
65
|
+
"h": 1,
|
66
|
+
"u1": 1,
|
67
|
+
"u2": 1,
|
68
|
+
"u3": 1,
|
69
|
+
"cx": 2,
|
70
|
+
"cy": 2,
|
71
|
+
"cz": 2,
|
72
|
+
"ch": 2,
|
73
|
+
"cu3": 2,
|
74
|
+
"ccx": 3,
|
75
|
+
"r": 1,
|
76
|
+
"single": 1,
|
77
|
+
"control": 2,
|
78
|
+
"multicontrol": 3,
|
77
79
|
}
|
78
80
|
|
79
|
-
full_basis = [
|
80
|
-
'cx', 'cy', 'cz', 'cu3', 'ccx']
|
81
|
+
full_basis = ["x", "y", "z", "id", "u1", "u2", "u3", "h", "unitary", "sx", "cx", "cy", "cz", "cu3", "ccx"]
|
81
82
|
|
82
83
|
|
83
84
|
def qiskit_device_dict():
|
@@ -85,8 +86,11 @@ def qiskit_device_dict():
|
|
85
86
|
# deprecated in the future
|
86
87
|
# TODO: Instead of building a dict with all backends just to search it, search directly with `get_backend`
|
87
88
|
# https://qiskit.github.io/qiskit-aer/stubs/qiskit_aer.AerProvider.html#qiskit_aer.AerProvider.get_backend
|
88
|
-
devices = {
|
89
|
-
|
89
|
+
devices = {
|
90
|
+
backend.name.lower(): backend
|
91
|
+
for backend in qiskit_aer.AerProvider().backends()
|
92
|
+
if isinstance(backend, AerSimulator)
|
93
|
+
}
|
90
94
|
|
91
95
|
# FakeProvider has been removed, see https://github.com/Qiskit/qiskit/issues/10954
|
92
96
|
# devices.update({str(x).lower(): x for x in qiskit.test.mock.FakeProvider().backends()})
|
@@ -139,6 +143,7 @@ class BackendCircuitQiskit(BackendCircuit):
|
|
139
143
|
transform a tequila NoiseModel into a qiskit noise model.
|
140
144
|
|
141
145
|
"""
|
146
|
+
|
142
147
|
STATEVECTOR_DEVICE_NAME = "aer_simulator_statevector"
|
143
148
|
|
144
149
|
compiler_arguments = {
|
@@ -157,7 +162,7 @@ class BackendCircuitQiskit(BackendCircuit):
|
|
157
162
|
"controlled_phase": False,
|
158
163
|
"toffoli": False,
|
159
164
|
"phase_to_z": False,
|
160
|
-
"cc_max": True
|
165
|
+
"cc_max": True,
|
161
166
|
}
|
162
167
|
|
163
168
|
numbering = BitNumbering.LSB
|
@@ -165,8 +170,7 @@ class BackendCircuitQiskit(BackendCircuit):
|
|
165
170
|
supports_sampling_initialization = True
|
166
171
|
supports_generic_initialization = True
|
167
172
|
|
168
|
-
def __init__(self, abstract_circuit: QCircuit, variables, qubit_map=None, noise=None,
|
169
|
-
device=None, *args, **kwargs):
|
173
|
+
def __init__(self, abstract_circuit: QCircuit, variables, qubit_map=None, noise=None, device=None, *args, **kwargs):
|
170
174
|
"""
|
171
175
|
|
172
176
|
Parameters
|
@@ -188,16 +192,16 @@ class BackendCircuitQiskit(BackendCircuit):
|
|
188
192
|
kwargs
|
189
193
|
"""
|
190
194
|
self.op_lookup = {
|
191
|
-
|
192
|
-
|
193
|
-
|
194
|
-
|
195
|
-
|
196
|
-
|
197
|
-
|
198
|
-
|
199
|
-
|
200
|
-
|
195
|
+
"I": (lambda c: c.iden),
|
196
|
+
"X": (lambda c: c.x, lambda c: c.cx, lambda c: c.ccx),
|
197
|
+
"Y": (lambda c: c.y, lambda c: c.cy, lambda c: c.ccy),
|
198
|
+
"Z": (lambda c: c.z, lambda c: c.cz, lambda c: c.ccz),
|
199
|
+
"H": (lambda c: c.h, lambda c: c.ch, lambda c: c.cch),
|
200
|
+
"Rx": (lambda c: c.rx, lambda c: c.mcrx),
|
201
|
+
"Ry": (lambda c: c.ry, lambda c: c.mcry),
|
202
|
+
"Rz": (lambda c: c.rz, lambda c: c.mcrz),
|
203
|
+
"Phase": (lambda c: c.p, lambda c: c.cp),
|
204
|
+
"SWAP": (lambda c: c.swap, lambda c: c.cswap),
|
201
205
|
}
|
202
206
|
|
203
207
|
self.resolver = {}
|
@@ -207,28 +211,37 @@ class BackendCircuitQiskit(BackendCircuit):
|
|
207
211
|
if qubit_map is None:
|
208
212
|
qubit_map = {q: i for i, q in enumerate(abstract_circuit.qubits)}
|
209
213
|
else:
|
210
|
-
warnings.warn(
|
211
|
-
|
212
|
-
|
214
|
+
warnings.warn(
|
215
|
+
f"reveived custom qubit_map = {qubit_map}\n"
|
216
|
+
"This is not fully integrated with qiskit and might result in unexpected behaviour",
|
217
|
+
TequilaWarning,
|
218
|
+
)
|
213
219
|
|
214
220
|
n_qubits = max(qubit_map.values()) + 1
|
215
221
|
|
216
222
|
self.q = qiskit.QuantumRegister(n_qubits, "q")
|
217
223
|
self.c = qiskit.ClassicalRegister(n_qubits, "c")
|
218
224
|
|
219
|
-
super().__init__(
|
220
|
-
|
225
|
+
super().__init__(
|
226
|
+
abstract_circuit=abstract_circuit,
|
227
|
+
variables=variables,
|
228
|
+
noise=noise,
|
229
|
+
device=device,
|
230
|
+
qubit_map=qubit_map,
|
231
|
+
*args,
|
232
|
+
**kwargs,
|
233
|
+
)
|
221
234
|
|
222
235
|
self.classical_map = self.make_classical_map(qubit_map=self.qubit_map)
|
223
236
|
|
224
237
|
if noise is not None:
|
225
238
|
self.noise_lookup = {
|
226
|
-
|
227
|
-
|
228
|
-
|
229
|
-
|
230
|
-
|
231
|
-
|
239
|
+
"phase damp": qiskitnoise.phase_damping_error,
|
240
|
+
"amplitude damp": qiskitnoise.amplitude_damping_error,
|
241
|
+
"bit flip": get_bit_flip,
|
242
|
+
"phase flip": get_phase_flip,
|
243
|
+
"phase-amplitude damp": qiskitnoise.phase_amplitude_damping_error,
|
244
|
+
"depolarizing": qiskitnoise.depolarizing_error,
|
232
245
|
}
|
233
246
|
|
234
247
|
if isinstance(noise, str): # string noise means "use the same noise as the device I tell you to get."
|
@@ -274,7 +287,7 @@ class BackendCircuitQiskit(BackendCircuit):
|
|
274
287
|
if isinstance(initial_state, QubitWaveFunction):
|
275
288
|
statevector = initial_state.to_array(self.numbering)
|
276
289
|
else:
|
277
|
-
statevector = np.zeros(2
|
290
|
+
statevector = np.zeros(2**self.n_qubits)
|
278
291
|
statevector[reverse_int_bits(initial_state, self.n_qubits)] = 1.0
|
279
292
|
|
280
293
|
init_circuit = qiskit.QuantumCircuit(self.q, self.c)
|
@@ -302,10 +315,12 @@ class BackendCircuitQiskit(BackendCircuit):
|
|
302
315
|
if self.device is None:
|
303
316
|
qiskit_backend = self.retrieve_device(self.STATEVECTOR_DEVICE_NAME)
|
304
317
|
else:
|
305
|
-
if
|
318
|
+
if "statevector" not in str(self.device):
|
306
319
|
raise TequilaException(
|
307
|
-
|
308
|
-
self.device, self.device
|
320
|
+
"For simulation, only state vector simulators are supported; recieved device={}, you might have forgoten to set the samples keyword - e.g. (device={}, samples=1000). If not set, tequila assumes that full wavefunction simualtion is demanded which is not compatible with qiskit devices or fake devices except for device=statevector".format(
|
321
|
+
self.device, self.device
|
322
|
+
)
|
323
|
+
)
|
309
324
|
else:
|
310
325
|
qiskit_backend = self.retrieve_device(self.device)
|
311
326
|
else:
|
@@ -313,7 +328,7 @@ class BackendCircuitQiskit(BackendCircuit):
|
|
313
328
|
|
314
329
|
optimization_level = None
|
315
330
|
if "optimization_level" in kwargs:
|
316
|
-
optimization_level = kwargs[
|
331
|
+
optimization_level = kwargs["optimization_level"]
|
317
332
|
|
318
333
|
circuit = self.circuit.assign_parameters(self.resolver)
|
319
334
|
circuit = self.add_state_init(circuit, initial_state)
|
@@ -321,10 +336,13 @@ class BackendCircuitQiskit(BackendCircuit):
|
|
321
336
|
circuit = transpile(circuit, qiskit_backend)
|
322
337
|
backend_result = qiskit_backend.run(circuit, optimization_level=optimization_level).result()
|
323
338
|
|
324
|
-
return QubitWaveFunction.from_array(
|
339
|
+
return QubitWaveFunction.from_array(
|
340
|
+
array=backend_result.get_statevector(circuit).data, numbering=self.numbering
|
341
|
+
)
|
325
342
|
|
326
|
-
def do_sample(
|
327
|
-
|
343
|
+
def do_sample(
|
344
|
+
self, circuit: qiskit.QuantumCircuit, samples: int, read_out_qubits, initial_state=0, *args, **kwargs
|
345
|
+
) -> QubitWaveFunction:
|
328
346
|
"""
|
329
347
|
Helper function for performing sampling.
|
330
348
|
Parameters
|
@@ -344,8 +362,8 @@ class BackendCircuitQiskit(BackendCircuit):
|
|
344
362
|
the result of sampling.
|
345
363
|
"""
|
346
364
|
optimization_level = 1
|
347
|
-
if
|
348
|
-
optimization_level = kwargs[
|
365
|
+
if "optimization_level" in kwargs:
|
366
|
+
optimization_level = kwargs["optimization_level"]
|
349
367
|
if self.device is None:
|
350
368
|
qiskit_backend = self.retrieve_device(self.STATEVECTOR_DEVICE_NAME)
|
351
369
|
else:
|
@@ -354,12 +372,14 @@ class BackendCircuitQiskit(BackendCircuit):
|
|
354
372
|
if HAS_IBMQ and isinstance(qiskit_backend, IBMBackend):
|
355
373
|
if self.noise_model is not None:
|
356
374
|
raise TequilaException(
|
357
|
-
|
375
|
+
"Cannot combine backend {} with custom noise models.".format(str(qiskit_backend))
|
376
|
+
)
|
358
377
|
circuit = circuit.assign_parameters(self.resolver) # this is necessary in spite of qiskit "fixing" it
|
359
378
|
circuit = qiskit.transpile(circuit, qiskit_backend)
|
360
|
-
return self.convert_measurements(
|
361
|
-
|
362
|
-
|
379
|
+
return self.convert_measurements(
|
380
|
+
qiskit_backend.run(circuit, shots=samples, optimization_level=optimization_level),
|
381
|
+
target_qubits=read_out_qubits,
|
382
|
+
)
|
363
383
|
else:
|
364
384
|
if isinstance(qiskit_backend, qiskit.providers.fake_provider.FakeBackend):
|
365
385
|
circuit = circuit.assign_parameters(self.resolver) # this is necessary in spite of qiskit "fixing" it
|
@@ -370,11 +390,13 @@ class BackendCircuitQiskit(BackendCircuit):
|
|
370
390
|
basis = from_back.basis_gates
|
371
391
|
use_backend = self.retrieve_device(self.STATEVECTOR_DEVICE_NAME)
|
372
392
|
use_backend.set_options(noise_model=from_back)
|
373
|
-
circuit = qiskit.transpile(
|
374
|
-
|
375
|
-
|
376
|
-
|
377
|
-
|
393
|
+
circuit = qiskit.transpile(
|
394
|
+
circuit,
|
395
|
+
backend=use_backend,
|
396
|
+
basis_gates=basis,
|
397
|
+
coupling_map=coupling_map,
|
398
|
+
optimization_level=optimization_level,
|
399
|
+
)
|
378
400
|
|
379
401
|
job = qiskit_backend.run(circuit, shots=samples)
|
380
402
|
return self.convert_measurements(job, target_qubits=read_out_qubits)
|
@@ -386,10 +408,9 @@ class BackendCircuitQiskit(BackendCircuit):
|
|
386
408
|
use_basis = qiskit_backend.configuration().basis_gates
|
387
409
|
circuit = circuit.assign_parameters(self.resolver) # this is necessary -- see qiskit-aer issue 1346
|
388
410
|
circuit = self.add_state_init(circuit, initial_state)
|
389
|
-
circuit = qiskit.transpile(
|
390
|
-
|
391
|
-
|
392
|
-
)
|
411
|
+
circuit = qiskit.transpile(
|
412
|
+
circuit, backend=qiskit_backend, basis_gates=use_basis, optimization_level=optimization_level
|
413
|
+
)
|
393
414
|
|
394
415
|
job = qiskit_backend.run(circuit, shots=samples)
|
395
416
|
return self.convert_measurements(job, target_qubits=read_out_qubits)
|
@@ -461,9 +482,10 @@ class BackendCircuitQiskit(BackendCircuit):
|
|
461
482
|
if len(gate.extract_variables()) > 0:
|
462
483
|
try:
|
463
484
|
par = self.tq_to_pars[gate.parameter]
|
464
|
-
except:
|
485
|
+
except Exception:
|
465
486
|
par = qiskit.circuit.parameter.Parameter(
|
466
|
-
|
487
|
+
"{}_{}".format(self._name_variable_objective(gate.parameter), str(self.counter))
|
488
|
+
)
|
467
489
|
self.tq_to_pars[gate.parameter] = par
|
468
490
|
self.counter += 1
|
469
491
|
else:
|
@@ -471,7 +493,8 @@ class BackendCircuitQiskit(BackendCircuit):
|
|
471
493
|
if gate.is_controlled():
|
472
494
|
if len(gate.control) > 2:
|
473
495
|
raise TequilaQiskitException(
|
474
|
-
"multi-controls beyond 2 not yet supported for the qiskit backend. Gate was:\n{}".format(gate)
|
496
|
+
"multi-controls beyond 2 not yet supported for the qiskit backend. Gate was:\n{}".format(gate)
|
497
|
+
)
|
475
498
|
ops[1](circuit)(par, self.qubit(gate.control[0]), self.qubit(gate.target[0]))
|
476
499
|
else:
|
477
500
|
ops[0](circuit)(par, self.qubit(gate.target[0]))
|
@@ -524,7 +547,8 @@ class BackendCircuitQiskit(BackendCircuit):
|
|
524
547
|
if gate.is_controlled():
|
525
548
|
if len(gate.control) > 2:
|
526
549
|
raise TequilaQiskitException(
|
527
|
-
"multi-controls beyond 2 not yet supported for the qiskit backend. Gate was:\n{}".format(gate)
|
550
|
+
"multi-controls beyond 2 not yet supported for the qiskit backend. Gate was:\n{}".format(gate)
|
551
|
+
)
|
528
552
|
ops[len(gate.control)](circuit)(*[self.qubit(q) for q in gate.control + gate.target])
|
529
553
|
else:
|
530
554
|
ops[0](circuit)(*[self.qubit(q) for q in gate.target])
|
@@ -561,32 +585,16 @@ class BackendCircuitQiskit(BackendCircuit):
|
|
561
585
|
active = active.tensor(action)
|
562
586
|
|
563
587
|
if noise.level == 2:
|
564
|
-
targets = [
|
565
|
-
'cy',
|
566
|
-
'cz',
|
567
|
-
'crz',
|
568
|
-
'crx',
|
569
|
-
'cry',
|
570
|
-
'cu3',
|
571
|
-
'ch']
|
588
|
+
targets = ["cx", "cy", "cz", "crz", "crx", "cry", "cu3", "ch"]
|
572
589
|
|
573
590
|
elif noise.level == 1:
|
574
|
-
targets = [
|
575
|
-
'y',
|
576
|
-
'z',
|
577
|
-
'u3',
|
578
|
-
'u1',
|
579
|
-
'u2',
|
580
|
-
'h',
|
581
|
-
'sx',
|
582
|
-
'unitary'
|
583
|
-
]
|
591
|
+
targets = ["x", "y", "z", "u3", "u1", "u2", "h", "sx", "unitary"]
|
584
592
|
|
585
593
|
elif noise.level == 3:
|
586
|
-
targets = [
|
594
|
+
targets = ["ccx"]
|
587
595
|
|
588
596
|
else:
|
589
|
-
raise TequilaQiskitException(
|
597
|
+
raise TequilaQiskitException("Sorry, no support yet for qiskit for noise on more than 3 qubits.")
|
590
598
|
qnoise.add_all_qubit_quantum_error(active, targets)
|
591
599
|
|
592
600
|
return qnoise
|
@@ -630,12 +638,12 @@ class BackendCircuitQiskit(BackendCircuit):
|
|
630
638
|
|
631
639
|
elif isinstance(device, dict):
|
632
640
|
try:
|
633
|
-
qiskit_provider = device[
|
634
|
-
d = device[
|
641
|
+
qiskit_provider = device["provider"]
|
642
|
+
d = device["name"].lower()
|
635
643
|
qiskit_provider.get_backend(name=d)
|
636
644
|
return
|
637
|
-
except:
|
638
|
-
raise TequilaQiskitException(
|
645
|
+
except Exception:
|
646
|
+
raise TequilaQiskitException("dictionary initialization with device = {} failed.".format(str(device)))
|
639
647
|
|
640
648
|
elif isinstance(device, str):
|
641
649
|
if device.lower() in qiskit_device_dict().keys():
|
@@ -648,8 +656,10 @@ class BackendCircuitQiskit(BackendCircuit):
|
|
648
656
|
return
|
649
657
|
else:
|
650
658
|
raise TequilaQiskitException(
|
651
|
-
|
652
|
-
str(device), type(device)
|
659
|
+
"received device {} of unrecognized type {}; only None, strings, dicts, and qiskit backends allowed".format(
|
660
|
+
str(device), type(device)
|
661
|
+
)
|
662
|
+
)
|
653
663
|
|
654
664
|
def retrieve_device(self, device):
|
655
665
|
"""
|
@@ -672,8 +682,8 @@ class BackendCircuitQiskit(BackendCircuit):
|
|
672
682
|
return device
|
673
683
|
|
674
684
|
elif isinstance(device, dict):
|
675
|
-
qiskit_provider = device[
|
676
|
-
d = device[
|
685
|
+
qiskit_provider = device["provider"]
|
686
|
+
d = device["name"].lower()
|
677
687
|
return qiskit_provider.get_backend(name=d)
|
678
688
|
|
679
689
|
elif isinstance(device, str):
|
@@ -687,8 +697,10 @@ class BackendCircuitQiskit(BackendCircuit):
|
|
687
697
|
return qiskit_provider.get_backend(device)
|
688
698
|
else:
|
689
699
|
raise TequilaQiskitException(
|
690
|
-
|
691
|
-
str(device), type(device)
|
700
|
+
"received device {} of unrecognized type {}; only None, strings, dicts, and qiskit backends allowed".format(
|
701
|
+
str(device), type(device)
|
702
|
+
)
|
703
|
+
)
|
692
704
|
|
693
705
|
|
694
706
|
class BackendExpectationValueQiskit(BackendExpectationValue):
|
@@ -2,13 +2,11 @@ import typing
|
|
2
2
|
from dataclasses import dataclass
|
3
3
|
|
4
4
|
import numpy as np
|
5
|
-
from qat.lang.AQASM import
|
6
|
-
QRoutine, X, Y, Z, build_gate)
|
5
|
+
from qat.lang.AQASM import PH, RX, RY, RZ, SWAP, AbstractGate, H, I, Program, QRoutine, X, Y, Z, build_gate
|
7
6
|
from qat.lang.AQASM.qint import QInt
|
8
7
|
from tequila.circuit._gates_impl import QGateImpl
|
9
8
|
from tequila.circuit.circuit import QCircuit
|
10
|
-
from tequila.simulators.simulator_base import
|
11
|
-
BackendExpectationValue)
|
9
|
+
from tequila.simulators.simulator_base import BackendCircuit, BackendExpectationValue
|
12
10
|
from tequila.utils.bitstrings import BitNumbering, BitString
|
13
11
|
from tequila.utils.exceptions import TequilaException
|
14
12
|
from tequila.utils.misc import to_float
|
@@ -18,6 +16,7 @@ from tequila.wavefunction.qubit_wavefunction import QubitWaveFunction
|
|
18
16
|
MY_QLM = True
|
19
17
|
try:
|
20
18
|
from qat.qpus import LinAlg
|
19
|
+
|
21
20
|
MY_QLM = False
|
22
21
|
except ImportError:
|
23
22
|
from qat.qpus import PyLinalg
|
@@ -42,7 +41,7 @@ def get_statevector(result) -> np.ndarray:
|
|
42
41
|
if result.statevector:
|
43
42
|
return result.statevector
|
44
43
|
qubits = result[0].qregs[0].length
|
45
|
-
statevector = np.zeros((2
|
44
|
+
statevector = np.zeros((2**qubits,), dtype=complex)
|
46
45
|
for sample in result:
|
47
46
|
statevector[sample._state] = sample.amplitude
|
48
47
|
return statevector
|
@@ -62,12 +61,14 @@ def initialize_state(initial_state: int, n_qubits: int):
|
|
62
61
|
----------
|
63
62
|
an abstract gate that uses X gates to create the wanted initial state.
|
64
63
|
"""
|
64
|
+
|
65
65
|
@build_gate("INIT", [])
|
66
66
|
def initialize():
|
67
67
|
routine = QRoutine()
|
68
68
|
qints = routine.new_wires(n_qubits, QInt)
|
69
69
|
qints.set_value(initial_state)
|
70
70
|
return routine
|
71
|
+
|
71
72
|
return initialize
|
72
73
|
|
73
74
|
|
@@ -76,6 +77,7 @@ class RawCircuit:
|
|
76
77
|
"""
|
77
78
|
A helper class to use the qlm program object more like circuits of other simulators.
|
78
79
|
"""
|
80
|
+
|
79
81
|
program: str
|
80
82
|
qubits: float
|
81
83
|
measure: typing.List[int] = None
|
@@ -123,6 +125,7 @@ class BackendCircuitQLM(BackendCircuit):
|
|
123
125
|
Methods
|
124
126
|
-------
|
125
127
|
"""
|
128
|
+
|
126
129
|
compiler_arguments = {
|
127
130
|
"multitarget": True,
|
128
131
|
"multicontrol": False,
|
@@ -142,14 +145,24 @@ class BackendCircuitQLM(BackendCircuit):
|
|
142
145
|
"cc_max": False,
|
143
146
|
"ry_gate": False,
|
144
147
|
"y_gate": False,
|
145
|
-
"ch_gate": False
|
148
|
+
"ch_gate": False,
|
146
149
|
}
|
147
150
|
|
148
151
|
numbering = BitNumbering.MSB
|
149
152
|
|
150
|
-
def __init__(
|
151
|
-
|
152
|
-
|
153
|
+
def __init__(
|
154
|
+
self,
|
155
|
+
abstract_circuit: QCircuit,
|
156
|
+
variables,
|
157
|
+
noise=None,
|
158
|
+
device=None,
|
159
|
+
qubit_map=None,
|
160
|
+
optimize_circuit=True,
|
161
|
+
qpu=None,
|
162
|
+
map_exact_qubits=False,
|
163
|
+
*args,
|
164
|
+
**kwargs,
|
165
|
+
):
|
153
166
|
"""
|
154
167
|
Parameters
|
155
168
|
----------
|
@@ -177,16 +190,16 @@ class BackendCircuitQLM(BackendCircuit):
|
|
177
190
|
"""
|
178
191
|
|
179
192
|
self.op_lookup = {
|
180
|
-
|
181
|
-
|
182
|
-
|
183
|
-
|
184
|
-
|
185
|
-
|
186
|
-
|
187
|
-
|
188
|
-
|
189
|
-
|
193
|
+
"I": I,
|
194
|
+
"X": X,
|
195
|
+
"Y": Y,
|
196
|
+
"Z": Z,
|
197
|
+
"H": H,
|
198
|
+
"Rx": RX,
|
199
|
+
"Ry": RY,
|
200
|
+
"Rz": RZ,
|
201
|
+
"Phase": PH,
|
202
|
+
"SWAP": SWAP,
|
190
203
|
}
|
191
204
|
|
192
205
|
self.tq_to_pars = {}
|
@@ -204,15 +217,25 @@ class BackendCircuitQLM(BackendCircuit):
|
|
204
217
|
"Use of device not suppoted. Device can be imitated by giving a QPu from QLM as parameter 'qpu'."
|
205
218
|
)
|
206
219
|
|
207
|
-
super().__init__(
|
208
|
-
|
220
|
+
super().__init__(
|
221
|
+
abstract_circuit=abstract_circuit,
|
222
|
+
variables=variables,
|
223
|
+
noise=noise,
|
224
|
+
device=device,
|
225
|
+
qubit_map=qubit_map,
|
226
|
+
optimize_circuit=optimize_circuit,
|
227
|
+
*args,
|
228
|
+
**kwargs,
|
229
|
+
)
|
209
230
|
|
210
231
|
if len(self.tq_to_pars.keys()) is None:
|
211
232
|
self.pars_to_tq = None
|
212
233
|
self.pars_for_job = None
|
213
234
|
else:
|
214
235
|
self.pars_to_tq = {v: k for k, v in self.tq_to_pars.items()}
|
215
|
-
self.pars_for_job = {
|
236
|
+
self.pars_for_job = {
|
237
|
+
next(iter(k.get_variables())): to_float(v(variables)) for k, v in self.pars_to_tq.items()
|
238
|
+
}
|
216
239
|
print(self.pars_for_job)
|
217
240
|
|
218
241
|
def initialize_circuit(self, *args, **kwargs) -> RawCircuit:
|
@@ -258,7 +281,7 @@ class BackendCircuitQLM(BackendCircuit):
|
|
258
281
|
try:
|
259
282
|
parameter = self.tq_to_pars[gate.parameter]
|
260
283
|
except KeyError:
|
261
|
-
parameter_name = f
|
284
|
+
parameter_name = f"{self._name_variable_objective(gate.parameter)}_{self.counter}".replace(" ", "$")
|
262
285
|
parameter = circuit.new_var(parameter_name)
|
263
286
|
self.tq_to_pars[gate.parameter] = parameter
|
264
287
|
self.counter += 1
|
@@ -318,8 +341,9 @@ class BackendCircuitQLM(BackendCircuit):
|
|
318
341
|
circuit.measure = target_qubits
|
319
342
|
return circuit
|
320
343
|
|
321
|
-
def do_sample(
|
322
|
-
|
344
|
+
def do_sample(
|
345
|
+
self, samples, circuit: RawCircuit, noise=None, abstract_qubits=None, initial_state=0, *args, **kwargs
|
346
|
+
) -> QubitWaveFunction:
|
323
347
|
"""
|
324
348
|
Helper function for performing sampling.
|
325
349
|
|
@@ -414,7 +438,9 @@ class BackendCircuitQLM(BackendCircuit):
|
|
414
438
|
None
|
415
439
|
"""
|
416
440
|
if self.pars_to_tq is not None:
|
417
|
-
self.pars_for_job = {
|
441
|
+
self.pars_for_job = {
|
442
|
+
next(iter(k.get_variables())): to_float(v(variables)) for k, v in self.pars_to_tq.items()
|
443
|
+
}
|
418
444
|
else:
|
419
445
|
self.pars_for_job = None
|
420
446
|
|