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
tequila/ml/ml_api.py
CHANGED
@@ -1,29 +1,30 @@
|
|
1
1
|
from .utils_ml import TequilaMLException
|
2
|
-
from shutil import which
|
3
2
|
from tequila.objective import Objective
|
4
|
-
|
3
|
+
|
4
|
+
SUPPORTED_PLATFORMS = ["pytorch"]
|
5
5
|
CONVERTERS = {}
|
6
6
|
|
7
|
-
#HAS_TORCH = which('torch') is not None or which('pytorch') is not None
|
7
|
+
# HAS_TORCH = which('torch') is not None or which('pytorch') is not None
|
8
8
|
HAS_TORCH = True
|
9
9
|
try:
|
10
10
|
import torch
|
11
|
-
except:
|
11
|
+
except Exception:
|
12
12
|
HAS_TORCH = False
|
13
13
|
|
14
14
|
if HAS_TORCH:
|
15
15
|
from .interface_torch import TorchLayer
|
16
|
-
CONVERTERS['pytorch'] = TorchLayer
|
17
16
|
|
18
|
-
|
19
|
-
|
17
|
+
CONVERTERS["pytorch"] = TorchLayer
|
18
|
+
|
19
|
+
|
20
|
+
def to_platform(objective: Objective, platform: str, compile_args: dict = None, input_vars: list = None):
|
20
21
|
plat = platform.lower()
|
21
|
-
if plat ==
|
22
|
+
if plat == "torch":
|
22
23
|
# common alias.
|
23
|
-
plat =
|
24
|
+
plat = "pytorch"
|
24
25
|
|
25
26
|
try:
|
26
27
|
f = CONVERTERS[plat]
|
27
28
|
return f(objective, compile_args, input_vars)
|
28
29
|
except KeyError:
|
29
|
-
raise TequilaMLException(
|
30
|
+
raise TequilaMLException("Desired ML platform {} either not supported, or not installed.".format(plat))
|
tequila/ml/utils_ml.py
CHANGED
@@ -1,6 +1,5 @@
|
|
1
1
|
from tequila.utils.exceptions import TequilaException
|
2
|
-
from tequila.objective.objective import assign_variable, Objective
|
3
|
-
format_variable_dictionary, format_variable_list
|
2
|
+
from tequila.objective.objective import assign_variable, Objective, format_variable_dictionary, format_variable_list
|
4
3
|
import typing
|
5
4
|
from tequila.simulators.simulator_api import compile
|
6
5
|
from tequila.circuit.gradient import grad
|
@@ -29,12 +28,12 @@ def check_compiler_args(c_args: dict) -> typing.Dict:
|
|
29
28
|
tequila.simulators.simulator_api.compile
|
30
29
|
"""
|
31
30
|
|
32
|
-
valid_keys=[
|
31
|
+
valid_keys = ["backend", "samples", "noise", "device", "initial_values"]
|
33
32
|
if c_args is None:
|
34
|
-
return {k:None for k in valid_keys}
|
33
|
+
return {k: None for k in valid_keys}
|
35
34
|
for k in c_args.keys():
|
36
35
|
if k not in valid_keys:
|
37
|
-
raise TequilaException(
|
36
|
+
raise TequilaException("improper keyword {} found in compilation kwargs dict; please try again.".format(k))
|
38
37
|
else:
|
39
38
|
pass
|
40
39
|
for k in valid_keys:
|
@@ -64,8 +63,10 @@ def preamble(objective: Objective, compile_args: dict = None, input_vars: list =
|
|
64
63
|
the compiled objective, it's compile arguments, its weight variables, dicts for the weight and input gradients,
|
65
64
|
and a dictionary that links positions in an array to each variable (parses parameters).
|
66
65
|
"""
|
66
|
+
|
67
67
|
def var_sorter(e):
|
68
68
|
return hash(e.name)
|
69
|
+
|
69
70
|
all_vars = objective.extract_variables()
|
70
71
|
all_vars.sort(key=var_sorter)
|
71
72
|
compile_args = check_compiler_args(compile_args)
|
@@ -80,21 +81,22 @@ def preamble(objective: Objective, compile_args: dict = None, input_vars: list =
|
|
80
81
|
if var not in input_vars:
|
81
82
|
weight_vars.append(assign_variable(var))
|
82
83
|
|
83
|
-
init_vals = compile_args[
|
84
|
+
init_vals = compile_args["initial_values"]
|
84
85
|
if init_vals is not None:
|
85
86
|
for k in init_vals.keys():
|
86
87
|
if assign_variable(k) in input_vars:
|
87
|
-
raise TequilaMLException(
|
88
|
-
|
88
|
+
raise TequilaMLException(
|
89
|
+
"initial_values contained key {},which is meant to be an input variable.".format(k)
|
90
|
+
)
|
89
91
|
init_vals = format_variable_dictionary(init_vals)
|
90
|
-
compile_args.pop(
|
92
|
+
compile_args.pop("initial_values")
|
91
93
|
|
92
94
|
comped = compile(objective, **compile_args)
|
93
95
|
|
94
96
|
gradients = get_gradients(objective, compile_args)
|
95
97
|
w_grad, i_grad = separate_gradients(gradients, weight_vars=weight_vars, input_vars=input_vars)
|
96
98
|
first, second = get_variable_orders(weight_vars, input_vars)
|
97
|
-
compile_args[
|
99
|
+
compile_args["initial_values"] = init_vals
|
98
100
|
return comped, compile_args, input_vars, weight_vars, i_grad, w_grad, first, second
|
99
101
|
|
100
102
|
|
@@ -179,4 +181,3 @@ def get_variable_orders(weight_vars, input_vars):
|
|
179
181
|
for j, v in enumerate(weight_vars):
|
180
182
|
second[j] = v
|
181
183
|
return first, second
|
182
|
-
|
tequila/objective/__init__.py
CHANGED
@@ -1,5 +1,10 @@
|
|
1
|
-
from tequila.objective.objective import
|
2
|
-
|
3
|
-
|
1
|
+
from tequila.objective.objective import (
|
2
|
+
Objective,
|
3
|
+
ExpectationValue,
|
4
|
+
Variable,
|
5
|
+
assign_variable,
|
6
|
+
format_variable_list,
|
7
|
+
format_variable_dictionary,
|
8
|
+
)
|
4
9
|
|
5
10
|
from tequila.objective.qtensor import QTensor, VectorObjective, vectorize
|
tequila/objective/braket.py
CHANGED
@@ -7,7 +7,8 @@ from tequila.hamiltonian import paulis
|
|
7
7
|
|
8
8
|
import numpy as np
|
9
9
|
|
10
|
-
|
10
|
+
|
11
|
+
def Fidelity(bra, ket, *args, **kwargs):
|
11
12
|
"""
|
12
13
|
|
13
14
|
Convenience initialization of an tq.Objective that corresponds to the fidelity |<bra|ket>|^2 between two quantum states
|
@@ -41,9 +42,10 @@ def Fidelity(bra,ket,*args,**kwargs):
|
|
41
42
|
P0 = paulis.Qp(qubits)
|
42
43
|
return ExpectationValue(H=P0, U=U, *args, **kwargs)
|
43
44
|
|
44
|
-
|
45
|
+
|
46
|
+
def Overlap(bra, ket, *args, **kwargs):
|
45
47
|
"""
|
46
|
-
|
48
|
+
|
47
49
|
Convenience initialization of an tq.Objective that corresponds to the overlap <bra|ket>
|
48
50
|
initialized by the circuits bra and ket
|
49
51
|
|
@@ -55,7 +57,7 @@ def Overlap(bra,ket,*args,**kwargs):
|
|
55
57
|
----------
|
56
58
|
bra: QCircuit
|
57
59
|
ket: QCircuit
|
58
|
-
|
60
|
+
|
59
61
|
Returns:
|
60
62
|
----------
|
61
63
|
A tuple of tq.Objective that evaluates to the real and imaginary part of the overlap between the two states
|
@@ -64,8 +66,9 @@ def Overlap(bra,ket,*args,**kwargs):
|
|
64
66
|
|
65
67
|
return BraKet(ket=ket, bra=bra, operator=None, *args, **kwargs)
|
66
68
|
|
69
|
+
|
67
70
|
def BraKet(ket: QCircuit, bra: QCircuit = None, operator: QubitHamiltonian = None, *args, **kwargs) -> ExpectationValue:
|
68
|
-
"""Function that allows to calculate different quantities
|
71
|
+
"""Function that allows to calculate different quantities
|
69
72
|
depending on the passed parameters:
|
70
73
|
1) If only ket is passed, returns the overlap with itself (1).
|
71
74
|
2) If ket and bra are passed, returns the overlap between the two states.
|
@@ -75,23 +78,25 @@ def BraKet(ket: QCircuit, bra: QCircuit = None, operator: QubitHamiltonian = Non
|
|
75
78
|
returns an instance of tq.Objective
|
76
79
|
|
77
80
|
Args:
|
78
|
-
ket (QCircuit): QCircuit corresponding to a state.
|
81
|
+
ket (QCircuit): QCircuit corresponding to a state.
|
79
82
|
bra (QCircuit, optional): QCircuit corresponding to a second state.
|
80
83
|
Defaults to None.
|
81
|
-
operator (QubitHamiltonian, optional): Operator of which we want to
|
82
|
-
calculate the transition element.
|
84
|
+
operator (QubitHamiltonian, optional): Operator of which we want to
|
85
|
+
calculate the transition element.
|
83
86
|
Defaults to None.
|
84
87
|
|
85
88
|
Returns:
|
86
89
|
a tuple of tq.Objective representing the real and imaginary part of the BraKet
|
87
90
|
"""
|
88
|
-
|
91
|
+
|
89
92
|
# allow for some convenience
|
90
93
|
if "H" in kwargs:
|
91
94
|
if operator is None:
|
92
|
-
operator=kwargs["H"]
|
95
|
+
operator = kwargs["H"]
|
93
96
|
else:
|
94
|
-
raise TequilaException(
|
97
|
+
raise TequilaException(
|
98
|
+
'BraKet inconsistency between operator and kwargs["H"] do not given H= ... and operator= ... in the same call'
|
99
|
+
)
|
95
100
|
kwargs.pop("H")
|
96
101
|
|
97
102
|
if bra is None:
|
@@ -99,86 +104,89 @@ def BraKet(ket: QCircuit, bra: QCircuit = None, operator: QubitHamiltonian = Non
|
|
99
104
|
|
100
105
|
if id(ket) == id(bra):
|
101
106
|
if operator is None:
|
102
|
-
return Objective()+1.0
|
103
|
-
return ExpectationValue(H=operator, U=ket, *args, **kwargs)
|
107
|
+
return Objective() + 1.0, Objective()
|
108
|
+
return ExpectationValue(H=operator, U=ket, *args, **kwargs), Objective()
|
104
109
|
else:
|
105
110
|
if operator is None:
|
106
|
-
return make_overlap(U0
|
107
|
-
|
108
|
-
return make_transition(U0
|
111
|
+
return make_overlap(U0=bra, U1=ket, *args, **kwargs)
|
112
|
+
|
113
|
+
return make_transition(U0=bra, U1=ket, H=operator, *args, **kwargs)
|
109
114
|
|
110
|
-
|
111
|
-
|
115
|
+
|
116
|
+
def make_overlap(U0: QCircuit = None, U1: QCircuit = None, *args, **kwargs) -> ExpectationValue:
|
117
|
+
"""
|
112
118
|
Function that calculates the overlap between two quantum states.
|
113
119
|
|
114
120
|
Parameters
|
115
121
|
----------
|
116
122
|
U0 : QCircuit tequila object, corresponding to the first state (will be the bra).
|
117
|
-
|
123
|
+
|
118
124
|
U1 : QCircuit tequila object, corresponding to the second state (will be the ket).
|
119
125
|
|
120
126
|
Returns
|
121
127
|
-------
|
122
128
|
Real and imaginary Tequila objectives to be simulated or compiled.
|
123
129
|
|
124
|
-
|
125
|
-
|
130
|
+
"""
|
131
|
+
|
126
132
|
ctrl = find_unused_qubit(U0=U0, U1=U1)
|
127
|
-
|
128
|
-
#print('Control qubit:',ctrl)
|
129
|
-
|
130
|
-
U_a = U0.add_controls([ctrl])
|
131
|
-
U_b = U1.add_controls([ctrl])
|
132
|
-
|
133
|
-
#bulding the circuit for the overlap evaluation
|
133
|
+
|
134
|
+
# print('Control qubit:',ctrl)
|
135
|
+
|
136
|
+
U_a = U0.add_controls([ctrl]) # this add the control by modifying the previous circuit
|
137
|
+
U_b = U1.add_controls([ctrl]) # NonType object
|
138
|
+
|
139
|
+
# bulding the circuit for the overlap evaluation
|
134
140
|
circuit = H(target=ctrl)
|
135
141
|
circuit += X(target=ctrl)
|
136
142
|
circuit += U_a
|
137
143
|
circuit += X(target=ctrl)
|
138
144
|
circuit += U_b
|
139
|
-
|
145
|
+
|
140
146
|
x = paulis.X(ctrl)
|
141
147
|
y = paulis.Y(ctrl)
|
142
148
|
Ex = ExpectationValue(H=x, U=circuit, *args, **kwargs)
|
143
149
|
Ey = ExpectationValue(H=y, U=circuit, *args, **kwargs)
|
144
|
-
|
150
|
+
|
145
151
|
return Ex, Ey
|
146
152
|
|
147
153
|
|
148
|
-
def make_transition(
|
149
|
-
|
154
|
+
def make_transition(
|
155
|
+
U0: QCircuit = None, U1: QCircuit = None, H: QubitHamiltonian = None, *args, **kwargs
|
156
|
+
) -> ExpectationValue:
|
157
|
+
"""
|
150
158
|
Function that calculates the transition elements of an Hamiltonian operator
|
151
159
|
between two different quantum states.
|
152
160
|
|
153
161
|
Parameters
|
154
162
|
----------
|
155
163
|
U0 : QCircuit tequila object, corresponding to the first state (will be the bra).
|
156
|
-
|
164
|
+
|
157
165
|
U1 : QCircuit tequila object, corresponding to the second state (will be the ket).
|
158
|
-
|
166
|
+
|
159
167
|
H : QubitHamiltonian tequila object
|
160
|
-
|
168
|
+
|
161
169
|
Returns
|
162
170
|
-------
|
163
171
|
Real and imaginary Tequila objectives to be simulated or compiled.
|
164
172
|
|
165
|
-
|
166
|
-
|
173
|
+
"""
|
174
|
+
|
167
175
|
# want to measure: <U1|H|U0> -> \sum_k c_k <U1|U_k|U0>
|
168
|
-
|
176
|
+
|
169
177
|
trans_real = 0
|
170
178
|
trans_im = 0
|
171
|
-
|
179
|
+
|
172
180
|
for ps in H.paulistrings:
|
173
|
-
#print('string',ps)
|
181
|
+
# print('string',ps)
|
174
182
|
c_k = ps.coeff
|
175
|
-
#print('coeff', c_k)
|
183
|
+
# print('coeff', c_k)
|
176
184
|
U_k = PauliGate(ps)
|
177
|
-
objective_real, objective_im = make_overlap(U0=U0, U1=U1+U_k, *args, **kwargs)
|
178
|
-
|
179
|
-
trans_real += c_k*objective_real
|
180
|
-
trans_im += c_k*objective_im
|
185
|
+
objective_real, objective_im = make_overlap(U0=U0, U1=U1 + U_k, *args, **kwargs)
|
186
|
+
|
187
|
+
trans_real += c_k * objective_real
|
188
|
+
trans_im += c_k * objective_im
|
189
|
+
|
190
|
+
# print('contribution', trans_real+trans_im)
|
181
191
|
|
182
|
-
#print('contribution', trans_real+trans_im)
|
183
|
-
|
184
192
|
return trans_real, trans_im
|
tequila/objective/objective.py
CHANGED
@@ -1,4 +1,6 @@
|
|
1
|
-
import typing
|
1
|
+
import typing
|
2
|
+
import copy
|
3
|
+
import numbers
|
2
4
|
from typing import Union
|
3
5
|
from tequila.grouping.compile_groups import compile_commuting_parts
|
4
6
|
from tequila import TequilaException
|
@@ -11,6 +13,7 @@ import collections
|
|
11
13
|
|
12
14
|
# convenience
|
13
15
|
|
16
|
+
|
14
17
|
class ExpectationValueImpl:
|
15
18
|
"""
|
16
19
|
Implements the (uncompiled) Expectation Value as a class. Should not be called directly.
|
@@ -114,9 +117,12 @@ class ExpectationValueImpl:
|
|
114
117
|
the ExpectationValueImpl structure with mapped qubits
|
115
118
|
|
116
119
|
"""
|
117
|
-
return ExpectationValueImpl(
|
118
|
-
|
119
|
-
|
120
|
+
return ExpectationValueImpl(
|
121
|
+
H=tuple([H.map_qubits(qubit_map=qubit_map) for H in self.H]),
|
122
|
+
U=self.U.map_qubits(qubit_map=qubit_map),
|
123
|
+
contraction=self._contraction,
|
124
|
+
shape=self._shape,
|
125
|
+
)
|
120
126
|
|
121
127
|
def map_variables(self, variables: dict, *args, **kwargs):
|
122
128
|
"""
|
@@ -130,17 +136,25 @@ class ExpectationValueImpl:
|
|
130
136
|
Circuit with changed variables
|
131
137
|
|
132
138
|
"""
|
133
|
-
return ExpectationValueImpl(
|
134
|
-
|
139
|
+
return ExpectationValueImpl(
|
140
|
+
H=self.H,
|
141
|
+
U=self.U.map_variables(variables=variables, *args, **kwargs),
|
142
|
+
contraction=self._contraction,
|
143
|
+
shape=self._shape,
|
144
|
+
)
|
135
145
|
|
136
146
|
def __call__(self, *args, **kwargs):
|
137
147
|
raise TequilaException(
|
138
|
-
"Tried to call uncompiled ExpectationValueImpl, compile your objective before calling with tq.compile(objective) or evaluate with tq.simulate(objective)"
|
148
|
+
"Tried to call uncompiled ExpectationValueImpl, compile your objective before calling with tq.compile(objective) or evaluate with tq.simulate(objective)"
|
149
|
+
)
|
139
150
|
|
140
151
|
def info(self, short=True, *args, **kwargs):
|
141
152
|
if short:
|
142
|
-
print(
|
143
|
-
qubits
|
153
|
+
print(
|
154
|
+
"Expectation Value with {qubits} active qubits and {paulis} paulistrings".format(
|
155
|
+
qubits=len(self.U.qubits), paulis=len(self.H)
|
156
|
+
)
|
157
|
+
)
|
144
158
|
else:
|
145
159
|
print("Hamiltonian:\n", str(self.H))
|
146
160
|
print("\n", str(self.U))
|
@@ -257,7 +271,7 @@ class Objective:
|
|
257
271
|
"""
|
258
272
|
variables = []
|
259
273
|
for arg in self.args:
|
260
|
-
if hasattr(arg,
|
274
|
+
if hasattr(arg, "extract_variables"):
|
261
275
|
variables += arg.extract_variables()
|
262
276
|
else:
|
263
277
|
variables += []
|
@@ -304,7 +318,6 @@ class Objective:
|
|
304
318
|
|
305
319
|
@property
|
306
320
|
def args(self) -> typing.Tuple:
|
307
|
-
|
308
321
|
if self._args is None:
|
309
322
|
return tuple()
|
310
323
|
else:
|
@@ -397,7 +410,7 @@ class Objective:
|
|
397
410
|
|
398
411
|
def __invert__(self):
|
399
412
|
new = Objective(args=[self])
|
400
|
-
return new
|
413
|
+
return new**-1
|
401
414
|
|
402
415
|
@classmethod
|
403
416
|
def unary_operator(cls, left, op):
|
@@ -418,8 +431,7 @@ class Objective:
|
|
418
431
|
Objective representing op applied to objective left.
|
419
432
|
|
420
433
|
"""
|
421
|
-
return Objective(args=left.args,
|
422
|
-
transformation=lambda *args: op(left.transformation(*args)))
|
434
|
+
return Objective(args=left.args, transformation=lambda *args: op(left.transformation(*args)))
|
423
435
|
|
424
436
|
@classmethod
|
425
437
|
def binary_operator(cls, left, right, op):
|
@@ -451,18 +463,23 @@ class Objective:
|
|
451
463
|
return cls.unary_operator(left=left, op=lambda E: op(E, right))
|
452
464
|
else:
|
453
465
|
raise TequilaException(
|
454
|
-
|
466
|
+
"BinaryOperator method called on types " + str(type(left)) + "," + str(type(right))
|
467
|
+
)
|
455
468
|
elif isinstance(left, numbers.Number):
|
456
469
|
if isinstance(right, Objective):
|
457
470
|
return cls.unary_operator(left=right, op=lambda E: op(left, E))
|
458
471
|
else:
|
459
472
|
raise TequilaException(
|
460
|
-
|
473
|
+
"BinaryOperator method called on types " + str(type(left)) + "," + str(type(right))
|
474
|
+
)
|
461
475
|
else:
|
462
476
|
split_at = len(left.args)
|
463
|
-
return Objective(
|
464
|
-
|
465
|
-
|
477
|
+
return Objective(
|
478
|
+
args=left.args + right.args,
|
479
|
+
transformation=JoinedTransformation(
|
480
|
+
left=left.transformation, right=right.transformation, split=split_at, op=op
|
481
|
+
),
|
482
|
+
)
|
466
483
|
|
467
484
|
def wrap(self, op):
|
468
485
|
"""
|
@@ -541,12 +558,14 @@ class Objective:
|
|
541
558
|
|
542
559
|
unique = self.count_expectationvalues(unique=True)
|
543
560
|
measurements = self.count_measurements()
|
544
|
-
return
|
545
|
-
|
546
|
-
|
547
|
-
|
548
|
-
|
549
|
-
|
561
|
+
return (
|
562
|
+
"Objective with {} unique expectation values\n"
|
563
|
+
"total measurements = {}\n"
|
564
|
+
"variables = {}\n"
|
565
|
+
"types = {}".format(unique, measurements, variables, types)
|
566
|
+
)
|
567
|
+
|
568
|
+
def __call__(self, variables=None, initial_state=0, *args, **kwargs):
|
550
569
|
"""
|
551
570
|
Return the output of the calculation the objective represents.
|
552
571
|
|
@@ -568,14 +587,15 @@ class Objective:
|
|
568
587
|
# failsafe
|
569
588
|
check_variables = {k: k in variables for k in self.extract_variables()}
|
570
589
|
if not all(list(check_variables.values())):
|
571
|
-
raise TequilaException(
|
572
|
-
|
573
|
-
|
574
|
-
|
575
|
-
|
576
|
-
|
577
|
-
|
578
|
-
|
590
|
+
raise TequilaException(
|
591
|
+
"Objective did not receive all variables:\n"
|
592
|
+
"You gave\n"
|
593
|
+
" {}\n"
|
594
|
+
" but the objective depends on\n"
|
595
|
+
" {}\n"
|
596
|
+
" missing values for\n"
|
597
|
+
" {}".format(variables, self.extract_variables(), [k for k, v in check_variables.items() if not v])
|
598
|
+
)
|
579
599
|
|
580
600
|
# avoid multiple evaluations
|
581
601
|
evaluated = {}
|
@@ -588,7 +608,7 @@ class Objective:
|
|
588
608
|
expval_result = evaluated[E]
|
589
609
|
try:
|
590
610
|
expval_result = float(expval_result)
|
591
|
-
except:
|
611
|
+
except Exception:
|
592
612
|
pass # allow array evaluation (non-standard operation)
|
593
613
|
ev_array.append(expval_result)
|
594
614
|
result = onp.asarray(self.transformation(*ev_array), dtype=float)
|
@@ -598,7 +618,7 @@ class Objective:
|
|
598
618
|
return float(result[0])
|
599
619
|
else:
|
600
620
|
return result
|
601
|
-
|
621
|
+
|
602
622
|
def contract(self):
|
603
623
|
"""
|
604
624
|
Exists only to be convient in optimizers, which all contract over VectrObjectives.
|
@@ -611,19 +631,20 @@ class Objective:
|
|
611
631
|
|
612
632
|
def __len__(self):
|
613
633
|
return 1
|
614
|
-
|
634
|
+
|
615
635
|
def is_translated(self):
|
616
636
|
"""
|
617
637
|
check if the objective was already translated to a quantum backend
|
618
638
|
"""
|
619
639
|
types = [type(E) for E in self.get_expectationvalues()]
|
620
640
|
types = list(set(types))
|
621
|
-
if len(types)==0 or (ExpectationValueImpl in types and len(types)==1):
|
641
|
+
if len(types) == 0 or (ExpectationValueImpl in types and len(types) == 1):
|
622
642
|
return False
|
623
643
|
else:
|
624
644
|
return True
|
625
645
|
|
626
|
-
|
646
|
+
|
647
|
+
def ExpectationValue(U, H, optimize_measurements=False, *args, **kwargs) -> Objective:
|
627
648
|
"""
|
628
649
|
Initialize an Objective which is just a single expectationvalue
|
629
650
|
"""
|
@@ -761,8 +782,10 @@ class Variable:
|
|
761
782
|
new = Objective(args=[self, other], transformation=op)
|
762
783
|
else:
|
763
784
|
raise TequilaException(
|
764
|
-
"unknown type in left_helper of objective arithmetics with operation {}: {}".format(
|
765
|
-
|
785
|
+
"unknown type in left_helper of objective arithmetics with operation {}: {}".format(
|
786
|
+
type(op), type(other)
|
787
|
+
)
|
788
|
+
)
|
766
789
|
return new
|
767
790
|
|
768
791
|
def _right_helper(self, op, other):
|
@@ -782,8 +805,10 @@ class Variable:
|
|
782
805
|
new = Objective(args=[other, self], transformation=op)
|
783
806
|
else:
|
784
807
|
raise TequilaException(
|
785
|
-
"unknown type in left_helper of objective arithmetics with operation {}: {}".format(
|
786
|
-
|
808
|
+
"unknown type in left_helper of objective arithmetics with operation {}: {}".format(
|
809
|
+
type(op), type(other)
|
810
|
+
)
|
811
|
+
)
|
787
812
|
return new
|
788
813
|
|
789
814
|
def __mul__(self, other):
|
@@ -799,7 +824,7 @@ class Variable:
|
|
799
824
|
return self._left_helper(numpy.true_divide, other)
|
800
825
|
|
801
826
|
def __neg__(self):
|
802
|
-
return Objective(args=[self], transformation=lambda v: numpy.multiply(v, -1.))
|
827
|
+
return Objective(args=[self], transformation=lambda v: numpy.multiply(v, -1.0))
|
803
828
|
|
804
829
|
def __pow__(self, other):
|
805
830
|
return self._left_helper(numpy.power, other)
|
@@ -818,7 +843,7 @@ class Variable:
|
|
818
843
|
|
819
844
|
def __invert__(self):
|
820
845
|
new = Objective(args=[self])
|
821
|
-
return new
|
846
|
+
return new**-1.0
|
822
847
|
|
823
848
|
def __len__(self):
|
824
849
|
return 1
|
@@ -830,7 +855,7 @@ class Variable:
|
|
830
855
|
return True
|
831
856
|
|
832
857
|
def apply(self, other):
|
833
|
-
assert
|
858
|
+
assert callable(other)
|
834
859
|
return Objective(args=[self], transformation=other)
|
835
860
|
|
836
861
|
def wrap(self, other):
|
@@ -841,6 +866,7 @@ class Variable:
|
|
841
866
|
|
842
867
|
def toJson(self):
|
843
868
|
import json
|
869
|
+
|
844
870
|
return json.dumps(self, default=lambda o: o.__dict__)
|
845
871
|
|
846
872
|
|
@@ -860,15 +886,16 @@ class FixedVariable(float):
|
|
860
886
|
return self
|
861
887
|
|
862
888
|
def apply(self, other):
|
863
|
-
assert
|
889
|
+
assert callable(other)
|
864
890
|
return Objective(args=[self], transformation=other)
|
865
891
|
|
866
892
|
def wrap(self, other):
|
867
893
|
return self.apply(other)
|
868
|
-
|
894
|
+
|
869
895
|
def map_variables(self, *args, **kwargs):
|
870
896
|
return self
|
871
897
|
|
898
|
+
|
872
899
|
def format_variable_list(variables: typing.List[typing.Hashable]) -> typing.List[Variable]:
|
873
900
|
"""
|
874
901
|
Convenience functions to assign tequila variables.
|
@@ -888,8 +915,9 @@ def format_variable_list(variables: typing.List[typing.Hashable]) -> typing.List
|
|
888
915
|
return [assign_variable(k) for k in variables]
|
889
916
|
|
890
917
|
|
891
|
-
def format_variable_dictionary(
|
892
|
-
|
918
|
+
def format_variable_dictionary(
|
919
|
+
variables: typing.Dict[typing.Hashable, typing.Any],
|
920
|
+
) -> typing.Dict[Variable, typing.Any]:
|
893
921
|
"""
|
894
922
|
Convenience function to assign tequila variables.
|
895
923
|
Parameters
|
@@ -908,8 +936,9 @@ def format_variable_dictionary(variables: typing.Dict[typing.Hashable, typing.An
|
|
908
936
|
return Variables(variables)
|
909
937
|
|
910
938
|
|
911
|
-
def assign_variable(
|
912
|
-
Variable, FixedVariable]
|
939
|
+
def assign_variable(
|
940
|
+
variable: typing.Union[typing.Hashable, numbers.Real, Variable, FixedVariable],
|
941
|
+
) -> typing.Union[Variable, FixedVariable]:
|
913
942
|
"""
|
914
943
|
Convenience function; maps various objects into Variable, FixedVariable, or Variables, for easy duck-typing.
|
915
944
|
|
@@ -920,7 +949,7 @@ def assign_variable(variable: typing.Union[typing.Hashable, numbers.Real, Variab
|
|
920
949
|
|
921
950
|
Raises
|
922
951
|
------
|
923
|
-
|
952
|
+
|
924
953
|
TequilaVariableException
|
925
954
|
|
926
955
|
|
@@ -945,8 +974,11 @@ def assign_variable(variable: typing.Union[typing.Hashable, numbers.Real, Variab
|
|
945
974
|
return Variable(name=variable)
|
946
975
|
else:
|
947
976
|
raise TequilaVariableException(
|
948
|
-
"Only hashable types can be assigned to Variables. You passed down "
|
949
|
-
|
977
|
+
"Only hashable types can be assigned to Variables. You passed down "
|
978
|
+
+ str(variable)
|
979
|
+
+ " type="
|
980
|
+
+ str(type(variable))
|
981
|
+
)
|
950
982
|
|
951
983
|
|
952
984
|
class Variables(collections.abc.MutableMapping):
|
@@ -988,5 +1020,5 @@ class Variables(collections.abc.MutableMapping):
|
|
988
1020
|
return result
|
989
1021
|
|
990
1022
|
def __repr__(self):
|
991
|
-
xdict = {k:v for k,v in self.items()}
|
1023
|
+
xdict = {k: v for k, v in self.items()}
|
992
1024
|
return xdict.__repr__()
|