emu-mps 2.0.0__py3-none-any.whl → 2.0.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_mps/__init__.py +3 -1
- emu_mps/mps.py +19 -0
- emu_mps/mps_backend_impl.py +2 -3
- emu_mps/observables.py +40 -0
- {emu_mps-2.0.0.dist-info → emu_mps-2.0.1.dist-info}/METADATA +2 -2
- {emu_mps-2.0.0.dist-info → emu_mps-2.0.1.dist-info}/RECORD +7 -6
- {emu_mps-2.0.0.dist-info → emu_mps-2.0.1.dist-info}/WHEEL +0 -0
emu_mps/__init__.py
CHANGED
|
@@ -13,6 +13,7 @@ from .mps_config import MPSConfig
|
|
|
13
13
|
from .mpo import MPO
|
|
14
14
|
from .mps import MPS, inner
|
|
15
15
|
from .mps_backend import MPSBackend
|
|
16
|
+
from .observables import EntanglementEntropy
|
|
16
17
|
from emu_base import aggregate
|
|
17
18
|
|
|
18
19
|
|
|
@@ -33,6 +34,7 @@ __all__ = [
|
|
|
33
34
|
"EnergyVariance",
|
|
34
35
|
"EnergySecondMoment",
|
|
35
36
|
"aggregate",
|
|
37
|
+
"EntanglementEntropy",
|
|
36
38
|
]
|
|
37
39
|
|
|
38
|
-
__version__ = "2.0.
|
|
40
|
+
__version__ = "2.0.1"
|
emu_mps/mps.py
CHANGED
|
@@ -307,6 +307,25 @@ class MPS(State[complex, torch.Tensor]):
|
|
|
307
307
|
"""
|
|
308
308
|
return torch.abs(self.inner(other)) ** 2 # type: ignore[no-any-return]
|
|
309
309
|
|
|
310
|
+
def entanglement_entropy(self, mps_site: int) -> torch.Tensor:
|
|
311
|
+
"""
|
|
312
|
+
Returns
|
|
313
|
+
the Von Neumann entanglement entropy of the state `mps` at the bond between sites b and b+1
|
|
314
|
+
S = -Σᵢsᵢ² log(sᵢ²)),
|
|
315
|
+
where sᵢ are the singular values at the chosen bond.
|
|
316
|
+
"""
|
|
317
|
+
self.orthogonalize(mps_site)
|
|
318
|
+
|
|
319
|
+
# perform svd on reshaped matrix at site b
|
|
320
|
+
matrix = self.factors[mps_site].flatten(end_dim=1)
|
|
321
|
+
s = torch.linalg.svdvals(matrix)
|
|
322
|
+
|
|
323
|
+
s_e = torch.Tensor(torch.special.entr(s**2))
|
|
324
|
+
s_e = torch.sum(s_e)
|
|
325
|
+
|
|
326
|
+
self.orthogonalize(0)
|
|
327
|
+
return s_e.cpu()
|
|
328
|
+
|
|
310
329
|
def get_memory_footprint(self) -> float:
|
|
311
330
|
"""
|
|
312
331
|
Returns the number of MBs of memory occupied to store the state
|
emu_mps/mps_backend_impl.py
CHANGED
|
@@ -151,14 +151,14 @@ class MPSBackendImpl:
|
|
|
151
151
|
def __getstate__(self) -> dict:
|
|
152
152
|
for obs in self.config.observables:
|
|
153
153
|
obs.apply = MethodType(type(obs).apply, obs) # type: ignore[method-assign]
|
|
154
|
-
d = self.__dict__
|
|
154
|
+
d = self.__dict__.copy()
|
|
155
155
|
# mypy thinks the method below is an attribute, because of the __getattr__ override
|
|
156
156
|
d["results"] = self.results._to_abstract_repr() # type: ignore[operator]
|
|
157
157
|
return d
|
|
158
158
|
|
|
159
159
|
def __setstate__(self, d: dict) -> None:
|
|
160
|
-
d["results"] = Results._from_abstract_repr(d["results"]) # type: ignore [attr-defined]
|
|
161
160
|
self.__dict__ = d
|
|
161
|
+
self.results = Results._from_abstract_repr(d["results"]) # type: ignore [attr-defined]
|
|
162
162
|
self.config.monkeypatch_observables()
|
|
163
163
|
|
|
164
164
|
@staticmethod
|
|
@@ -444,7 +444,6 @@ class MPSBackendImpl:
|
|
|
444
444
|
basename = self.autosave_file
|
|
445
445
|
with open(basename.with_suffix(".new"), "wb") as file_handle:
|
|
446
446
|
pickle.dump(self, file_handle)
|
|
447
|
-
|
|
448
447
|
if basename.is_file():
|
|
449
448
|
os.rename(basename, basename.with_suffix(".bak"))
|
|
450
449
|
|
emu_mps/observables.py
ADDED
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
from pulser.backend.state import State
|
|
2
|
+
from pulser.backend.observable import Observable
|
|
3
|
+
from emu_mps.mps import MPS
|
|
4
|
+
from typing import Sequence, Any
|
|
5
|
+
import torch
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
class EntanglementEntropy(Observable):
|
|
9
|
+
"""Entanglement Entropy subclass used only in emu_mps"""
|
|
10
|
+
|
|
11
|
+
def __init__(
|
|
12
|
+
self,
|
|
13
|
+
mps_site: int,
|
|
14
|
+
*,
|
|
15
|
+
evaluation_times: Sequence[float] | None = None,
|
|
16
|
+
tag_suffix: str | None = None,
|
|
17
|
+
):
|
|
18
|
+
super().__init__(evaluation_times=evaluation_times, tag_suffix=tag_suffix)
|
|
19
|
+
self.mps_site = mps_site
|
|
20
|
+
|
|
21
|
+
@property
|
|
22
|
+
def _base_tag(self) -> str:
|
|
23
|
+
return "entanglement_entropy"
|
|
24
|
+
|
|
25
|
+
def _to_abstract_repr(self) -> dict[str, Any]:
|
|
26
|
+
repr = super()._to_abstract_repr()
|
|
27
|
+
repr["mps_site"] = self.mps_site
|
|
28
|
+
return repr
|
|
29
|
+
|
|
30
|
+
def apply(self, *, state: State, **kwargs: Any) -> torch.Tensor:
|
|
31
|
+
if not isinstance(state, MPS):
|
|
32
|
+
raise NotImplementedError(
|
|
33
|
+
"Entanglement entropy observable is only available for emu_mps emulator."
|
|
34
|
+
)
|
|
35
|
+
if not (0 <= self.mps_site <= len(state.factors) - 2):
|
|
36
|
+
raise ValueError(
|
|
37
|
+
f"Invalid bond index {self.mps_site}. "
|
|
38
|
+
f"Expected value in range 0 <= bond_index <= {len(state.factors)-2}."
|
|
39
|
+
)
|
|
40
|
+
return state.entanglement_entropy(self.mps_site)
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: emu-mps
|
|
3
|
-
Version: 2.0.
|
|
3
|
+
Version: 2.0.1
|
|
4
4
|
Summary: Pasqal MPS based pulse emulator built on PyTorch
|
|
5
5
|
Project-URL: Documentation, https://pasqal-io.github.io/emulators/
|
|
6
6
|
Project-URL: Repository, https://github.com/pasqal-io/emulators
|
|
@@ -25,7 +25,7 @@ Classifier: Programming Language :: Python :: 3.10
|
|
|
25
25
|
Classifier: Programming Language :: Python :: Implementation :: CPython
|
|
26
26
|
Classifier: Programming Language :: Python :: Implementation :: PyPy
|
|
27
27
|
Requires-Python: >=3.10
|
|
28
|
-
Requires-Dist: emu-base==2.0.
|
|
28
|
+
Requires-Dist: emu-base==2.0.1
|
|
29
29
|
Description-Content-Type: text/markdown
|
|
30
30
|
|
|
31
31
|
<div align="center">
|
|
@@ -1,18 +1,19 @@
|
|
|
1
|
-
emu_mps/__init__.py,sha256=
|
|
1
|
+
emu_mps/__init__.py,sha256=GIR0FJOvmMHby7Vx_Da3w7YqqLpOxa0E8E3poxXsapY,734
|
|
2
2
|
emu_mps/algebra.py,sha256=ngPtTH-j2ZCBWoaJZXlkUyIlug7dY7Q92gzfnRlpPMA,5485
|
|
3
3
|
emu_mps/custom_callback_implementations.py,sha256=CUs0kW3HRaPE7UeFNQOFbeWJMsz4hS2q4rgS57BBp-A,2411
|
|
4
4
|
emu_mps/hamiltonian.py,sha256=LcBs6CKBb643a1e9AAVtQoUfa4L_0dIhLOKecx5OOWs,15864
|
|
5
5
|
emu_mps/mpo.py,sha256=wSonS6i3zEt3yRTgyZ7F6vT51pUKavFcLOxFFphBv8k,8793
|
|
6
|
-
emu_mps/mps.py,sha256=
|
|
6
|
+
emu_mps/mps.py,sha256=KqAjo-nxgM-xQSg1NFNchwXKoPRcrKuuycFMsWr7iX8,19610
|
|
7
7
|
emu_mps/mps_backend.py,sha256=_3rlg6XeI4fHaDiJRfPL6pDkX9k48hAHKXd8fkvkOFs,2004
|
|
8
|
-
emu_mps/mps_backend_impl.py,sha256=
|
|
8
|
+
emu_mps/mps_backend_impl.py,sha256=M_do7QRBLAoHfwF_EpyMCb6g7w7BSs5hsPa5UE0z9Zs,22958
|
|
9
9
|
emu_mps/mps_config.py,sha256=89nu5OhNUX31eAeeYvvKnAHegpPVD43jH5Nmp635HVU,6984
|
|
10
10
|
emu_mps/noise.py,sha256=h4X2EFjoC_Ok0gZ8I9wN77RANXaVehTBbjkcbY_GAmY,784
|
|
11
|
+
emu_mps/observables.py,sha256=7GQDH5kyaVNrwckk2f8ZJRV9Ca4jKhWWDsOCqYWsoEk,1349
|
|
11
12
|
emu_mps/tdvp.py,sha256=pIQ2NXA2Mrkp3elhqQbX3pdJVbtKkG3c5r9fFlJo7pI,5755
|
|
12
13
|
emu_mps/utils.py,sha256=BqRJYAcXqprtZVJ0V_j954ON2bhTdtZiaTojsYyrWrg,8193
|
|
13
14
|
emu_mps/optimatrix/__init__.py,sha256=lHWYNeThHp57ZrwTwXd0p8bNvcCv0w_AZ31iCWflBUo,226
|
|
14
15
|
emu_mps/optimatrix/optimiser.py,sha256=7j9_jMQC-Uh2DzdIVB44InRzZO6AbbGhvmm7lC6N3tk,6737
|
|
15
16
|
emu_mps/optimatrix/permutations.py,sha256=JRXGont8B4QgbkV9CzrA0w7uzLgBrmZ1J9aa0G52hPo,1979
|
|
16
|
-
emu_mps-2.0.
|
|
17
|
-
emu_mps-2.0.
|
|
18
|
-
emu_mps-2.0.
|
|
17
|
+
emu_mps-2.0.1.dist-info/METADATA,sha256=aGt2cFa9rplEaJAo8z4J5uoAkqq9WnQIlOhciUc6vkg,3505
|
|
18
|
+
emu_mps-2.0.1.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87
|
|
19
|
+
emu_mps-2.0.1.dist-info/RECORD,,
|
|
File without changes
|