emu-base 1.2.1__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 +47 -0
- emu_base/base_classes/__init__.py +31 -0
- emu_base/base_classes/aggregators.py +59 -0
- emu_base/base_classes/backend.py +48 -0
- emu_base/base_classes/callback.py +90 -0
- emu_base/base_classes/config.py +81 -0
- emu_base/base_classes/default_callbacks.py +300 -0
- emu_base/base_classes/operator.py +126 -0
- emu_base/base_classes/results.py +174 -0
- emu_base/base_classes/state.py +97 -0
- emu_base/lindblad_operators.py +44 -0
- emu_base/math/__init__.py +3 -0
- emu_base/math/brents_root_finding.py +121 -0
- emu_base/math/krylov_exp.py +127 -0
- emu_base/pulser_adapter.py +248 -0
- emu_base/utils.py +9 -0
- emu_base-1.2.1.dist-info/METADATA +134 -0
- emu_base-1.2.1.dist-info/RECORD +19 -0
- emu_base-1.2.1.dist-info/WHEEL +4 -0
|
@@ -0,0 +1,248 @@
|
|
|
1
|
+
import pulser
|
|
2
|
+
from typing import Tuple
|
|
3
|
+
import torch
|
|
4
|
+
import math
|
|
5
|
+
from pulser.noise_model import NoiseModel
|
|
6
|
+
from enum import Enum
|
|
7
|
+
|
|
8
|
+
from emu_base.base_classes.config import BackendConfig
|
|
9
|
+
from emu_base.lindblad_operators import get_lindblad_operators
|
|
10
|
+
from emu_base.utils import dist2, dist3
|
|
11
|
+
|
|
12
|
+
|
|
13
|
+
class HamiltonianType(Enum):
|
|
14
|
+
Rydberg = 1
|
|
15
|
+
XY = 2
|
|
16
|
+
|
|
17
|
+
|
|
18
|
+
def _get_qubit_positions(
|
|
19
|
+
register: pulser.Register,
|
|
20
|
+
) -> list[torch.Tensor]:
|
|
21
|
+
"""Conversion from pulser Register to emu-mps register (torch type).
|
|
22
|
+
Each element will be given as [Rx,Ry,Rz]"""
|
|
23
|
+
|
|
24
|
+
positions = [position.as_tensor() for position in register.qubits.values()]
|
|
25
|
+
|
|
26
|
+
if len(positions[0]) == 2:
|
|
27
|
+
return [torch.cat((position, torch.zeros(1))) for position in positions]
|
|
28
|
+
return positions
|
|
29
|
+
|
|
30
|
+
|
|
31
|
+
def _rydberg_interaction(sequence: pulser.Sequence) -> torch.Tensor:
|
|
32
|
+
"""
|
|
33
|
+
Computes the Ising interaction matrix from the qubit positions.
|
|
34
|
+
Hᵢⱼ=C₆/Rᵢⱼ⁶ (nᵢ⊗ nⱼ)
|
|
35
|
+
"""
|
|
36
|
+
|
|
37
|
+
num_qubits = len(sequence.register.qubit_ids)
|
|
38
|
+
|
|
39
|
+
c6 = sequence.device.interaction_coeff
|
|
40
|
+
|
|
41
|
+
qubit_positions = _get_qubit_positions(sequence.register)
|
|
42
|
+
interaction_matrix = torch.zeros(num_qubits, num_qubits)
|
|
43
|
+
|
|
44
|
+
for numi in range(len(qubit_positions)):
|
|
45
|
+
for numj in range(numi + 1, len(qubit_positions)):
|
|
46
|
+
interaction_matrix[numi][numj] = (
|
|
47
|
+
c6 / dist2(qubit_positions[numi], qubit_positions[numj]) ** 3
|
|
48
|
+
)
|
|
49
|
+
interaction_matrix[numj, numi] = interaction_matrix[numi, numj]
|
|
50
|
+
return interaction_matrix
|
|
51
|
+
|
|
52
|
+
|
|
53
|
+
def _xy_interaction(sequence: pulser.Sequence) -> torch.Tensor:
|
|
54
|
+
"""
|
|
55
|
+
Computes the XY interaction matrix from the qubit positions.
|
|
56
|
+
C₃ (1−3 cos(𝜃ᵢⱼ)²)/ Rᵢⱼ³ (𝜎ᵢ⁺ 𝜎ⱼ⁻ + 𝜎ᵢ⁻ 𝜎ⱼ⁺)
|
|
57
|
+
"""
|
|
58
|
+
num_qubits = len(sequence.register.qubit_ids)
|
|
59
|
+
|
|
60
|
+
c3 = sequence.device.interaction_coeff_xy
|
|
61
|
+
|
|
62
|
+
qubit_positions = _get_qubit_positions(sequence.register)
|
|
63
|
+
interaction_matrix = torch.zeros(num_qubits, num_qubits)
|
|
64
|
+
mag_field = torch.tensor(sequence.magnetic_field) # by default [0.0,0.0,30.0]
|
|
65
|
+
mag_norm = torch.norm(mag_field)
|
|
66
|
+
|
|
67
|
+
for numi in range(len(qubit_positions)):
|
|
68
|
+
for numj in range(numi + 1, len(qubit_positions)):
|
|
69
|
+
cosine = 0
|
|
70
|
+
if mag_norm >= 1e-8: # selected by hand
|
|
71
|
+
cosine = torch.dot(
|
|
72
|
+
(qubit_positions[numi] - qubit_positions[numj]), mag_field
|
|
73
|
+
) / (torch.norm(qubit_positions[numi] - qubit_positions[numj]) * mag_norm)
|
|
74
|
+
|
|
75
|
+
interaction_matrix[numi][numj] = (
|
|
76
|
+
c3 # check this value with pulser people
|
|
77
|
+
* (1 - 3 * cosine**2)
|
|
78
|
+
/ dist3(qubit_positions[numi], qubit_positions[numj])
|
|
79
|
+
)
|
|
80
|
+
interaction_matrix[numj, numi] = interaction_matrix[numi, numj]
|
|
81
|
+
|
|
82
|
+
return interaction_matrix
|
|
83
|
+
|
|
84
|
+
|
|
85
|
+
def _extract_omega_delta_phi(
|
|
86
|
+
*,
|
|
87
|
+
sequence: pulser.Sequence,
|
|
88
|
+
dt: int,
|
|
89
|
+
with_modulation: bool,
|
|
90
|
+
laser_waist: float | None,
|
|
91
|
+
) -> Tuple[torch.Tensor, torch.Tensor, torch.Tensor]:
|
|
92
|
+
"""
|
|
93
|
+
Samples the Pulser sequence and returns a tuple of tensors (omega, delta, phi)
|
|
94
|
+
containing:
|
|
95
|
+
- omega[i, q] = amplitude at time i * dt for qubit q
|
|
96
|
+
- delta[i, q] = detuning at time i * dt for qubit q
|
|
97
|
+
- phi[i, q] = phase at time i * dt for qubit q
|
|
98
|
+
|
|
99
|
+
if laser_waist is w_0 != None, the omega values coming from the global pulse channel
|
|
100
|
+
will me modulated as $\\Omega_i=\\Omega_i e^{-r_i^2/w_0^2}$
|
|
101
|
+
"""
|
|
102
|
+
|
|
103
|
+
if with_modulation and sequence._slm_mask_targets:
|
|
104
|
+
raise NotImplementedError(
|
|
105
|
+
"Simulation of sequences combining an SLM mask and output "
|
|
106
|
+
"modulation is not supported."
|
|
107
|
+
)
|
|
108
|
+
|
|
109
|
+
samples = pulser.sampler.sample(
|
|
110
|
+
sequence,
|
|
111
|
+
modulation=with_modulation,
|
|
112
|
+
extended_duration=sequence.get_duration(include_fall_time=with_modulation),
|
|
113
|
+
)
|
|
114
|
+
sequence_dict = samples.to_nested_dict(all_local=True, samples_type="tensor")["Local"]
|
|
115
|
+
|
|
116
|
+
if "ground-rydberg" in sequence_dict and len(sequence_dict) == 1:
|
|
117
|
+
locals_a_d_p = sequence_dict["ground-rydberg"]
|
|
118
|
+
elif "XY" in sequence_dict and len(sequence_dict) == 1:
|
|
119
|
+
locals_a_d_p = sequence_dict["XY"]
|
|
120
|
+
else:
|
|
121
|
+
raise ValueError("Emu-MPS only accepts ground-rydberg or mw_global channels")
|
|
122
|
+
|
|
123
|
+
max_duration = sequence.get_duration(include_fall_time=with_modulation)
|
|
124
|
+
|
|
125
|
+
nsamples = math.ceil(max_duration / dt - 1 / 2)
|
|
126
|
+
omega = torch.zeros(
|
|
127
|
+
nsamples,
|
|
128
|
+
len(sequence.register.qubit_ids),
|
|
129
|
+
dtype=torch.complex128,
|
|
130
|
+
)
|
|
131
|
+
|
|
132
|
+
delta = torch.zeros(
|
|
133
|
+
nsamples,
|
|
134
|
+
len(sequence.register.qubit_ids),
|
|
135
|
+
dtype=torch.complex128,
|
|
136
|
+
)
|
|
137
|
+
phi = torch.zeros(
|
|
138
|
+
nsamples,
|
|
139
|
+
len(sequence.register.qubit_ids),
|
|
140
|
+
dtype=torch.complex128,
|
|
141
|
+
)
|
|
142
|
+
|
|
143
|
+
if laser_waist:
|
|
144
|
+
qubit_positions = _get_qubit_positions(sequence.register)
|
|
145
|
+
waist_factors = torch.tensor(
|
|
146
|
+
[math.exp(-((x[:2].norm() / laser_waist) ** 2)) for x in qubit_positions]
|
|
147
|
+
)
|
|
148
|
+
else:
|
|
149
|
+
waist_factors = torch.ones(len(sequence.register.qubit_ids))
|
|
150
|
+
|
|
151
|
+
global_times = set()
|
|
152
|
+
for ch, ch_samples in samples.channel_samples.items():
|
|
153
|
+
if samples._ch_objs[ch].addressing == "Global":
|
|
154
|
+
for slot in ch_samples.slots:
|
|
155
|
+
global_times |= set(i for i in range(slot.ti, slot.tf))
|
|
156
|
+
|
|
157
|
+
step = 0
|
|
158
|
+
t = int((step + 1 / 2) * dt)
|
|
159
|
+
|
|
160
|
+
while t < max_duration:
|
|
161
|
+
for q_pos, q_id in enumerate(sequence.register.qubit_ids):
|
|
162
|
+
omega[step, q_pos] = locals_a_d_p[q_id]["amp"][t]
|
|
163
|
+
delta[step, q_pos] = locals_a_d_p[q_id]["det"][t]
|
|
164
|
+
phi[step, q_pos] = locals_a_d_p[q_id]["phase"][t]
|
|
165
|
+
if t in global_times:
|
|
166
|
+
omega[step] *= waist_factors
|
|
167
|
+
step += 1
|
|
168
|
+
t = int((step + 1 / 2) * dt)
|
|
169
|
+
|
|
170
|
+
return omega, delta, phi
|
|
171
|
+
|
|
172
|
+
|
|
173
|
+
_NON_LINDBLADIAN_NOISE = {"SPAM", "doppler", "amplitude"}
|
|
174
|
+
|
|
175
|
+
|
|
176
|
+
def _get_all_lindblad_noise_operators(
|
|
177
|
+
noise_model: NoiseModel | None,
|
|
178
|
+
) -> list[torch.Tensor]:
|
|
179
|
+
if noise_model is None:
|
|
180
|
+
return []
|
|
181
|
+
|
|
182
|
+
return [
|
|
183
|
+
op
|
|
184
|
+
for noise_type in noise_model.noise_types
|
|
185
|
+
if noise_type not in _NON_LINDBLADIAN_NOISE
|
|
186
|
+
for op in get_lindblad_operators(noise_type=noise_type, noise_model=noise_model)
|
|
187
|
+
]
|
|
188
|
+
|
|
189
|
+
|
|
190
|
+
class PulserData:
|
|
191
|
+
slm_end_time: int
|
|
192
|
+
full_interaction_matrix: torch.Tensor
|
|
193
|
+
masked_interaction_matrix: torch.Tensor
|
|
194
|
+
omega: torch.Tensor
|
|
195
|
+
delta: torch.Tensor
|
|
196
|
+
phi: torch.Tensor
|
|
197
|
+
hamiltonian_type: HamiltonianType
|
|
198
|
+
lindblad_ops: list[torch.Tensor]
|
|
199
|
+
|
|
200
|
+
def __init__(self, *, sequence: pulser.Sequence, config: BackendConfig, dt: int):
|
|
201
|
+
self.qubit_count = len(sequence.register.qubit_ids)
|
|
202
|
+
|
|
203
|
+
laser_waist = (
|
|
204
|
+
config.noise_model.laser_waist if config.noise_model is not None else None
|
|
205
|
+
)
|
|
206
|
+
self.omega, self.delta, self.phi = _extract_omega_delta_phi(
|
|
207
|
+
sequence=sequence,
|
|
208
|
+
dt=dt,
|
|
209
|
+
with_modulation=config.with_modulation,
|
|
210
|
+
laser_waist=laser_waist,
|
|
211
|
+
)
|
|
212
|
+
self.lindblad_ops = _get_all_lindblad_noise_operators(config.noise_model)
|
|
213
|
+
self.has_lindblad_noise: bool = self.lindblad_ops != []
|
|
214
|
+
|
|
215
|
+
addressed_basis = sequence.get_addressed_bases()[0]
|
|
216
|
+
if addressed_basis == "ground-rydberg": # for local and global
|
|
217
|
+
self.hamiltonian_type = HamiltonianType.Rydberg
|
|
218
|
+
elif addressed_basis == "XY":
|
|
219
|
+
self.hamiltonian_type = HamiltonianType.XY
|
|
220
|
+
else:
|
|
221
|
+
raise ValueError(f"Unsupported basis: {addressed_basis}")
|
|
222
|
+
|
|
223
|
+
if config.interaction_matrix is not None:
|
|
224
|
+
assert len(config.interaction_matrix) == self.qubit_count, (
|
|
225
|
+
"The number of qubits in the register should be the same as the size of "
|
|
226
|
+
"the interaction matrix"
|
|
227
|
+
)
|
|
228
|
+
|
|
229
|
+
self.full_interaction_matrix = torch.tensor(
|
|
230
|
+
config.interaction_matrix, dtype=torch.float64
|
|
231
|
+
)
|
|
232
|
+
elif self.hamiltonian_type == HamiltonianType.Rydberg:
|
|
233
|
+
self.full_interaction_matrix = _rydberg_interaction(sequence)
|
|
234
|
+
elif self.hamiltonian_type == HamiltonianType.XY:
|
|
235
|
+
self.full_interaction_matrix = _xy_interaction(sequence)
|
|
236
|
+
self.full_interaction_matrix[
|
|
237
|
+
torch.abs(self.full_interaction_matrix) < config.interaction_cutoff
|
|
238
|
+
] = 0.0
|
|
239
|
+
self.masked_interaction_matrix = self.full_interaction_matrix.clone()
|
|
240
|
+
|
|
241
|
+
slm_targets = sequence._slm_mask_targets
|
|
242
|
+
self.slm_end_time = (
|
|
243
|
+
sequence._slm_mask_time[1] if len(sequence._slm_mask_time) > 1 else 0.0
|
|
244
|
+
)
|
|
245
|
+
|
|
246
|
+
for target in slm_targets:
|
|
247
|
+
self.masked_interaction_matrix[target] = 0.0
|
|
248
|
+
self.masked_interaction_matrix[:, target] = 0.0
|
emu_base/utils.py
ADDED
|
@@ -0,0 +1,134 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: emu-base
|
|
3
|
+
Version: 1.2.1
|
|
4
|
+
Summary: Pasqal base classes for emulators
|
|
5
|
+
Author-email: Anton Quelle <anton.quelle@pasqal.com>, Mauro Mendizabal <mauro.mendizabal-pico@pasqal.com>, Stefano Grava <stefano.grava@pasqal.com>, Pablo Le Henaff <pablo.le-henaff@pasqal.com>
|
|
6
|
+
License: Proprietary
|
|
7
|
+
Classifier: License :: Other/Proprietary License
|
|
8
|
+
Classifier: Programming Language :: Python :: 3.10
|
|
9
|
+
Classifier: Programming Language :: Python :: Implementation :: CPython
|
|
10
|
+
Classifier: Programming Language :: Python :: Implementation :: PyPy
|
|
11
|
+
Requires-Python: >=3.10
|
|
12
|
+
Requires-Dist: pulser-core==1.1.*
|
|
13
|
+
Requires-Dist: torch==2.5.0
|
|
14
|
+
Description-Content-Type: text/markdown
|
|
15
|
+
|
|
16
|
+
<div align="center">
|
|
17
|
+
<img src="docs/logos/LogoTaglineSoftGreen.svg">
|
|
18
|
+
|
|
19
|
+
# Emu-MPS
|
|
20
|
+
</div>
|
|
21
|
+
|
|
22
|
+
**EMU-MPS** is a Pulser backend, designed to **EMU**late the dynamics of programmable arrays of neutral atoms, with matrix product states (**MPS**). It allows users to increase the number of qubits and reduce computation time.
|
|
23
|
+
|
|
24
|
+
Join us on [Slack](https://pasqalworkspace.slack.com/archives/C07MUV5K7EU) or by [e-mail](mailto:emulation@pasqal.com) to give us feedback about how you plan to use Emu-MPS or if you require specific feature-upgrades.
|
|
25
|
+
|
|
26
|
+
|
|
27
|
+
## Getting started
|
|
28
|
+
|
|
29
|
+
You can install from source, or download the package from the private pypi registry that pasqal maintains in gitlab.
|
|
30
|
+
For developers, we recommend installing from source, for users we recommend installing from the registry.
|
|
31
|
+
|
|
32
|
+
**Warning:** installing emu-mps will update pulser-core
|
|
33
|
+
|
|
34
|
+
We always recommend using a virtual environment.
|
|
35
|
+
|
|
36
|
+
<details>
|
|
37
|
+
<summary>Click me to see how it is done</summary>
|
|
38
|
+
|
|
39
|
+
#### Create a virtual environment using python
|
|
40
|
+
|
|
41
|
+
```
|
|
42
|
+
python -m venv .venv
|
|
43
|
+
```
|
|
44
|
+
|
|
45
|
+
Or
|
|
46
|
+
|
|
47
|
+
```
|
|
48
|
+
python -m venv /path/to/new/virtual/environment
|
|
49
|
+
```
|
|
50
|
+
|
|
51
|
+
Replace `/path/to/new/virtual/environment` with your desired directory path.
|
|
52
|
+
|
|
53
|
+
Then activate the environment On linux or MacOS
|
|
54
|
+
|
|
55
|
+
```
|
|
56
|
+
source /path/to/new/virtual/environment/bin/activate
|
|
57
|
+
```
|
|
58
|
+
|
|
59
|
+
While on Windows it's
|
|
60
|
+
|
|
61
|
+
```
|
|
62
|
+
C:\> /path/to/new/virtual/environment/Scripts/activate
|
|
63
|
+
```
|
|
64
|
+
|
|
65
|
+
Remember to replace `/path/to/new/virtual/environment` with the actual path to your virtual environment. Once the environment is activated, you can clone emu_mps and install it using
|
|
66
|
+
|
|
67
|
+
</details>
|
|
68
|
+
|
|
69
|
+
### installing from the registry
|
|
70
|
+
|
|
71
|
+
When pip is configured to know about the pasqal registry, Emu-MPS installs as
|
|
72
|
+
|
|
73
|
+
```bash
|
|
74
|
+
pip install emu-mps
|
|
75
|
+
```
|
|
76
|
+
When pip is not already configured, the easiest way to do so, is to add a file `~/.config/pip/pip.conf` containing:
|
|
77
|
+
|
|
78
|
+
```
|
|
79
|
+
[global]
|
|
80
|
+
extra-index-url=https://gitlab.pasqal.com/api/v4/projects/597/packages/pypi/simple
|
|
81
|
+
possible.other.urls
|
|
82
|
+
```
|
|
83
|
+
|
|
84
|
+
As this shows, it is also possible to have multiple extra repositories configured. Note that the order is not important.
|
|
85
|
+
|
|
86
|
+
It is also possible to add the `extra-index-url` to the `pip install` command directly, if you somehow don't want to create a `pip.conf` file.
|
|
87
|
+
|
|
88
|
+
### installing from source
|
|
89
|
+
git clone this [repository ](https://gitlab.pasqal.com/emulation/rydberg-atoms/emu-ct) or download
|
|
90
|
+
|
|
91
|
+
|
|
92
|
+
Then, `cd` into the root folder of the repo and type
|
|
93
|
+
|
|
94
|
+
```bash
|
|
95
|
+
pip install -e .
|
|
96
|
+
```
|
|
97
|
+
|
|
98
|
+
<details>
|
|
99
|
+
<summary>Guidelines for developers </summary>
|
|
100
|
+
We recommend using an environment, git clone the repository, then inside the `emu_mps` folder
|
|
101
|
+
|
|
102
|
+
```bash
|
|
103
|
+
pip install -e .
|
|
104
|
+
```
|
|
105
|
+
|
|
106
|
+
Also, the installation of pytest, nbmake, pre-commit.
|
|
107
|
+
|
|
108
|
+
Do not forget to run the unit test suite by simply running `pytest` command.
|
|
109
|
+
|
|
110
|
+
Another way can be using hatch.
|
|
111
|
+
|
|
112
|
+
#### virtual environment with `hatch`
|
|
113
|
+
|
|
114
|
+
```bash
|
|
115
|
+
python -m pip install hatch
|
|
116
|
+
python -m hatch -v shell
|
|
117
|
+
```
|
|
118
|
+
|
|
119
|
+
When inside the shell with development dependencies, install first the pre-commit hook:
|
|
120
|
+
```
|
|
121
|
+
pre-commit install
|
|
122
|
+
```
|
|
123
|
+
</details>
|
|
124
|
+
|
|
125
|
+
## Check the tutorial notebooks and example scripts
|
|
126
|
+
|
|
127
|
+
For more information, you can check the tutorials and examples located in the [examples folder](https://gitlab.pasqal.com/emulation/rydberg-atoms/emu-ct/-/tree/main/examples?ref_type=heads)
|
|
128
|
+
|
|
129
|
+
## Documentation
|
|
130
|
+
|
|
131
|
+
Please check the [documentation](./docs/index.md) page for more info about contributing, the API, benchmarks, etc.
|
|
132
|
+
|
|
133
|
+
|
|
134
|
+

|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
emu_base/__init__.py,sha256=afeGAvgNi3tn7J0cWS2JBQxYZ-HYWS6o1skt0Ev319c,1130
|
|
2
|
+
emu_base/lindblad_operators.py,sha256=eXkXsLt_fV7jhF31EkxzYFU04rOJV3uWXsl6t1aTAqs,1562
|
|
3
|
+
emu_base/pulser_adapter.py,sha256=AjBT9CM0HX5vh8JaU1wRZq1QgXVAryAsYMNKmtPk9x4,8730
|
|
4
|
+
emu_base/utils.py,sha256=YCi7UngUzZYSOONhecUdFSB_OkH_aadMTvixzqHYYAc,235
|
|
5
|
+
emu_base/base_classes/__init__.py,sha256=Su6fHtjCyg0fw-7y7e7nbMfDASppNRQs8iGaAOkO3c4,570
|
|
6
|
+
emu_base/base_classes/aggregators.py,sha256=bcvoGfZCkPKv-CI29gTma6HBphGh7bjBq2Ome77eRJM,1840
|
|
7
|
+
emu_base/base_classes/backend.py,sha256=7tnwb9MnRbwRN1_JTqliYftjqExuOE-Rrwz9AU2Pc4c,1645
|
|
8
|
+
emu_base/base_classes/callback.py,sha256=JXah_ZDNM8iyPWy7IOwW481qRFyqVvlSM-0OkjBzV0A,3055
|
|
9
|
+
emu_base/base_classes/config.py,sha256=e7ZRNcBBTEfD_TrODZqCRncvOTUs07TivH04dKaiXrI,3333
|
|
10
|
+
emu_base/base_classes/default_callbacks.py,sha256=F44kkuwWdVcvMGZ9vJ2q7ug-_P8IQyJv-SVxSVWHW_w,9940
|
|
11
|
+
emu_base/base_classes/operator.py,sha256=MJjuDUTwJLbaSJzSNCKDWGvmGCGAEIEWISLoPSSzNsU,3501
|
|
12
|
+
emu_base/base_classes/results.py,sha256=7-Mz3jmFy19hd3PIA5idK610mC3b5jOf3EKBmV14Jv4,5569
|
|
13
|
+
emu_base/base_classes/state.py,sha256=7iIyZmBqqJ6G4SyYZ3kyylWjAqiYIx0aW5B0T74EPZI,2707
|
|
14
|
+
emu_base/math/__init__.py,sha256=6BbIytYV5uC-e5jLMtIErkcUl_PvfSNnhmVFY9Il8uQ,97
|
|
15
|
+
emu_base/math/brents_root_finding.py,sha256=AVx6L1Il6rpPJWrLJ7cn6oNmJyZOPRgEaaZaubC9lsU,3711
|
|
16
|
+
emu_base/math/krylov_exp.py,sha256=TKvlByRKfCNZdS_YcfCtTk4D7YGhJ-2eIylLVT-X7i4,3784
|
|
17
|
+
emu_base-1.2.1.dist-info/METADATA,sha256=NJK1z5qdfuhJj4B-7f3jfJ4IgxyUp3JHGBqvdxTPhXA,4220
|
|
18
|
+
emu_base-1.2.1.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87
|
|
19
|
+
emu_base-1.2.1.dist-info/RECORD,,
|