qadence 1.7.8__py3-none-any.whl → 1.9.0__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.
- qadence/__init__.py +1 -1
- qadence/analog/device.py +1 -1
- qadence/analog/parse_analog.py +1 -2
- qadence/backend.py +3 -3
- qadence/backends/gpsr.py +8 -2
- qadence/backends/horqrux/backend.py +3 -3
- qadence/backends/pulser/backend.py +21 -38
- qadence/backends/pulser/convert_ops.py +2 -2
- qadence/backends/pyqtorch/backend.py +85 -10
- qadence/backends/pyqtorch/config.py +10 -3
- qadence/backends/pyqtorch/convert_ops.py +245 -233
- qadence/backends/utils.py +9 -1
- qadence/blocks/abstract.py +1 -1
- qadence/blocks/embedding.py +21 -11
- qadence/blocks/matrix.py +3 -1
- qadence/blocks/primitive.py +37 -11
- qadence/circuit.py +1 -1
- qadence/constructors/__init__.py +2 -1
- qadence/constructors/ansatze.py +176 -0
- qadence/engines/differentiable_backend.py +3 -3
- qadence/engines/jax/differentiable_backend.py +2 -2
- qadence/engines/jax/differentiable_expectation.py +2 -2
- qadence/engines/torch/differentiable_backend.py +2 -2
- qadence/engines/torch/differentiable_expectation.py +2 -2
- qadence/execution.py +14 -16
- qadence/extensions.py +1 -1
- qadence/log_config.yaml +10 -0
- qadence/measurements/shadow.py +101 -133
- qadence/measurements/tomography.py +2 -2
- qadence/measurements/utils.py +4 -4
- qadence/mitigations/analog_zne.py +8 -7
- qadence/mitigations/protocols.py +2 -2
- qadence/mitigations/readout.py +14 -5
- qadence/ml_tools/__init__.py +4 -8
- qadence/ml_tools/callbacks/__init__.py +30 -0
- qadence/ml_tools/callbacks/callback.py +451 -0
- qadence/ml_tools/callbacks/callbackmanager.py +214 -0
- qadence/ml_tools/{saveload.py → callbacks/saveload.py} +11 -11
- qadence/ml_tools/callbacks/writer_registry.py +430 -0
- qadence/ml_tools/config.py +132 -258
- qadence/ml_tools/constructors.py +2 -2
- qadence/ml_tools/data.py +7 -3
- qadence/ml_tools/loss/__init__.py +10 -0
- qadence/ml_tools/loss/loss.py +87 -0
- qadence/ml_tools/models.py +7 -7
- qadence/ml_tools/optimize_step.py +45 -10
- qadence/ml_tools/stages.py +46 -0
- qadence/ml_tools/train_utils/__init__.py +7 -0
- qadence/ml_tools/train_utils/base_trainer.py +548 -0
- qadence/ml_tools/train_utils/config_manager.py +184 -0
- qadence/ml_tools/trainer.py +692 -0
- qadence/model.py +6 -6
- qadence/noise/__init__.py +2 -2
- qadence/noise/protocols.py +188 -36
- qadence/operations/control_ops.py +37 -22
- qadence/operations/ham_evo.py +88 -26
- qadence/operations/parametric.py +32 -10
- qadence/operations/primitive.py +61 -29
- qadence/overlap.py +0 -6
- qadence/parameters.py +3 -2
- qadence/transpile/__init__.py +2 -1
- qadence/transpile/noise.py +53 -0
- qadence/types.py +39 -3
- {qadence-1.7.8.dist-info → qadence-1.9.0.dist-info}/METADATA +5 -9
- {qadence-1.7.8.dist-info → qadence-1.9.0.dist-info}/RECORD +67 -63
- {qadence-1.7.8.dist-info → qadence-1.9.0.dist-info}/WHEEL +1 -1
- qadence/backends/braket/__init__.py +0 -4
- qadence/backends/braket/backend.py +0 -234
- qadence/backends/braket/config.py +0 -22
- qadence/backends/braket/convert_ops.py +0 -116
- qadence/ml_tools/printing.py +0 -153
- qadence/ml_tools/train_grad.py +0 -395
- qadence/ml_tools/train_no_grad.py +0 -199
- qadence/noise/readout.py +0 -218
- {qadence-1.7.8.dist-info → qadence-1.9.0.dist-info}/licenses/LICENSE +0 -0
qadence/operations/parametric.py
CHANGED
@@ -15,6 +15,7 @@ from qadence.blocks.utils import (
|
|
15
15
|
add, # noqa
|
16
16
|
chain,
|
17
17
|
)
|
18
|
+
from qadence.noise import NoiseHandler
|
18
19
|
from qadence.parameters import (
|
19
20
|
Parameter,
|
20
21
|
ParamMap,
|
@@ -32,10 +33,15 @@ class PHASE(ParametricBlock):
|
|
32
33
|
|
33
34
|
name = OpName.PHASE
|
34
35
|
|
35
|
-
def __init__(
|
36
|
+
def __init__(
|
37
|
+
self,
|
38
|
+
target: int,
|
39
|
+
parameter: Parameter | TNumber | sympy.Expr | str,
|
40
|
+
noise: NoiseHandler | None = None,
|
41
|
+
) -> None:
|
36
42
|
self.parameters = ParamMap(parameter=parameter)
|
37
43
|
self.generator = I(target) - Z(target)
|
38
|
-
super().__init__((target,))
|
44
|
+
super().__init__((target,), noise=noise)
|
39
45
|
|
40
46
|
@classmethod
|
41
47
|
def num_parameters(cls) -> int:
|
@@ -56,13 +62,18 @@ class RX(ParametricBlock):
|
|
56
62
|
|
57
63
|
name = OpName.RX
|
58
64
|
|
59
|
-
def __init__(
|
65
|
+
def __init__(
|
66
|
+
self,
|
67
|
+
target: int,
|
68
|
+
parameter: Parameter | TParameter | ParamMap,
|
69
|
+
noise: NoiseHandler | None = None,
|
70
|
+
) -> None:
|
60
71
|
# TODO: should we give them more meaningful names? like 'angle'?
|
61
72
|
self.parameters = (
|
62
73
|
parameter if isinstance(parameter, ParamMap) else ParamMap(parameter=parameter)
|
63
74
|
)
|
64
75
|
self.generator = X(target)
|
65
|
-
super().__init__((target,))
|
76
|
+
super().__init__((target,), noise=noise)
|
66
77
|
|
67
78
|
@classmethod
|
68
79
|
def num_parameters(cls) -> int:
|
@@ -84,12 +95,17 @@ class RY(ParametricBlock):
|
|
84
95
|
|
85
96
|
name = OpName.RY
|
86
97
|
|
87
|
-
def __init__(
|
98
|
+
def __init__(
|
99
|
+
self,
|
100
|
+
target: int,
|
101
|
+
parameter: Parameter | TParameter | ParamMap,
|
102
|
+
noise: NoiseHandler | None = None,
|
103
|
+
) -> None:
|
88
104
|
self.parameters = (
|
89
105
|
parameter if isinstance(parameter, ParamMap) else ParamMap(parameter=parameter)
|
90
106
|
)
|
91
107
|
self.generator = Y(target)
|
92
|
-
super().__init__((target,))
|
108
|
+
super().__init__((target,), noise=noise)
|
93
109
|
|
94
110
|
@classmethod
|
95
111
|
def num_parameters(cls) -> int:
|
@@ -111,12 +127,17 @@ class RZ(ParametricBlock):
|
|
111
127
|
|
112
128
|
name = OpName.RZ
|
113
129
|
|
114
|
-
def __init__(
|
130
|
+
def __init__(
|
131
|
+
self,
|
132
|
+
target: int,
|
133
|
+
parameter: Parameter | TParameter | ParamMap,
|
134
|
+
noise: NoiseHandler | None = None,
|
135
|
+
) -> None:
|
115
136
|
self.parameters = (
|
116
137
|
parameter if isinstance(parameter, ParamMap) else ParamMap(parameter=parameter)
|
117
138
|
)
|
118
139
|
self.generator = Z(target)
|
119
|
-
super().__init__((target,))
|
140
|
+
super().__init__((target,), noise=noise)
|
120
141
|
|
121
142
|
@classmethod
|
122
143
|
def num_parameters(cls) -> int:
|
@@ -147,10 +168,11 @@ class U(ParametricBlock):
|
|
147
168
|
phi: Parameter | TParameter,
|
148
169
|
theta: Parameter | TParameter,
|
149
170
|
omega: Parameter | TParameter,
|
150
|
-
|
171
|
+
noise: NoiseHandler | None = None,
|
172
|
+
) -> None:
|
151
173
|
self.parameters = ParamMap(phi=phi, theta=theta, omega=omega)
|
152
174
|
self.generator = chain(Z(target), Y(target), Z(target))
|
153
|
-
super().__init__((target,))
|
175
|
+
super().__init__((target,), noise=noise)
|
154
176
|
|
155
177
|
@classmethod
|
156
178
|
def num_parameters(cls) -> int:
|
qadence/operations/primitive.py
CHANGED
@@ -18,6 +18,7 @@ from qadence.blocks.utils import (
|
|
18
18
|
chain,
|
19
19
|
kron,
|
20
20
|
)
|
21
|
+
from qadence.noise import NoiseHandler
|
21
22
|
from qadence.parameters import (
|
22
23
|
Parameter,
|
23
24
|
)
|
@@ -31,8 +32,8 @@ class X(PrimitiveBlock):
|
|
31
32
|
|
32
33
|
name = OpName.X
|
33
34
|
|
34
|
-
def __init__(self, target: int):
|
35
|
-
super().__init__((target,))
|
35
|
+
def __init__(self, target: int, noise: NoiseHandler | None = None) -> None:
|
36
|
+
super().__init__((target,), noise=noise)
|
36
37
|
|
37
38
|
@property
|
38
39
|
def generator(self) -> AbstractBlock:
|
@@ -52,8 +53,8 @@ class Y(PrimitiveBlock):
|
|
52
53
|
|
53
54
|
name = OpName.Y
|
54
55
|
|
55
|
-
def __init__(self, target: int):
|
56
|
-
super().__init__((target,))
|
56
|
+
def __init__(self, target: int, noise: NoiseHandler | None = None) -> None:
|
57
|
+
super().__init__((target,), noise=noise)
|
57
58
|
|
58
59
|
@property
|
59
60
|
def generator(self) -> AbstractBlock:
|
@@ -73,8 +74,8 @@ class Z(PrimitiveBlock):
|
|
73
74
|
|
74
75
|
name = OpName.Z
|
75
76
|
|
76
|
-
def __init__(self, target: int):
|
77
|
-
super().__init__((target,))
|
77
|
+
def __init__(self, target: int, noise: NoiseHandler | None = None) -> None:
|
78
|
+
super().__init__((target,), noise=noise)
|
78
79
|
|
79
80
|
@property
|
80
81
|
def generator(self) -> AbstractBlock:
|
@@ -94,8 +95,8 @@ class I(PrimitiveBlock):
|
|
94
95
|
|
95
96
|
name = OpName.I
|
96
97
|
|
97
|
-
def __init__(self, target: int):
|
98
|
-
super().__init__((target,))
|
98
|
+
def __init__(self, target: int, noise: NoiseHandler | None = None) -> None:
|
99
|
+
super().__init__((target,), noise=noise)
|
99
100
|
|
100
101
|
def __ixor__(self, other: AbstractBlock | int) -> AbstractBlock:
|
101
102
|
if not isinstance(other, AbstractBlock):
|
@@ -113,7 +114,7 @@ class I(PrimitiveBlock):
|
|
113
114
|
|
114
115
|
@property
|
115
116
|
def generator(self) -> AbstractBlock:
|
116
|
-
return I(
|
117
|
+
return I(self.qubit_support[0])
|
117
118
|
|
118
119
|
@property
|
119
120
|
def eigenvalues_generator(self) -> Tensor:
|
@@ -137,8 +138,9 @@ class Projector(ProjectorBlock):
|
|
137
138
|
ket: str,
|
138
139
|
bra: str,
|
139
140
|
qubit_support: int | tuple[int, ...],
|
140
|
-
|
141
|
-
|
141
|
+
noise: NoiseHandler | None = None,
|
142
|
+
) -> None:
|
143
|
+
super().__init__(ket=ket, bra=bra, qubit_support=qubit_support, noise=noise)
|
142
144
|
|
143
145
|
@property
|
144
146
|
def generator(self) -> None:
|
@@ -154,8 +156,13 @@ class N(Projector):
|
|
154
156
|
|
155
157
|
name = OpName.N
|
156
158
|
|
157
|
-
def __init__(
|
158
|
-
|
159
|
+
def __init__(
|
160
|
+
self,
|
161
|
+
target: int,
|
162
|
+
state: str = "1",
|
163
|
+
noise: NoiseHandler | None = None,
|
164
|
+
) -> None:
|
165
|
+
super().__init__(ket=state, bra=state, qubit_support=(target,), noise=noise)
|
159
166
|
|
160
167
|
@property
|
161
168
|
def generator(self) -> None:
|
@@ -175,9 +182,13 @@ class S(PrimitiveBlock):
|
|
175
182
|
|
176
183
|
name = OpName.S
|
177
184
|
|
178
|
-
def __init__(
|
185
|
+
def __init__(
|
186
|
+
self,
|
187
|
+
target: int,
|
188
|
+
noise: NoiseHandler | None = None,
|
189
|
+
) -> None:
|
179
190
|
self.generator = I(target) - Z(target)
|
180
|
-
super().__init__((target,))
|
191
|
+
super().__init__((target,), noise=noise)
|
181
192
|
|
182
193
|
@property
|
183
194
|
def eigenvalues_generator(self) -> Tensor:
|
@@ -188,7 +199,7 @@ class S(PrimitiveBlock):
|
|
188
199
|
return tensor([1, 1j], dtype=cdouble)
|
189
200
|
|
190
201
|
def dagger(self) -> SDagger:
|
191
|
-
return SDagger(
|
202
|
+
return SDagger(self.qubit_support[0])
|
192
203
|
|
193
204
|
|
194
205
|
class SDagger(PrimitiveBlock):
|
@@ -196,9 +207,13 @@ class SDagger(PrimitiveBlock):
|
|
196
207
|
|
197
208
|
name = OpName.SDAGGER
|
198
209
|
|
199
|
-
def __init__(
|
210
|
+
def __init__(
|
211
|
+
self,
|
212
|
+
target: int,
|
213
|
+
noise: NoiseHandler | None = None,
|
214
|
+
) -> None:
|
200
215
|
self.generator = I(target) - Z(target)
|
201
|
-
super().__init__((target,))
|
216
|
+
super().__init__((target,), noise=noise)
|
202
217
|
|
203
218
|
@property
|
204
219
|
def eigenvalues_generator(self) -> Tensor:
|
@@ -209,7 +224,7 @@ class SDagger(PrimitiveBlock):
|
|
209
224
|
return tensor([1, -1j], dtype=cdouble)
|
210
225
|
|
211
226
|
def dagger(self) -> S:
|
212
|
-
return S(
|
227
|
+
return S(self.qubit_support[0])
|
213
228
|
|
214
229
|
|
215
230
|
class H(PrimitiveBlock):
|
@@ -217,9 +232,13 @@ class H(PrimitiveBlock):
|
|
217
232
|
|
218
233
|
name = OpName.H
|
219
234
|
|
220
|
-
def __init__(
|
235
|
+
def __init__(
|
236
|
+
self,
|
237
|
+
target: int,
|
238
|
+
noise: NoiseHandler | None = None,
|
239
|
+
) -> None:
|
221
240
|
self.generator = (1 / np.sqrt(2)) * (X(target) + Z(target) - np.sqrt(2) * I(target))
|
222
|
-
super().__init__((target,))
|
241
|
+
super().__init__((target,), noise=noise)
|
223
242
|
|
224
243
|
@property
|
225
244
|
def eigenvalues_generator(self) -> Tensor:
|
@@ -275,9 +294,13 @@ class T(PrimitiveBlock):
|
|
275
294
|
|
276
295
|
name = OpName.T
|
277
296
|
|
278
|
-
def __init__(
|
297
|
+
def __init__(
|
298
|
+
self,
|
299
|
+
target: int,
|
300
|
+
noise: NoiseHandler | None = None,
|
301
|
+
) -> None:
|
279
302
|
self.generator = I(target) - Z(target)
|
280
|
-
super().__init__((target,))
|
303
|
+
super().__init__((target,), noise)
|
281
304
|
|
282
305
|
@property
|
283
306
|
def eigenvalues_generator(self) -> Tensor:
|
@@ -292,7 +315,7 @@ class T(PrimitiveBlock):
|
|
292
315
|
return 1
|
293
316
|
|
294
317
|
def dagger(self) -> TDagger:
|
295
|
-
return TDagger(
|
318
|
+
return TDagger(self.qubit_support[0])
|
296
319
|
|
297
320
|
|
298
321
|
class TDagger(PrimitiveBlock):
|
@@ -301,9 +324,13 @@ class TDagger(PrimitiveBlock):
|
|
301
324
|
# FIXME: this gate is not support by any backend
|
302
325
|
name = "T_dagger"
|
303
326
|
|
304
|
-
def __init__(
|
327
|
+
def __init__(
|
328
|
+
self,
|
329
|
+
target: int,
|
330
|
+
noise: NoiseHandler | None = None,
|
331
|
+
) -> None:
|
305
332
|
self.generator = I(target) - Z(target)
|
306
|
-
super().__init__((target,))
|
333
|
+
super().__init__((target,), noise)
|
307
334
|
|
308
335
|
@property
|
309
336
|
def eigenvalues_generator(self) -> Tensor:
|
@@ -318,7 +345,7 @@ class TDagger(PrimitiveBlock):
|
|
318
345
|
return 1
|
319
346
|
|
320
347
|
def dagger(self) -> T:
|
321
|
-
return T(
|
348
|
+
return T(self.qubit_support[0])
|
322
349
|
|
323
350
|
|
324
351
|
class SWAP(PrimitiveBlock):
|
@@ -326,7 +353,12 @@ class SWAP(PrimitiveBlock):
|
|
326
353
|
|
327
354
|
name = OpName.SWAP
|
328
355
|
|
329
|
-
def __init__(
|
356
|
+
def __init__(
|
357
|
+
self,
|
358
|
+
control: int,
|
359
|
+
target: int,
|
360
|
+
noise: NoiseHandler | None = None,
|
361
|
+
) -> None:
|
330
362
|
a11 = 0.5 * (Z(control) - I(control))
|
331
363
|
a22 = -0.5 * (Z(target) + I(target))
|
332
364
|
a12 = 0.5 * (chain(X(control), Z(control)) + X(control))
|
@@ -334,7 +366,7 @@ class SWAP(PrimitiveBlock):
|
|
334
366
|
self.generator = (
|
335
367
|
kron(-1.0 * a22, a11) + kron(-1.0 * a11, a22) + kron(a12, a21) + kron(a21, a12)
|
336
368
|
)
|
337
|
-
super().__init__((control, target))
|
369
|
+
super().__init__((control, target), noise=noise)
|
338
370
|
|
339
371
|
@property
|
340
372
|
def eigenvalues_generator(self) -> Tensor:
|
qadence/overlap.py
CHANGED
@@ -102,9 +102,6 @@ def _select_overlap_method(
|
|
102
102
|
return overlap
|
103
103
|
|
104
104
|
elif method == OverlapMethod.SWAP_TEST:
|
105
|
-
if backend == BackendName.BRAKET:
|
106
|
-
raise ValueError("SWAP test method is not supported by the Braket backend.")
|
107
|
-
|
108
105
|
n_qubits = bra_circuit.n_qubits
|
109
106
|
|
110
107
|
# shift qubit support of bra and ket circuit blocks
|
@@ -128,9 +125,6 @@ def _select_overlap_method(
|
|
128
125
|
return overlap
|
129
126
|
|
130
127
|
elif method == OverlapMethod.HADAMARD_TEST:
|
131
|
-
if backend == BackendName.BRAKET:
|
132
|
-
raise ValueError("Hadamard test method is not supported by the Braket backend.")
|
133
|
-
|
134
128
|
n_qubits = bra_circuit.n_qubits
|
135
129
|
|
136
130
|
# construct controlled bra and ket blocks
|
qadence/parameters.py
CHANGED
@@ -228,7 +228,7 @@ def sympy_to_numeric(expr: Basic) -> TNumber:
|
|
228
228
|
return float(expr)
|
229
229
|
|
230
230
|
|
231
|
-
def evaluate(expr: Expr, values: dict =
|
231
|
+
def evaluate(expr: Expr, values: dict | None = None, as_torch: bool = False) -> TNumber | Tensor:
|
232
232
|
"""
|
233
233
|
Arguments:
|
234
234
|
|
@@ -260,7 +260,8 @@ def evaluate(expr: Expr, values: dict = {}, as_torch: bool = False) -> TNumber |
|
|
260
260
|
"""
|
261
261
|
res: Basic
|
262
262
|
res_value: TNumber | Tensor
|
263
|
-
query: dict[Parameter, TNumber | Tensor] =
|
263
|
+
query: dict[Parameter, TNumber | Tensor] = dict()
|
264
|
+
values = values or dict()
|
264
265
|
if isinstance(expr, Array):
|
265
266
|
return Tensor(expr.tolist())
|
266
267
|
else:
|
qadence/transpile/__init__.py
CHANGED
@@ -12,6 +12,7 @@ from .circuit import fill_identities
|
|
12
12
|
from .digitalize import digitalize
|
13
13
|
from .flatten import flatten
|
14
14
|
from .invert import invert_endianness, reassign
|
15
|
+
from .noise import set_noise
|
15
16
|
from .transpile import blockfn_to_circfn, transpile
|
16
17
|
|
17
|
-
__all__ = ["set_trainable", "invert_endianness"]
|
18
|
+
__all__ = ["set_trainable", "invert_endianness", "set_noise"]
|
@@ -0,0 +1,53 @@
|
|
1
|
+
from __future__ import annotations
|
2
|
+
|
3
|
+
from qadence.backend import ConvertedCircuit
|
4
|
+
from qadence.blocks.abstract import AbstractBlock
|
5
|
+
from qadence.circuit import QuantumCircuit
|
6
|
+
from qadence.noise.protocols import NoiseHandler
|
7
|
+
|
8
|
+
from .apply_fn import apply_fn_to_blocks
|
9
|
+
|
10
|
+
|
11
|
+
def _set_noise(
|
12
|
+
block: AbstractBlock,
|
13
|
+
noise: NoiseHandler | None,
|
14
|
+
target_class: type[AbstractBlock] | None = None,
|
15
|
+
) -> AbstractBlock:
|
16
|
+
"""Changes the noise protocol of a given block in place."""
|
17
|
+
if target_class is not None:
|
18
|
+
if isinstance(block, target_class):
|
19
|
+
block._noise = noise # type: ignore [attr-defined]
|
20
|
+
else:
|
21
|
+
block._noise = noise # type: ignore [attr-defined]
|
22
|
+
|
23
|
+
return block
|
24
|
+
|
25
|
+
|
26
|
+
def set_noise(
|
27
|
+
circuit: QuantumCircuit | AbstractBlock | ConvertedCircuit,
|
28
|
+
noise: NoiseHandler | None,
|
29
|
+
target_class: AbstractBlock | None = None,
|
30
|
+
) -> QuantumCircuit | AbstractBlock:
|
31
|
+
"""
|
32
|
+
Parses a `QuantumCircuit` or `CompositeBlock` to add noise to specific gates.
|
33
|
+
|
34
|
+
If `circuit` is a `ConvertedCircuit`, this is done within `circuit.abstract`.
|
35
|
+
|
36
|
+
Changes the input in place.
|
37
|
+
|
38
|
+
Arguments:
|
39
|
+
circuit: the circuit or block to parse.
|
40
|
+
noise: the NoiseHandler protocol to change to, or `None` to remove the noise.
|
41
|
+
target_class: optional class to selectively add noise to.
|
42
|
+
"""
|
43
|
+
input_block: AbstractBlock
|
44
|
+
if isinstance(circuit, ConvertedCircuit):
|
45
|
+
input_block = circuit.abstract.block
|
46
|
+
elif isinstance(circuit, QuantumCircuit):
|
47
|
+
input_block = circuit.block
|
48
|
+
else:
|
49
|
+
input_block = circuit
|
50
|
+
|
51
|
+
apply_fn_to_blocks(input_block, _set_noise, noise, target_class)
|
52
|
+
|
53
|
+
return circuit
|
qadence/types.py
CHANGED
@@ -1,6 +1,7 @@
|
|
1
1
|
from __future__ import annotations
|
2
2
|
|
3
3
|
import importlib
|
4
|
+
from dataclasses import dataclass
|
4
5
|
from enum import Enum
|
5
6
|
from typing import Callable, Iterable, Tuple, Union
|
6
7
|
|
@@ -8,7 +9,9 @@ import numpy as np
|
|
8
9
|
import sympy
|
9
10
|
from matplotlib.figure import Figure
|
10
11
|
from numpy.typing import ArrayLike
|
11
|
-
from pyqtorch.
|
12
|
+
from pyqtorch.noise import NoiseType as DigitalNoise
|
13
|
+
from pyqtorch.noise.readout import WhiteNoise
|
14
|
+
from pyqtorch.utils import DropoutMode, SolverType
|
12
15
|
from torch import Tensor, pi
|
13
16
|
from torch.nn import Module
|
14
17
|
|
@@ -26,6 +29,7 @@ TArray = Union[Iterable, Tensor, np.ndarray]
|
|
26
29
|
TGenerator = Union[Tensor, sympy.Array, sympy.Basic]
|
27
30
|
"""Union of torch tensors and numpy arrays."""
|
28
31
|
|
32
|
+
|
29
33
|
PI = pi
|
30
34
|
|
31
35
|
# Modules to be automatically added to the qadence namespace
|
@@ -51,6 +55,9 @@ __all__ = [
|
|
51
55
|
"SerializationFormat",
|
52
56
|
"PI",
|
53
57
|
"SolverType",
|
58
|
+
"DropoutMode",
|
59
|
+
"NoiseProtocol",
|
60
|
+
"WhiteNoise",
|
54
61
|
] # type: ignore
|
55
62
|
|
56
63
|
|
@@ -221,8 +228,6 @@ class _BackendName(StrEnum):
|
|
221
228
|
|
222
229
|
PYQTORCH = "pyqtorch"
|
223
230
|
"""The Pyqtorch backend."""
|
224
|
-
BRAKET = "braket"
|
225
|
-
"""The Braket backend."""
|
226
231
|
PULSER = "pulser"
|
227
232
|
"""The Pulser backend."""
|
228
233
|
HORQRUX = "horqrux"
|
@@ -457,3 +462,34 @@ class ExperimentTrackingTool(StrEnum):
|
|
457
462
|
|
458
463
|
|
459
464
|
LoggablePlotFunction = Callable[[Module, int], tuple[str, Figure]]
|
465
|
+
|
466
|
+
|
467
|
+
class AnalogNoise(StrEnum):
|
468
|
+
"""Type of noise protocol."""
|
469
|
+
|
470
|
+
DEPOLARIZING = "Depolarizing"
|
471
|
+
DEPHASING = "Dephasing"
|
472
|
+
|
473
|
+
|
474
|
+
class ReadoutNoise(StrEnum):
|
475
|
+
"""Type of readout protocol."""
|
476
|
+
|
477
|
+
INDEPENDENT = "Independent Readout"
|
478
|
+
"""Simple readout protocols where each qubit is corrupted independently."""
|
479
|
+
CORRELATED = "Correlated Readout"
|
480
|
+
"""Using a confusion matrix (2**n, 2**n) for corrupting bitstrings values."""
|
481
|
+
|
482
|
+
|
483
|
+
@dataclass
|
484
|
+
class NoiseProtocol:
|
485
|
+
"""Type of noise protocol."""
|
486
|
+
|
487
|
+
ANALOG = AnalogNoise
|
488
|
+
"""Noise applied in analog blocks."""
|
489
|
+
READOUT = ReadoutNoise
|
490
|
+
"""Noise applied on outputs of quantum programs."""
|
491
|
+
DIGITAL = DigitalNoise
|
492
|
+
"""Noise applied to digital blocks."""
|
493
|
+
|
494
|
+
|
495
|
+
NoiseEnum = Union[DigitalNoise, AnalogNoise, ReadoutNoise]
|
@@ -1,10 +1,9 @@
|
|
1
1
|
Metadata-Version: 2.3
|
2
2
|
Name: qadence
|
3
|
-
Version: 1.
|
3
|
+
Version: 1.9.0
|
4
4
|
Summary: Pasqal interface for circuit-based quantum computing SDKs
|
5
5
|
Author-email: Aleksander Wennersteen <aleksander.wennersteen@pasqal.com>, Gert-Jan Both <gert-jan.both@pasqal.com>, Niklas Heim <niklas.heim@pasqal.com>, Mario Dagrada <mario.dagrada@pasqal.com>, Vincent Elfving <vincent.elfving@pasqal.com>, Dominik Seitz <dominik.seitz@pasqal.com>, Roland Guichard <roland.guichard@pasqal.com>, "Joao P. Moutinho" <joao.moutinho@pasqal.com>, Vytautas Abramavicius <vytautas.abramavicius@pasqal.com>, Gergana Velikova <gergana.velikova@pasqal.com>, Eduardo Maschio <eduardo.maschio@pasqal.com>, Smit Chaudhary <smit.chaudhary@pasqal.com>, Ignacio Fernández Graña <ignacio.fernandez-grana@pasqal.com>, Charles Moussa <charles.moussa@pasqal.com>, Giorgio Tosti Balducci <giorgio.tosti-balducci@pasqal.com>, Daniele Cucurachi <daniele.cucurachi@pasqal.com>
|
6
6
|
License: Apache 2.0
|
7
|
-
License-File: LICENSE
|
8
7
|
Classifier: License :: OSI Approved :: Apache Software License
|
9
8
|
Classifier: Programming Language :: Python
|
10
9
|
Classifier: Programming Language :: Python :: 3
|
@@ -22,7 +21,7 @@ Requires-Dist: matplotlib
|
|
22
21
|
Requires-Dist: nevergrad
|
23
22
|
Requires-Dist: numpy
|
24
23
|
Requires-Dist: openfermion
|
25
|
-
Requires-Dist: pyqtorch==1.
|
24
|
+
Requires-Dist: pyqtorch==1.6.0
|
26
25
|
Requires-Dist: pyyaml
|
27
26
|
Requires-Dist: rich
|
28
27
|
Requires-Dist: scipy
|
@@ -31,14 +30,11 @@ Requires-Dist: sympytorch>=0.1.2
|
|
31
30
|
Requires-Dist: tensorboard>=2.12.0
|
32
31
|
Requires-Dist: torch
|
33
32
|
Provides-Extra: all
|
34
|
-
Requires-Dist: braket; extra == 'all'
|
35
33
|
Requires-Dist: libs; extra == 'all'
|
36
34
|
Requires-Dist: mlflow; extra == 'all'
|
37
35
|
Requires-Dist: protocols; extra == 'all'
|
38
36
|
Requires-Dist: pulser; extra == 'all'
|
39
37
|
Requires-Dist: visualization; extra == 'all'
|
40
|
-
Provides-Extra: braket
|
41
|
-
Requires-Dist: amazon-braket-sdk<1.71.2; extra == 'braket'
|
42
38
|
Provides-Extra: dlprof
|
43
39
|
Requires-Dist: nvidia-dlprof[pytorch]; extra == 'dlprof'
|
44
40
|
Requires-Dist: nvidia-pyindex; extra == 'dlprof'
|
@@ -57,9 +53,9 @@ Requires-Dist: mlflow; extra == 'mlflow'
|
|
57
53
|
Provides-Extra: protocols
|
58
54
|
Requires-Dist: qadence-protocols; extra == 'protocols'
|
59
55
|
Provides-Extra: pulser
|
60
|
-
Requires-Dist: pasqal-cloud==0.12.
|
61
|
-
Requires-Dist: pulser-core==
|
62
|
-
Requires-Dist: pulser-simulation==
|
56
|
+
Requires-Dist: pasqal-cloud==0.12.5; extra == 'pulser'
|
57
|
+
Requires-Dist: pulser-core==1.1.1; extra == 'pulser'
|
58
|
+
Requires-Dist: pulser-simulation==1.1.1; extra == 'pulser'
|
63
59
|
Provides-Extra: visualization
|
64
60
|
Requires-Dist: graphviz; extra == 'visualization'
|
65
61
|
Description-Content-Type: text/markdown
|