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
@@ -0,0 +1,102 @@
|
|
1
|
+
from calendar import c
|
2
|
+
from tequila.utils.keymap import KeyMapRegisterToSubregister
|
3
|
+
from tequila import BitString
|
4
|
+
from tequila.simulators.simulator_qiskit import (
|
5
|
+
BackendCircuitQiskit,
|
6
|
+
BackendExpectationValueQiskit,
|
7
|
+
TequilaQiskitException,
|
8
|
+
)
|
9
|
+
from qiskit_aqt_provider import AQTProvider
|
10
|
+
from qiskit_aqt_provider.aqt_resource import AQTResource
|
11
|
+
from qiskit.circuit import QuantumCircuit
|
12
|
+
from tequila.wavefunction.qubit_wavefunction import QubitWaveFunction
|
13
|
+
from tequila import TequilaException
|
14
|
+
import qiskit
|
15
|
+
from typing import Union
|
16
|
+
|
17
|
+
|
18
|
+
class TequilaAQTException(TequilaQiskitException):
|
19
|
+
def __str__(self):
|
20
|
+
return "Error in AQT backend:" + self.message
|
21
|
+
|
22
|
+
|
23
|
+
class BackendCircuitAQT(BackendCircuitQiskit):
|
24
|
+
def __init__(self, *args, **kwargs):
|
25
|
+
super().__init__(*args, **kwargs)
|
26
|
+
if "device" in kwargs.keys() and kwargs["device"] is not None:
|
27
|
+
self.device = kwargs["device"]
|
28
|
+
|
29
|
+
def retrieve_backend(self) -> AQTResource:
|
30
|
+
if self.device is None:
|
31
|
+
raise TequilaAQTException("No AQT device specified. Please provide a valid AQT device as backend.")
|
32
|
+
return self.device
|
33
|
+
|
34
|
+
# state measurement operation?
|
35
|
+
def get_circuit(
|
36
|
+
self, circuit: QuantumCircuit, qiskit_backend, initial_state=0, optimization_level=1, *args, **kwargs
|
37
|
+
) -> QuantumCircuit:
|
38
|
+
circ = circuit.assign_parameters(self.resolver) # this is necessary -- see qiskit-aer issue 1346
|
39
|
+
circ = self.add_state_init(circ, initial_state)
|
40
|
+
basis = qiskit_backend.target.operation_names
|
41
|
+
circ = qiskit.transpile(circ, backend=qiskit_backend, basis_gates=basis, optimization_level=optimization_level)
|
42
|
+
return circ
|
43
|
+
|
44
|
+
def sample(self, variables, samples, read_out_qubits=None, circuit=None, initial_state=0, *args, **kwargs):
|
45
|
+
if initial_state != 0 and not self.supports_sampling_initialization:
|
46
|
+
raise TequilaException("Backend does not support initial states for sampling")
|
47
|
+
|
48
|
+
if isinstance(initial_state, QubitWaveFunction) and not self.supports_generic_initialization:
|
49
|
+
raise TequilaException("Backend does not support arbitrary initial states")
|
50
|
+
|
51
|
+
self.update_variables(variables)
|
52
|
+
if read_out_qubits is None:
|
53
|
+
read_out_qubits = self.abstract_qubits
|
54
|
+
|
55
|
+
if len(read_out_qubits) == 0:
|
56
|
+
raise Exception("read_out_qubits are empty")
|
57
|
+
|
58
|
+
if circuit is None:
|
59
|
+
circuit = self.add_measurement(circuit=self.circuit, target_qubits=read_out_qubits)
|
60
|
+
else:
|
61
|
+
if isinstance(circuit, list):
|
62
|
+
assert len(circuit) == len(read_out_qubits), "circuit and read_out_qubits have to be of the same length"
|
63
|
+
for i, c in enumerate(circuit):
|
64
|
+
circuit[i] = self.add_measurement(circuit=c, target_qubits=read_out_qubits[i])
|
65
|
+
else:
|
66
|
+
circuit = self.add_measurement(circuit=circuit, target_qubits=read_out_qubits)
|
67
|
+
return self.do_sample(
|
68
|
+
samples=samples,
|
69
|
+
circuit=circuit,
|
70
|
+
read_out_qubits=read_out_qubits,
|
71
|
+
initial_state=initial_state,
|
72
|
+
*args,
|
73
|
+
**kwargs,
|
74
|
+
)
|
75
|
+
|
76
|
+
def do_sample(
|
77
|
+
self, circuit: QuantumCircuit, samples: int, read_out_qubits, initial_state=0, *args, **kwargs
|
78
|
+
) -> QubitWaveFunction:
|
79
|
+
optimization_level = 1
|
80
|
+
if "optimization_level" in kwargs:
|
81
|
+
optimization_level = kwargs["optimization_level"]
|
82
|
+
qiskit_backend = self.retrieve_backend()
|
83
|
+
|
84
|
+
circuit = self.get_circuit(
|
85
|
+
circuit=circuit,
|
86
|
+
qiskit_backend=qiskit_backend,
|
87
|
+
initial_state=initial_state,
|
88
|
+
optimization_level=optimization_level,
|
89
|
+
*args,
|
90
|
+
**kwargs,
|
91
|
+
)
|
92
|
+
job = qiskit_backend.run(circuit, shots=samples)
|
93
|
+
wfn = self.convert_measurements(job, target_qubits=read_out_qubits)
|
94
|
+
|
95
|
+
return wfn
|
96
|
+
|
97
|
+
def do_simulate(self, variables, initial_state=0, *args, **kwargs):
|
98
|
+
raise TequilaAQTException("AQT backend does not support do_simulate")
|
99
|
+
|
100
|
+
|
101
|
+
class BackendExpectationValueAQT(BackendExpectationValueQiskit):
|
102
|
+
BackendCircuitType = BackendCircuitAQT
|
@@ -1,3 +1,4 @@
|
|
1
|
+
from tequila.circuit._gates_impl import GlobalPhaseGateImpl
|
1
2
|
from tequila.utils import TequilaException, to_float, TequilaWarning
|
2
3
|
from tequila.circuit.circuit import QCircuit
|
3
4
|
from tequila.utils.keymap import KeyMapSubregisterToRegister
|
@@ -8,8 +9,13 @@ from tequila import BitString
|
|
8
9
|
from tequila.objective.objective import Variable, format_variable_dictionary
|
9
10
|
from tequila.circuit import compiler
|
10
11
|
from typing import Union
|
12
|
+
import numpy as np
|
11
13
|
|
12
|
-
import numbers
|
14
|
+
import numbers
|
15
|
+
import typing
|
16
|
+
import numpy
|
17
|
+
import copy
|
18
|
+
import warnings
|
13
19
|
|
14
20
|
from dataclasses import dataclass
|
15
21
|
|
@@ -20,7 +26,7 @@ Todo: Classes are now immutable:
|
|
20
26
|
"""
|
21
27
|
|
22
28
|
|
23
|
-
class BackendCircuit
|
29
|
+
class BackendCircuit:
|
24
30
|
"""
|
25
31
|
Base class for circuits compiled to run on specific backends.
|
26
32
|
|
@@ -105,7 +111,7 @@ class BackendCircuit():
|
|
105
111
|
"controlled_phase": True,
|
106
112
|
"toffoli": True,
|
107
113
|
"phase_to_z": True,
|
108
|
-
"cc_max": True
|
114
|
+
"cc_max": True,
|
109
115
|
}
|
110
116
|
|
111
117
|
# Can be overwritten by backends that allow basis state initialization when sampling
|
@@ -135,8 +141,17 @@ class BackendCircuit():
|
|
135
141
|
"""
|
136
142
|
return self.qubit_map[abstract_qubit].instance
|
137
143
|
|
138
|
-
def __init__(
|
139
|
-
|
144
|
+
def __init__(
|
145
|
+
self,
|
146
|
+
abstract_circuit: QCircuit,
|
147
|
+
variables,
|
148
|
+
noise=None,
|
149
|
+
device=None,
|
150
|
+
qubit_map=None,
|
151
|
+
optimize_circuit=True,
|
152
|
+
*args,
|
153
|
+
**kwargs,
|
154
|
+
):
|
140
155
|
"""
|
141
156
|
|
142
157
|
Parameters
|
@@ -160,8 +175,15 @@ class BackendCircuit():
|
|
160
175
|
kwargs
|
161
176
|
"""
|
162
177
|
|
163
|
-
self._input_args = {
|
164
|
-
|
178
|
+
self._input_args = {
|
179
|
+
"abstract_circuit": abstract_circuit,
|
180
|
+
"variables": variables,
|
181
|
+
"noise": noise,
|
182
|
+
"qubit_map": qubit_map,
|
183
|
+
"optimize_circuits": optimize_circuit,
|
184
|
+
"device": device,
|
185
|
+
**kwargs,
|
186
|
+
}
|
165
187
|
|
166
188
|
self.no_translation = False
|
167
189
|
self._variables = tuple(abstract_circuit.extract_variables())
|
@@ -179,14 +201,24 @@ class BackendCircuit():
|
|
179
201
|
if qubit_map is None:
|
180
202
|
qubit_map = {q: i for i, q in enumerate(abstract_circuit.qubits)}
|
181
203
|
elif not qubit_map == {q: i for i, q in enumerate(abstract_circuit.qubits)}:
|
182
|
-
warnings.warn(
|
183
|
-
|
184
|
-
|
204
|
+
warnings.warn(
|
205
|
+
"reveived custom qubit_map = {}\n"
|
206
|
+
"This is not fully integrated and might result in unexpected behaviour!".format(qubit_map),
|
207
|
+
TequilaWarning,
|
208
|
+
)
|
185
209
|
|
186
|
-
if len(qubit_map) > abstract_circuit.max_qubit()+1:
|
187
|
-
raise TequilaException(
|
210
|
+
if len(qubit_map) > abstract_circuit.max_qubit() + 1:
|
211
|
+
raise TequilaException(
|
212
|
+
"Custom qubit_map has too many qubits {} vs {}".format(
|
213
|
+
len(qubit_map), abstract_circuit.max_qubit() + 1
|
214
|
+
)
|
215
|
+
)
|
188
216
|
if max(qubit_map.keys()) > abstract_circuit.max_qubit():
|
189
|
-
raise TequilaException(
|
217
|
+
raise TequilaException(
|
218
|
+
"Custom qubit_map tries to assign qubit {} but we only have {}".format(
|
219
|
+
max(qubit_map.keys()), abstract_circuit.max_qubit()
|
220
|
+
)
|
221
|
+
)
|
190
222
|
|
191
223
|
# qubit map is initialized to have BackendQubits as values (they carry number and instance attributes)
|
192
224
|
self.qubit_map = self.make_qubit_map(qubit_map)
|
@@ -195,6 +227,10 @@ class BackendCircuit():
|
|
195
227
|
compiled = c(abstract_circuit)
|
196
228
|
self.abstract_circuit = compiled
|
197
229
|
|
230
|
+
self.global_phase = sum(g.parameter for g in compiled.gates if isinstance(g, GlobalPhaseGateImpl))
|
231
|
+
# Filter out identity and global phase gates because they should not be passed to the backends
|
232
|
+
compiled.gates = filter(lambda g: g.name != "I" and not isinstance(g, GlobalPhaseGateImpl), compiled.gates)
|
233
|
+
|
198
234
|
self.noise = noise
|
199
235
|
self.check_device(device)
|
200
236
|
self.device = self.retrieve_device(device)
|
@@ -205,11 +241,7 @@ class BackendCircuit():
|
|
205
241
|
if optimize_circuit and noise is None:
|
206
242
|
self.circuit = self.optimize_circuit(circuit=self.circuit)
|
207
243
|
|
208
|
-
def __call__(self,
|
209
|
-
variables: typing.Dict[Variable, numbers.Real] = None,
|
210
|
-
samples: int = None,
|
211
|
-
*args,
|
212
|
-
**kwargs):
|
244
|
+
def __call__(self, variables: typing.Dict[Variable, numbers.Real] = None, samples: int = None, *args, **kwargs):
|
213
245
|
"""
|
214
246
|
Simulate or sample the backend circuit.
|
215
247
|
|
@@ -233,7 +265,9 @@ class BackendCircuit():
|
|
233
265
|
if variables is None or set(self._variables) > set(variables.keys()):
|
234
266
|
raise TequilaException(
|
235
267
|
"BackendCircuit received not all variables. Circuit depends on variables {}, you gave {}".format(
|
236
|
-
self._variables, variables
|
268
|
+
self._variables, variables
|
269
|
+
)
|
270
|
+
)
|
237
271
|
|
238
272
|
self.update_variables(variables)
|
239
273
|
if samples is None:
|
@@ -269,7 +303,7 @@ class BackendCircuit():
|
|
269
303
|
result = self.initialize_circuit(*args, **kwargs)
|
270
304
|
|
271
305
|
for g in abstract_circuit.gates:
|
272
|
-
if g.
|
306
|
+
if g.is_parameterized():
|
273
307
|
self.add_parametrized_gate(g, result, *args, **kwargs)
|
274
308
|
else:
|
275
309
|
self.add_basic_gate(g, result, *args, **kwargs)
|
@@ -292,7 +326,7 @@ class BackendCircuit():
|
|
292
326
|
TequilaException
|
293
327
|
"""
|
294
328
|
if device is not None:
|
295
|
-
raise TequilaException(
|
329
|
+
raise TequilaException("Devices not enabled for {}".format(str(type(self))))
|
296
330
|
|
297
331
|
def retrieve_device(self, device):
|
298
332
|
"""
|
@@ -313,7 +347,7 @@ class BackendCircuit():
|
|
313
347
|
if device is None:
|
314
348
|
return device
|
315
349
|
else:
|
316
|
-
raise TequilaException(
|
350
|
+
raise TequilaException("Devices not enabled for {}".format(str(type(self))))
|
317
351
|
|
318
352
|
def add_parametrized_gate(self, gate, circuit, *args, **kwargs):
|
319
353
|
raise TequilaException("Backend Handler needs to be overwritten for supported simulators")
|
@@ -334,7 +368,9 @@ class BackendCircuit():
|
|
334
368
|
"""
|
335
369
|
self.circuit = self.create_circuit(abstract_circuit=self.abstract_circuit, variables=variables)
|
336
370
|
|
337
|
-
def simulate(
|
371
|
+
def simulate(
|
372
|
+
self, variables, initial_state: Union[int, QubitWaveFunction] = 0, *args, **kwargs
|
373
|
+
) -> QubitWaveFunction:
|
338
374
|
"""
|
339
375
|
simulate the circuit via the backend.
|
340
376
|
|
@@ -382,11 +418,17 @@ class BackendCircuit():
|
|
382
418
|
else:
|
383
419
|
mapped_initial_state = initial_state
|
384
420
|
|
385
|
-
result = self.do_simulate(variables=variables, initial_state=mapped_initial_state, *args,
|
386
|
-
|
421
|
+
result = self.do_simulate(variables=variables, initial_state=mapped_initial_state, *args, **kwargs)
|
422
|
+
|
423
|
+
# Multiply the state by its global phase (consisting of the sum of the arguments of all global phases)
|
424
|
+
# Does currently not support variable parameters
|
425
|
+
if isinstance(self.global_phase, float):
|
426
|
+
result *= np.exp(1j * self.global_phase)
|
387
427
|
|
388
428
|
if keymap_required:
|
389
|
-
result = QubitWaveFunction.from_wavefunction(
|
429
|
+
result = QubitWaveFunction.from_wavefunction(
|
430
|
+
result, keymap, n_qubits=len(all_qubits), initial_state=initial_state
|
431
|
+
)
|
390
432
|
|
391
433
|
return result
|
392
434
|
|
@@ -428,11 +470,18 @@ class BackendCircuit():
|
|
428
470
|
else:
|
429
471
|
circuit = self.add_measurement(circuit=circuit, target_qubits=read_out_qubits)
|
430
472
|
|
431
|
-
return self.do_sample(
|
432
|
-
|
433
|
-
|
434
|
-
|
435
|
-
|
473
|
+
return self.do_sample(
|
474
|
+
samples=samples,
|
475
|
+
circuit=circuit,
|
476
|
+
read_out_qubits=read_out_qubits,
|
477
|
+
initial_state=initial_state,
|
478
|
+
*args,
|
479
|
+
**kwargs,
|
480
|
+
)
|
481
|
+
|
482
|
+
def sample_all_z_hamiltonian(
|
483
|
+
self, samples: int, hamiltonian, variables, initial_state: Union[int, QubitWaveFunction] = 0, *args, **kwargs
|
484
|
+
):
|
436
485
|
"""
|
437
486
|
Sample from a Hamiltonian which only consists of Pauli-Z and unit operators
|
438
487
|
Parameters
|
@@ -457,11 +506,20 @@ class BackendCircuit():
|
|
457
506
|
# assert that the Hamiltonian was mapped before
|
458
507
|
if not all(q in self.qubit_map.keys() for q in abstract_qubits_H):
|
459
508
|
raise TequilaException(
|
460
|
-
"Qubits in {}-qubit Hamiltonian were not traced out for {}-qubit circuit".format(
|
461
|
-
|
509
|
+
"Qubits in {}-qubit Hamiltonian were not traced out for {}-qubit circuit".format(
|
510
|
+
hamiltonian.n_qubits, self.n_qubits
|
511
|
+
)
|
512
|
+
)
|
462
513
|
|
463
514
|
# run simulators
|
464
|
-
counts = self.sample(
|
515
|
+
counts = self.sample(
|
516
|
+
samples=samples,
|
517
|
+
read_out_qubits=abstract_qubits_H,
|
518
|
+
variables=variables,
|
519
|
+
initial_state=initial_state,
|
520
|
+
*args,
|
521
|
+
**kwargs,
|
522
|
+
)
|
465
523
|
read_out_map = {q: i for i, q in enumerate(abstract_qubits_H)}
|
466
524
|
|
467
525
|
# compute energy
|
@@ -484,8 +542,9 @@ class BackendCircuit():
|
|
484
542
|
assert n_samples == samples
|
485
543
|
return E
|
486
544
|
|
487
|
-
def sample_paulistring(
|
488
|
-
|
545
|
+
def sample_paulistring(
|
546
|
+
self, samples: int, paulistring, variables, initial_state: Union[int, QubitWaveFunction] = 0, *args, **kwargs
|
547
|
+
) -> numbers.Real:
|
489
548
|
"""
|
490
549
|
Sample an individual pauli word (pauli string) and return the average result thereof.
|
491
550
|
Parameters
|
@@ -523,8 +582,15 @@ class BackendCircuit():
|
|
523
582
|
# on construction: tq.ExpectationValue(H=H, U=U, optimize_measurements=True)
|
524
583
|
circuit = self.create_circuit(circuit=copy.deepcopy(self.circuit), abstract_circuit=basis_change)
|
525
584
|
# run simulators
|
526
|
-
counts = self.sample(
|
527
|
-
|
585
|
+
counts = self.sample(
|
586
|
+
samples=samples,
|
587
|
+
circuit=circuit,
|
588
|
+
read_out_qubits=qubits,
|
589
|
+
variables=variables,
|
590
|
+
initial_state=initial_state,
|
591
|
+
*args,
|
592
|
+
**kwargs,
|
593
|
+
)
|
528
594
|
# compute energy
|
529
595
|
E = 0.0
|
530
596
|
n_samples = 0
|
@@ -537,7 +603,9 @@ class BackendCircuit():
|
|
537
603
|
E = E / samples * paulistring.coeff
|
538
604
|
return E
|
539
605
|
|
540
|
-
def do_sample(
|
606
|
+
def do_sample(
|
607
|
+
self, samples, circuit, noise, abstract_qubits=None, initial_state=0, *args, **kwargs
|
608
|
+
) -> QubitWaveFunction:
|
541
609
|
"""
|
542
610
|
helper function for sampling. MUST be overwritten by inheritors.
|
543
611
|
|
@@ -731,6 +799,7 @@ class BackendExpectationValue:
|
|
731
799
|
wrapper over the update_variables of BackendCircuit.
|
732
800
|
|
733
801
|
"""
|
802
|
+
|
734
803
|
BackendCircuitType = BackendCircuit
|
735
804
|
|
736
805
|
# map to smaller subsystem if there are qubits which are not touched by the circuits,
|
@@ -795,14 +864,17 @@ class BackendExpectationValue:
|
|
795
864
|
def __deepcopy__(self, memodict={}):
|
796
865
|
return type(self)(self.abstract_expectationvalue, **self._input_args)
|
797
866
|
|
798
|
-
def __call__(
|
799
|
-
|
867
|
+
def __call__(
|
868
|
+
self, variables, samples: int = None, initial_state: Union[int, QubitWaveFunction] = 0, *args, **kwargs
|
869
|
+
):
|
800
870
|
variables = format_variable_dictionary(variables=variables)
|
801
871
|
if self._variables is not None and len(self._variables) > 0:
|
802
872
|
if variables is None or (not set(self._variables) <= set(variables.keys())):
|
803
873
|
raise TequilaException(
|
804
874
|
"BackendExpectationValue received not all variables. Circuit depends on variables {}, you gave {}".format(
|
805
|
-
self._variables, variables
|
875
|
+
self._variables, variables
|
876
|
+
)
|
877
|
+
)
|
806
878
|
|
807
879
|
if samples is None:
|
808
880
|
data = self.simulate(variables=variables, initial_state=initial_state, *args, **kwargs)
|
@@ -847,15 +919,23 @@ class BackendExpectationValue:
|
|
847
919
|
|
848
920
|
def initialize_unitary(self, U, variables, noise, device, *args, **kwargs):
|
849
921
|
"""return a compiled unitary"""
|
850
|
-
return self.BackendCircuitType(
|
851
|
-
|
852
|
-
|
922
|
+
return self.BackendCircuitType(
|
923
|
+
abstract_circuit=U,
|
924
|
+
variables=variables,
|
925
|
+
device=device,
|
926
|
+
use_mapping=self.use_mapping,
|
927
|
+
noise=noise,
|
928
|
+
*args,
|
929
|
+
**kwargs,
|
930
|
+
)
|
853
931
|
|
854
932
|
def update_variables(self, variables):
|
855
933
|
"""wrapper over circuit update_variables"""
|
856
934
|
self._U.update_variables(variables=variables)
|
857
935
|
|
858
|
-
def sample(
|
936
|
+
def sample(
|
937
|
+
self, variables, samples, initial_state: Union[int, QubitWaveFunction] = 0, *args, **kwargs
|
938
|
+
) -> numpy.array:
|
859
939
|
"""
|
860
940
|
sample the expectationvalue.
|
861
941
|
|
@@ -879,14 +959,21 @@ class BackendExpectationValue:
|
|
879
959
|
suggested = None
|
880
960
|
if hasattr(samples, "lower") and samples.lower()[:4] == "auto":
|
881
961
|
if self.abstract_expectationvalue.samples is None:
|
882
|
-
raise TequilaException(
|
962
|
+
raise TequilaException(
|
963
|
+
"samples='auto' requested but no samples where set in individual expectation values"
|
964
|
+
)
|
883
965
|
total_samples = int(samples[5:])
|
884
966
|
samples = max(1, int(self.abstract_expectationvalue.samples * total_samples))
|
885
967
|
suggested = samples
|
886
968
|
# samples are not necessarily set (either the user has to set it or some functions like optimize_measurements)
|
887
969
|
|
888
970
|
if suggested is not None and suggested != samples:
|
889
|
-
warnings.warn(
|
971
|
+
warnings.warn(
|
972
|
+
"simulating with samples={}, but expectationvalue carries suggested samples={}\nTry calling with samples='auto-total#ofsamples'".format(
|
973
|
+
samples, suggested
|
974
|
+
),
|
975
|
+
TequilaWarning,
|
976
|
+
)
|
890
977
|
|
891
978
|
self.update_variables(variables)
|
892
979
|
|
@@ -896,16 +983,23 @@ class BackendExpectationValue:
|
|
896
983
|
if len(H.qubits) == 0:
|
897
984
|
E = sum([ps.coeff for ps in H.paulistrings])
|
898
985
|
elif H.is_all_z():
|
899
|
-
E = self.U.sample_all_z_hamiltonian(
|
900
|
-
|
986
|
+
E = self.U.sample_all_z_hamiltonian(
|
987
|
+
samples=samples, hamiltonian=H, variables=variables, initial_state=initial_state, *args, **kwargs
|
988
|
+
)
|
901
989
|
else:
|
902
990
|
for ps in H.paulistrings:
|
903
|
-
E += self.U.sample_paulistring(
|
904
|
-
|
991
|
+
E += self.U.sample_paulistring(
|
992
|
+
samples=samples,
|
993
|
+
paulistring=ps,
|
994
|
+
variables=variables,
|
995
|
+
initial_state=initial_state,
|
996
|
+
*args,
|
997
|
+
**kwargs,
|
998
|
+
)
|
905
999
|
result.append(to_float(E))
|
906
1000
|
return numpy.asarray(result)
|
907
1001
|
|
908
|
-
def simulate(self, variables, initial_state: Union[int, QubitWaveFunction], *args, **kwargs):
|
1002
|
+
def simulate(self, variables, initial_state: Union[int, QubitWaveFunction], *args, **kwargs) -> numpy.array:
|
909
1003
|
"""
|
910
1004
|
Simulate the expectationvalue.
|
911
1005
|
|