emu-base 1.2.6__py3-none-any.whl → 1.2.7__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.
- emu_base/__init__.py +1 -1
- emu_base/base_classes/aggregators.py +8 -3
- emu_base/base_classes/config.py +1 -1
- emu_base/base_classes/results.py +9 -0
- emu_base/lindblad_operators.py +4 -1
- emu_base/pulser_adapter.py +24 -17
- {emu_base-1.2.6.dist-info → emu_base-1.2.7.dist-info}/METADATA +1 -1
- {emu_base-1.2.6.dist-info → emu_base-1.2.7.dist-info}/RECORD +9 -9
- {emu_base-1.2.6.dist-info → emu_base-1.2.7.dist-info}/WHEEL +0 -0
emu_base/__init__.py
CHANGED
|
@@ -9,9 +9,14 @@ _NUMERIC_TYPES = {int, float, complex}
|
|
|
9
9
|
|
|
10
10
|
def mean_aggregator(
|
|
11
11
|
values: list[Any],
|
|
12
|
-
) ->
|
|
13
|
-
|
|
14
|
-
|
|
12
|
+
) -> (
|
|
13
|
+
complex
|
|
14
|
+
| float
|
|
15
|
+
| list[complex]
|
|
16
|
+
| list[float]
|
|
17
|
+
| list[list[complex]]
|
|
18
|
+
| list[list[float]]
|
|
19
|
+
): # FIXME: support tuples?
|
|
15
20
|
if values == []:
|
|
16
21
|
raise ValueError("Cannot average 0 samples")
|
|
17
22
|
|
emu_base/base_classes/config.py
CHANGED
|
@@ -37,7 +37,7 @@ class BackendConfig:
|
|
|
37
37
|
*,
|
|
38
38
|
observables: list[Callback] | None = None,
|
|
39
39
|
with_modulation: bool = False,
|
|
40
|
-
noise_model: NoiseModel = None,
|
|
40
|
+
noise_model: NoiseModel | None = None,
|
|
41
41
|
interaction_matrix: list[list[float]] | None = None,
|
|
42
42
|
interaction_cutoff: float = 0.0,
|
|
43
43
|
log_level: int = logging.INFO,
|
emu_base/base_classes/results.py
CHANGED
|
@@ -3,11 +3,19 @@ from typing import Any, Callable, Optional
|
|
|
3
3
|
from pathlib import Path
|
|
4
4
|
import json
|
|
5
5
|
import logging
|
|
6
|
+
import torch
|
|
6
7
|
|
|
7
8
|
from emu_base.base_classes.callback import Callback, AggregationType
|
|
8
9
|
from emu_base.base_classes.aggregators import aggregation_types_definitions
|
|
9
10
|
|
|
10
11
|
|
|
12
|
+
class ResultsEncoder(json.JSONEncoder):
|
|
13
|
+
def default(self, obj: Any) -> Any:
|
|
14
|
+
if isinstance(obj, torch.Tensor):
|
|
15
|
+
return obj.tolist()
|
|
16
|
+
return super().default(obj)
|
|
17
|
+
|
|
18
|
+
|
|
11
19
|
@dataclass
|
|
12
20
|
class Results:
|
|
13
21
|
"""
|
|
@@ -171,4 +179,5 @@ class Results:
|
|
|
171
179
|
"statistics": self.statistics,
|
|
172
180
|
},
|
|
173
181
|
file_handle,
|
|
182
|
+
cls=ResultsEncoder,
|
|
174
183
|
)
|
emu_base/lindblad_operators.py
CHANGED
|
@@ -32,7 +32,10 @@ def get_lindblad_operators(
|
|
|
32
32
|
]
|
|
33
33
|
|
|
34
34
|
if noise_type == "eff_noise":
|
|
35
|
-
if not all(
|
|
35
|
+
if not all(
|
|
36
|
+
isinstance(op, torch.Tensor) and op.shape == (2, 2)
|
|
37
|
+
for op in noise_model.eff_noise_opers
|
|
38
|
+
):
|
|
36
39
|
raise ValueError("Only 2 * 2 effective noise operator matrices are supported")
|
|
37
40
|
|
|
38
41
|
return [
|
emu_base/pulser_adapter.py
CHANGED
|
@@ -5,6 +5,8 @@ import math
|
|
|
5
5
|
from pulser.noise_model import NoiseModel
|
|
6
6
|
from enum import Enum
|
|
7
7
|
|
|
8
|
+
from pulser.register.base_register import BaseRegister
|
|
9
|
+
|
|
8
10
|
from emu_base.base_classes.config import BackendConfig
|
|
9
11
|
from emu_base.lindblad_operators import get_lindblad_operators
|
|
10
12
|
from emu_base.utils import dist2, dist3
|
|
@@ -16,7 +18,7 @@ class HamiltonianType(Enum):
|
|
|
16
18
|
|
|
17
19
|
|
|
18
20
|
def _get_qubit_positions(
|
|
19
|
-
register:
|
|
21
|
+
register: BaseRegister,
|
|
20
22
|
) -> list[torch.Tensor]:
|
|
21
23
|
"""Conversion from pulser Register to emu-mps register (torch type).
|
|
22
24
|
Each element will be given as [Rx,Ry,Rz]"""
|
|
@@ -31,7 +33,7 @@ def _get_qubit_positions(
|
|
|
31
33
|
def _rydberg_interaction(sequence: pulser.Sequence) -> torch.Tensor:
|
|
32
34
|
"""
|
|
33
35
|
Computes the Ising interaction matrix from the qubit positions.
|
|
34
|
-
Hᵢⱼ=C₆/R
|
|
36
|
+
Hᵢⱼ=C₆/R⁶ᵢⱼ (nᵢ⊗ nⱼ)
|
|
35
37
|
"""
|
|
36
38
|
|
|
37
39
|
num_qubits = len(sequence.register.qubit_ids)
|
|
@@ -88,7 +90,7 @@ def _xy_interaction(sequence: pulser.Sequence) -> torch.Tensor:
|
|
|
88
90
|
def _extract_omega_delta_phi(
|
|
89
91
|
*,
|
|
90
92
|
sequence: pulser.Sequence,
|
|
91
|
-
|
|
93
|
+
target_times: list[int],
|
|
92
94
|
with_modulation: bool,
|
|
93
95
|
laser_waist: float | None,
|
|
94
96
|
) -> Tuple[torch.Tensor, torch.Tensor, torch.Tensor]:
|
|
@@ -125,7 +127,7 @@ def _extract_omega_delta_phi(
|
|
|
125
127
|
|
|
126
128
|
max_duration = sequence.get_duration(include_fall_time=with_modulation)
|
|
127
129
|
|
|
128
|
-
nsamples =
|
|
130
|
+
nsamples = len(target_times) - 1
|
|
129
131
|
omega = torch.zeros(
|
|
130
132
|
nsamples,
|
|
131
133
|
len(sequence.register.qubit_ids),
|
|
@@ -157,12 +159,11 @@ def _extract_omega_delta_phi(
|
|
|
157
159
|
for slot in ch_samples.slots:
|
|
158
160
|
global_times |= set(i for i in range(slot.ti, slot.tf))
|
|
159
161
|
|
|
160
|
-
step = 0
|
|
161
|
-
t = (step + 1 / 2) * dt
|
|
162
162
|
omega_1 = torch.zeros_like(omega[0])
|
|
163
163
|
omega_2 = torch.zeros_like(omega[0])
|
|
164
164
|
|
|
165
|
-
|
|
165
|
+
for i in range(nsamples):
|
|
166
|
+
t = (target_times[i] + target_times[i + 1]) / 2
|
|
166
167
|
# The sampled values correspond to the start of each interval
|
|
167
168
|
# To maximize the order of the solver, we need the values in the middle
|
|
168
169
|
if math.ceil(t) < max_duration:
|
|
@@ -173,10 +174,10 @@ def _extract_omega_delta_phi(
|
|
|
173
174
|
t2 = math.ceil(t)
|
|
174
175
|
omega_1[q_pos] = locals_a_d_p[q_id]["amp"][t1]
|
|
175
176
|
omega_2[q_pos] = locals_a_d_p[q_id]["amp"][t2]
|
|
176
|
-
delta[
|
|
177
|
+
delta[i, q_pos] = (
|
|
177
178
|
locals_a_d_p[q_id]["det"][t1] + locals_a_d_p[q_id]["det"][t2]
|
|
178
179
|
) / 2.0
|
|
179
|
-
phi[
|
|
180
|
+
phi[i, q_pos] = (
|
|
180
181
|
locals_a_d_p[q_id]["phase"][t1] + locals_a_d_p[q_id]["phase"][t2]
|
|
181
182
|
) / 2.0
|
|
182
183
|
# omegas at different times need to have the laser waist applied independently
|
|
@@ -184,21 +185,19 @@ def _extract_omega_delta_phi(
|
|
|
184
185
|
omega_1 *= waist_factors
|
|
185
186
|
if t2 in global_times:
|
|
186
187
|
omega_2 *= waist_factors
|
|
187
|
-
omega[
|
|
188
|
+
omega[i] = 0.5 * (omega_1 + omega_2)
|
|
188
189
|
else:
|
|
189
190
|
# We're in the final step and dt=1, approximate this using linear extrapolation
|
|
190
191
|
# we can reuse omega_1 and omega_2 from before
|
|
191
192
|
for q_pos, q_id in enumerate(sequence.register.qubit_ids):
|
|
192
|
-
delta[
|
|
193
|
+
delta[i, q_pos] = (
|
|
193
194
|
3.0 * locals_a_d_p[q_id]["det"][t2] - locals_a_d_p[q_id]["det"][t1]
|
|
194
195
|
) / 2.0
|
|
195
|
-
phi[
|
|
196
|
+
phi[i, q_pos] = (
|
|
196
197
|
3.0 * locals_a_d_p[q_id]["phase"][t2]
|
|
197
198
|
- locals_a_d_p[q_id]["phase"][t1]
|
|
198
199
|
) / 2.0
|
|
199
|
-
omega[
|
|
200
|
-
step += 1
|
|
201
|
-
t = (step + 1 / 2) * dt
|
|
200
|
+
omega[i] = torch.clamp(0.5 * (3 * omega_2 - omega_1).real, min=0.0)
|
|
202
201
|
|
|
203
202
|
return omega, delta, phi
|
|
204
203
|
|
|
@@ -221,7 +220,7 @@ def _get_all_lindblad_noise_operators(
|
|
|
221
220
|
|
|
222
221
|
|
|
223
222
|
class PulserData:
|
|
224
|
-
slm_end_time:
|
|
223
|
+
slm_end_time: float
|
|
225
224
|
full_interaction_matrix: torch.Tensor
|
|
226
225
|
masked_interaction_matrix: torch.Tensor
|
|
227
226
|
omega: torch.Tensor
|
|
@@ -233,12 +232,20 @@ class PulserData:
|
|
|
233
232
|
def __init__(self, *, sequence: pulser.Sequence, config: BackendConfig, dt: int):
|
|
234
233
|
self.qubit_count = len(sequence.register.qubit_ids)
|
|
235
234
|
|
|
235
|
+
# the end value is exclusive, so add +1
|
|
236
|
+
observable_times = set(torch.arange(0, sequence.get_duration() + 1, dt).tolist())
|
|
237
|
+
observable_times.add(sequence.get_duration())
|
|
238
|
+
for obs in config.callbacks:
|
|
239
|
+
observable_times |= set(obs.evaluation_times)
|
|
240
|
+
self.target_times = list(observable_times)
|
|
241
|
+
self.target_times.sort()
|
|
242
|
+
|
|
236
243
|
laser_waist = (
|
|
237
244
|
config.noise_model.laser_waist if config.noise_model is not None else None
|
|
238
245
|
)
|
|
239
246
|
self.omega, self.delta, self.phi = _extract_omega_delta_phi(
|
|
240
247
|
sequence=sequence,
|
|
241
|
-
|
|
248
|
+
target_times=self.target_times,
|
|
242
249
|
with_modulation=config.with_modulation,
|
|
243
250
|
laser_waist=laser_waist,
|
|
244
251
|
)
|
|
@@ -1,20 +1,20 @@
|
|
|
1
|
-
emu_base/__init__.py,sha256=
|
|
1
|
+
emu_base/__init__.py,sha256=i2Gv8rIusAD2hXepDFdFTfC5FQOOpNXtB0F1xoSd6QQ,1186
|
|
2
2
|
emu_base/constants.py,sha256=41LYkKLUCz-oxPbd-j7nUDZuhIbUrnez6prT0uR0jcE,56
|
|
3
|
-
emu_base/lindblad_operators.py,sha256=
|
|
4
|
-
emu_base/pulser_adapter.py,sha256=
|
|
3
|
+
emu_base/lindblad_operators.py,sha256=Nsl1YrWb8IDM9Z50ucy2Ed44p_IRETnlbr6qaqAgV50,1629
|
|
4
|
+
emu_base/pulser_adapter.py,sha256=SIkw3Mrob4RPTt4QNYzC8CUJ0tj-sTj-t-fEKEyRTtU,10858
|
|
5
5
|
emu_base/utils.py,sha256=RM8O0qfPAJfcdqqAojwEEKV7I3ZfVDklnTisTGhUg5k,233
|
|
6
6
|
emu_base/base_classes/__init__.py,sha256=Su6fHtjCyg0fw-7y7e7nbMfDASppNRQs8iGaAOkO3c4,570
|
|
7
|
-
emu_base/base_classes/aggregators.py,sha256=
|
|
7
|
+
emu_base/base_classes/aggregators.py,sha256=BDzFq12q36p12TXp2qv3g7a9cHnXbT1hhMZJLVojkDU,1862
|
|
8
8
|
emu_base/base_classes/backend.py,sha256=7tnwb9MnRbwRN1_JTqliYftjqExuOE-Rrwz9AU2Pc4c,1645
|
|
9
9
|
emu_base/base_classes/callback.py,sha256=JXah_ZDNM8iyPWy7IOwW481qRFyqVvlSM-0OkjBzV0A,3055
|
|
10
|
-
emu_base/base_classes/config.py,sha256=
|
|
10
|
+
emu_base/base_classes/config.py,sha256=oLS2jwmxqwMbLKIPdqohK-KPIcXdtpG3sRr_Y12poNQ,4105
|
|
11
11
|
emu_base/base_classes/default_callbacks.py,sha256=F44kkuwWdVcvMGZ9vJ2q7ug-_P8IQyJv-SVxSVWHW_w,9940
|
|
12
12
|
emu_base/base_classes/operator.py,sha256=MJjuDUTwJLbaSJzSNCKDWGvmGCGAEIEWISLoPSSzNsU,3501
|
|
13
|
-
emu_base/base_classes/results.py,sha256=
|
|
13
|
+
emu_base/base_classes/results.py,sha256=w4js7gThb49sNjEEDfEf0tYRwK004GrafWPeEOvyeCg,5810
|
|
14
14
|
emu_base/base_classes/state.py,sha256=7iIyZmBqqJ6G4SyYZ3kyylWjAqiYIx0aW5B0T74EPZI,2707
|
|
15
15
|
emu_base/math/__init__.py,sha256=6BbIytYV5uC-e5jLMtIErkcUl_PvfSNnhmVFY9Il8uQ,97
|
|
16
16
|
emu_base/math/brents_root_finding.py,sha256=AVx6L1Il6rpPJWrLJ7cn6oNmJyZOPRgEaaZaubC9lsU,3711
|
|
17
17
|
emu_base/math/krylov_exp.py,sha256=UCFNeq-j2ukgBsOPC9_Jiv1aqpy88SrslDLiCxIGBwk,3840
|
|
18
|
-
emu_base-1.2.
|
|
19
|
-
emu_base-1.2.
|
|
20
|
-
emu_base-1.2.
|
|
18
|
+
emu_base-1.2.7.dist-info/METADATA,sha256=JpfSGDOQtIu2hwwoHXgBNgf8ZmIkUh0MUDiwJYPZL_Q,3522
|
|
19
|
+
emu_base-1.2.7.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87
|
|
20
|
+
emu_base-1.2.7.dist-info/RECORD,,
|
|
File without changes
|