bound-entangled 0.1.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.
- bound_entangled-0.1.0.dist-info/METADATA +112 -0
- bound_entangled-0.1.0.dist-info/RECORD +29 -0
- bound_entangled-0.1.0.dist-info/WHEEL +5 -0
- bound_entangled-0.1.0.dist-info/licenses/LICENSE +21 -0
- bound_entangled-0.1.0.dist-info/top_level.txt +6 -0
- c3_otimes_c3/__init__.py +7 -0
- c3_otimes_c3/chessboard.py +57 -0
- c3_otimes_c3/cross_hatch.py +25 -0
- c3_otimes_c3/horodecki.py +23 -0
- c3_otimes_c3/steering.py +42 -0
- c3_otimes_c3/upb/__init__.py +0 -0
- c3_otimes_c3/upb/parametrized_UPB.py +159 -0
- c3_otimes_c3/upb/pyramid_UPB.py +37 -0
- c3_otimes_c3/upb/tiles_UPB.py +20 -0
- c4_otimes_c4/__init__.py +1 -0
- c4_otimes_c4/pianni.py +46 -0
- c5_otimes_c5/__init__.py +1 -0
- c5_otimes_c5/sn3_grid_state.py +36 -0
- cd_otimes_cd/__init__.py +2 -0
- cd_otimes_cd/gen_tiles.py +73 -0
- cd_otimes_cd/yu_oh.py +145 -0
- cm_otimes_cn/__init__.py +4 -0
- cm_otimes_cn/gen_tiles.py +80 -0
- cm_otimes_cn/generalized_grid_state.py +38 -0
- cm_otimes_cn/grid_state.py +42 -0
- cm_otimes_cn/random_not_bound_entangled.py +62 -0
- utils/__init__.py +2 -0
- utils/ketbra.py +14 -0
- utils/upb.py +27 -0
|
@@ -0,0 +1,112 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: bound-entangled
|
|
3
|
+
Version: 0.1.0
|
|
4
|
+
Summary: Families of bound entangled states for Quantum Information
|
|
5
|
+
Author-email: AVlyx <anton@vancleem.com>
|
|
6
|
+
License: MIT
|
|
7
|
+
Project-URL: Homepage, https://github.com/AVlyx/bound-entangled
|
|
8
|
+
Requires-Python: >=3.9
|
|
9
|
+
Description-Content-Type: text/markdown
|
|
10
|
+
License-File: LICENSE
|
|
11
|
+
Requires-Dist: toqito>=1.3.0
|
|
12
|
+
Requires-Dist: numpy>=2.4.1
|
|
13
|
+
Provides-Extra: test
|
|
14
|
+
Requires-Dist: pytest; extra == "test"
|
|
15
|
+
Provides-Extra: docs
|
|
16
|
+
Requires-Dist: mkdocs; extra == "docs"
|
|
17
|
+
Requires-Dist: mkdocs-material; extra == "docs"
|
|
18
|
+
Requires-Dist: mkdocstrings[python]; extra == "docs"
|
|
19
|
+
Dynamic: license-file
|
|
20
|
+
|
|
21
|
+
# bound-entangled
|
|
22
|
+
|
|
23
|
+
Reference implementations of several families of **bound entangled states** from
|
|
24
|
+
the quantum information literature, as plain NumPy density matrices.
|
|
25
|
+
|
|
26
|
+
A bound entangled state is entangled yet has a positive partial transpose (PPT),
|
|
27
|
+
so no pure entanglement can be distilled from it. This library collects
|
|
28
|
+
constructions that are otherwise scattered across papers into a single, tested
|
|
29
|
+
package, each factory returning the density matrix `rho` of the state.
|
|
30
|
+
|
|
31
|
+
## Installation
|
|
32
|
+
|
|
33
|
+
```bash
|
|
34
|
+
pip install -e .
|
|
35
|
+
# with the test dependencies:
|
|
36
|
+
pip install -e ".[test]"
|
|
37
|
+
```
|
|
38
|
+
|
|
39
|
+
Requires Python ≥ 3.9. Depends on [`toqito`](https://toqito.readthedocs.io) and
|
|
40
|
+
NumPy.
|
|
41
|
+
|
|
42
|
+
## Usage
|
|
43
|
+
|
|
44
|
+
Packages are organized by the bipartite Hilbert space the states live in
|
|
45
|
+
(`c3_otimes_c3` = C³ ⊗ C³, `cm_otimes_cn` = C^m ⊗ C^n, etc.).
|
|
46
|
+
|
|
47
|
+
```python
|
|
48
|
+
from c3_otimes_c3 import chessboard_extremal_PPT, tiles_upb, pyramid_upb
|
|
49
|
+
from cd_otimes_cd import yu_oh
|
|
50
|
+
from c5_otimes_c5 import sn3_grid_state
|
|
51
|
+
|
|
52
|
+
rho = chessboard_extremal_PPT() # 9x9 PPT-entangled chessboard state
|
|
53
|
+
rho = yu_oh(d=3, x=0.5, y=0.5) # Yu-Oh nonlocal bound entangled state
|
|
54
|
+
```
|
|
55
|
+
|
|
56
|
+
## States
|
|
57
|
+
|
|
58
|
+
### `c3_otimes_c3` — C³ ⊗ C³
|
|
59
|
+
|
|
60
|
+
| Factory | State | Reference |
|
|
61
|
+
|---|---|---|
|
|
62
|
+
| `chessboard`, `chessboard_extremal_PPT` | Bruß–Peres chessboard states | [quant-ph/9911056](https://arxiv.org/abs/quant-ph/9911056) |
|
|
63
|
+
| `cross_hatch` | 3×3 "cross-hatch" grid state (CCNR-detected) | [1705.09261](https://arxiv.org/abs/1705.09261) |
|
|
64
|
+
| `steering_state` | Steerable bound entangled state (counterexample to the stronger Peres conjecture) | [1405.0262](https://arxiv.org/abs/1405.0262) |
|
|
65
|
+
| `tiles_upb`, `pyramid_upb` | States from the Tiles / Pyramid unextendible product bases | [quant-ph/9808030](https://arxiv.org/abs/quant-ph/9808030) |
|
|
66
|
+
| `parametrized_upb` | Six-parameter family of UPBs generalizing Tiles / Pyramid | [quant-ph/9908070](https://arxiv.org/abs/quant-ph/9908070) |
|
|
67
|
+
| `horodecki` | 3x3 Horodecki bound entangled state | [quant-ph/9703004](https://arxiv.org/abs/quant-ph/9703004) |
|
|
68
|
+
|
|
69
|
+
|
|
70
|
+
### `c4_otimes_c4` — C⁴ ⊗ C⁴
|
|
71
|
+
|
|
72
|
+
| Factory | State | Reference |
|
|
73
|
+
|---|---|---|
|
|
74
|
+
| `pianni` | 4×4 Benatti–Floreanini–Piani state | [quant-ph/0411095](https://arxiv.org/abs/quant-ph/0411095) |
|
|
75
|
+
|
|
76
|
+
### `c5_otimes_c5` — C⁵ ⊗ C⁵
|
|
77
|
+
|
|
78
|
+
| Factory | State | Reference |
|
|
79
|
+
|---|---|---|
|
|
80
|
+
| `sn3_grid_state` | Smallest known Schmidt-number-3 PPT bound entangled state | [2402.12966](https://arxiv.org/abs/2402.12966) |
|
|
81
|
+
|
|
82
|
+
### `cd_otimes_cd` — C^d ⊗ C^d
|
|
83
|
+
|
|
84
|
+
| Factory | State | Reference |
|
|
85
|
+
|---|---|---|
|
|
86
|
+
| `yu_oh`, `is_valid_yu_oh_input` | Yu–Oh family of nonlocal bound entangled states | [1509.08991](https://arxiv.org/abs/1509.08991) |
|
|
87
|
+
| `gen_tiles1` | GenTiles1 UPB generalizing Tiles to d⊗d, even d≥4 | [quant-ph/9908070](https://arxiv.org/abs/quant-ph/9908070) |
|
|
88
|
+
|
|
89
|
+
### `cm_otimes_cn` — C^m ⊗ C^n (parametric constructions)
|
|
90
|
+
|
|
91
|
+
| Factory | State | Reference |
|
|
92
|
+
|---|---|---|
|
|
93
|
+
| `grid_state` | Quantum grid states from graph edges | [1705.09261](https://arxiv.org/abs/1705.09261) |
|
|
94
|
+
| `generalized_grid_state` | Grid states generalized to hyperedges | [2402.12966](https://arxiv.org/abs/2402.12966) |
|
|
95
|
+
| `random_NPT`, `random_PPT`, `random_PPT_close_to_the_PPT_edge` | Random density matrices by PPT class (rejection sampling) | — |
|
|
96
|
+
| `gen_tiles2` | GenTiles2 UPB generalizing Tiles to m⊗n, n>3, m≥3, n≥m | [quant-ph/9908070](https://arxiv.org/abs/quant-ph/9908070) |
|
|
97
|
+
|
|
98
|
+
|
|
99
|
+
## Documentation
|
|
100
|
+
|
|
101
|
+
Full API docs (built with [MkDocs](https://www.mkdocs.org/) +
|
|
102
|
+
[mkdocstrings](https://mkdocstrings.github.io/)) are published to GitHub Pages
|
|
103
|
+
on every push to `main`. To preview locally:
|
|
104
|
+
|
|
105
|
+
```bash
|
|
106
|
+
pip install -e ".[docs]"
|
|
107
|
+
mkdocs serve
|
|
108
|
+
```
|
|
109
|
+
|
|
110
|
+
## License
|
|
111
|
+
|
|
112
|
+
MIT
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
bound_entangled-0.1.0.dist-info/licenses/LICENSE,sha256=3aSIAWubi-IapGuDdpfZdzLZRr17TkXoHjqP-BvHSRI,1075
|
|
2
|
+
c3_otimes_c3/__init__.py,sha256=kWt_O5UZF8saDQhglGO1wBxZ7_2xXo4Kd01cBW8j71w,380
|
|
3
|
+
c3_otimes_c3/chessboard.py,sha256=l3vS8NUk-eiTRdAiZOyJ_G4VUpYgxmsZ31x4A-tBLLw,1681
|
|
4
|
+
c3_otimes_c3/cross_hatch.py,sha256=097zRRe6YcBBbPGJl_99xt0Ym32ZI4Cx0Q5FbEMt3No,595
|
|
5
|
+
c3_otimes_c3/horodecki.py,sha256=pBa7ml534dOGk08IBCs66-dnqBluVb5eO1Ngyq0_czA,793
|
|
6
|
+
c3_otimes_c3/steering.py,sha256=gCFpWS1zG3l5ANYemGwW9SqrdA8PkW4dQKAcHdv3IYs,1588
|
|
7
|
+
c3_otimes_c3/upb/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
8
|
+
c3_otimes_c3/upb/parametrized_UPB.py,sha256=rs1BoTITomDv-X4sOvH48n77IwDTQmVNvkvM-dVf_9c,4435
|
|
9
|
+
c3_otimes_c3/upb/pyramid_UPB.py,sha256=Ba8KCGa5hDUHG3eYNrdRpFU1djJco1s9yrcUpA78nhA,1144
|
|
10
|
+
c3_otimes_c3/upb/tiles_UPB.py,sha256=Mu0r5TpxyDTILAJoTxBm7sYU4zFZ_hoDzxiU3_Si3N0,610
|
|
11
|
+
c4_otimes_c4/__init__.py,sha256=2medfp224azI35nMwsRDFHH0uP8cNnXT5J9TfNvF9IA,39
|
|
12
|
+
c4_otimes_c4/pianni.py,sha256=P8p5u6bk0Uz3nPWkkTbq1mPqmLBMaev0lQ0Z-_S_cHg,1512
|
|
13
|
+
c5_otimes_c5/__init__.py,sha256=2Wf2yfbMM98BgXxUcEvf6jFrCWXZ_VLtwAIJw0eaixc,55
|
|
14
|
+
c5_otimes_c5/sn3_grid_state.py,sha256=NZ4tShUBg-_5Bg60ov2UVsF1ZddZ-c8hYjfPygcSMYU,945
|
|
15
|
+
cd_otimes_cd/__init__.py,sha256=fLSu2xyR619EHtPb2SqPp5JtjRwBtYIIhkls7IDzhvc,105
|
|
16
|
+
cd_otimes_cd/gen_tiles.py,sha256=84ecdzoxKZNXonIh_bW5bPVVcse0jzFL-NW528qgE4A,2507
|
|
17
|
+
cd_otimes_cd/yu_oh.py,sha256=HeyB5LsGgV-Ok961F5O2utY5oJ_lXSwVmS1NB6xUw9I,4043
|
|
18
|
+
cm_otimes_cn/__init__.py,sha256=53-rTyfj6SrIIT2MJaxqvkzj-31RnMmTG4VfKbHdX3U,273
|
|
19
|
+
cm_otimes_cn/gen_tiles.py,sha256=UL8lGq78rXdBGb3S7rC0GHqpm8H6QdsBGKsA7X9wKqw,2906
|
|
20
|
+
cm_otimes_cn/generalized_grid_state.py,sha256=vLcQUX-V6XPZnN5YCsY1DdKUNumaJWnASMs_tSEfHsA,1113
|
|
21
|
+
cm_otimes_cn/grid_state.py,sha256=i2ETuwblBtGM8BGdVn3K9VMxTambJdFJdOn8h264-gE,1202
|
|
22
|
+
cm_otimes_cn/random_not_bound_entangled.py,sha256=bk6e07wqK91CcpkWCN9GLsb1yovcQWY6w6V1liUswEc,1869
|
|
23
|
+
utils/__init__.py,sha256=lclnRF8GVRvHnZRot-razEy066ZGWWZ-FJQSw-QSc1U,58
|
|
24
|
+
utils/ketbra.py,sha256=NShTAaBzEBfOV3lPGUgWB_wiMXmcSG244luNLNGYj1o,314
|
|
25
|
+
utils/upb.py,sha256=09iR5tCah4M1fIojt6335344es9L8LuomrL0kwFSkAs,1042
|
|
26
|
+
bound_entangled-0.1.0.dist-info/METADATA,sha256=atDL_Hbo7vSPbjKvvyBSIOGZddPaLMSpg8wOBU2U70s,4316
|
|
27
|
+
bound_entangled-0.1.0.dist-info/WHEEL,sha256=K260EYznzXsJYBQGqmI8VTxEdiZYNvDZwW9cBh9-_MA,91
|
|
28
|
+
bound_entangled-0.1.0.dist-info/top_level.txt,sha256=r2aBXhUrfTe3MEuDk5Ruz0ISX4dOiUnJdzVh1Att52Y,71
|
|
29
|
+
bound_entangled-0.1.0.dist-info/RECORD,,
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 Anton Van Cleemput
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
c3_otimes_c3/__init__.py
ADDED
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
from c3_otimes_c3.chessboard import chessboard, chessboard_extremal_PPT
|
|
2
|
+
from c3_otimes_c3.cross_hatch import cross_hatch
|
|
3
|
+
from c3_otimes_c3.steering import steering_state
|
|
4
|
+
from c3_otimes_c3.upb.tiles_UPB import tiles_upb
|
|
5
|
+
from c3_otimes_c3.upb.pyramid_UPB import pyramid_upb
|
|
6
|
+
from c3_otimes_c3.upb.parametrized_UPB import parametrized_upb
|
|
7
|
+
from c3_otimes_c3.horodecki import horodecki
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
"""https://arxiv.org/abs/quant-ph/9911056
|
|
2
|
+
|
|
3
|
+
D. Bruß, A. Peres, "Construction of quantum states with bound entanglement",
|
|
4
|
+
Phys. Rev. A 61, 030301(R) (2000). Named "chessboard states" because their
|
|
5
|
+
8x8 matrix form looks like a chessboard (see also
|
|
6
|
+
https://arxiv.org/abs/2010.08372, Appendix C2).
|
|
7
|
+
"""
|
|
8
|
+
|
|
9
|
+
from toqito.states import chessboard as chessboard_toqito
|
|
10
|
+
from typing import Optional
|
|
11
|
+
import numpy as np
|
|
12
|
+
|
|
13
|
+
|
|
14
|
+
def chessboard(
|
|
15
|
+
a: complex, b: complex, c: complex, d: complex, m: complex, n: complex, s: Optional[complex] = None, t: Optional[complex] = None
|
|
16
|
+
) -> np.ndarray:
|
|
17
|
+
"""A chessboard state.
|
|
18
|
+
|
|
19
|
+
Args:
|
|
20
|
+
a: free real parameter.
|
|
21
|
+
b: free real parameter.
|
|
22
|
+
c: free real parameter.
|
|
23
|
+
d: free real parameter.
|
|
24
|
+
m: free real parameter.
|
|
25
|
+
n: free real parameter.
|
|
26
|
+
s: defaults to c/n if None.
|
|
27
|
+
t: defaults to a*d/m if None.
|
|
28
|
+
|
|
29
|
+
Returns:
|
|
30
|
+
np.ndarray: a chessboard quantum state.
|
|
31
|
+
"""
|
|
32
|
+
return chessboard_toqito([a, b, c, d, m, n], s, t) # type: ignore
|
|
33
|
+
|
|
34
|
+
|
|
35
|
+
def chessboard_extremal_PPT() -> np.ndarray:
|
|
36
|
+
"""Extremal PPT chessboard state.
|
|
37
|
+
|
|
38
|
+
The state from the chessboard family with m = n = b = -3/5, a = 3/5,
|
|
39
|
+
c = -d = 6/5, shown to be an extremal point of the PPT-entangled states
|
|
40
|
+
in https://arxiv.org/abs/2010.08372 (Fig. 2 / Fig. 9, page 25).
|
|
41
|
+
|
|
42
|
+
Returns:
|
|
43
|
+
np.ndarray: the extremal PPT chessboard state.
|
|
44
|
+
"""
|
|
45
|
+
return chessboard(
|
|
46
|
+
# m = n = b = -3/5
|
|
47
|
+
m=-3 / 5,
|
|
48
|
+
n=-3 / 5,
|
|
49
|
+
b=-3 / 5,
|
|
50
|
+
# a = 3/5
|
|
51
|
+
a=3 / 5,
|
|
52
|
+
# c = -d = 6/5
|
|
53
|
+
c=6 / 5,
|
|
54
|
+
d=-6 / 5,
|
|
55
|
+
s=(3 / 5) * (6 / 5) / (-3 / 5),
|
|
56
|
+
t=(3 / 5) * (-6 / 5) / (-3 / 5),
|
|
57
|
+
)
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
"""https://arxiv.org/abs/1705.09261
|
|
2
|
+
|
|
3
|
+
J. Lockhart, O. Gühne, S. Severini, "Entanglement properties of quantum grid
|
|
4
|
+
states", Phys. Rev. A 97, 062340 (2018).
|
|
5
|
+
"""
|
|
6
|
+
|
|
7
|
+
from cm_otimes_cn.grid_state import grid_state
|
|
8
|
+
|
|
9
|
+
|
|
10
|
+
def cross_hatch():
|
|
11
|
+
"""The 3x3 "cross-hatch" grid state.
|
|
12
|
+
|
|
13
|
+
A bound entangled example of a quantum grid state, detected by the CCNR
|
|
14
|
+
(realignment) criterion.
|
|
15
|
+
|
|
16
|
+
Returns:
|
|
17
|
+
np.ndarray: the cross-hatch grid state.
|
|
18
|
+
"""
|
|
19
|
+
return grid_state(
|
|
20
|
+
(3, 3),
|
|
21
|
+
((0, 0), (1, 2)),
|
|
22
|
+
((1, 0), (2, 2)),
|
|
23
|
+
((0, 1), (2, 0)),
|
|
24
|
+
((0, 2), (2, 1)),
|
|
25
|
+
)
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
"""https://arxiv.org/abs/quant-ph/9703004
|
|
2
|
+
|
|
3
|
+
P. Horodecki, "Separability criterion and inseparable mixed states with
|
|
4
|
+
positive partial transposition", Phys. Lett. A 232, 333 (1997), Section 4.1.
|
|
5
|
+
One of the first known families of bound entangled states: PPT for every
|
|
6
|
+
a_param in [0, 1], separable only at the endpoints a_param = 0 or 1.
|
|
7
|
+
"""
|
|
8
|
+
|
|
9
|
+
from toqito.states import horodecki as horodecki_toqito
|
|
10
|
+
import numpy as np
|
|
11
|
+
|
|
12
|
+
|
|
13
|
+
def horodecki(a_param: float) -> np.ndarray:
|
|
14
|
+
"""The 3x3 Horodecki state.
|
|
15
|
+
|
|
16
|
+
Args:
|
|
17
|
+
a_param: free real parameter in [0, 1]. The state is PPT for every
|
|
18
|
+
value in this range, and separable only at a_param = 0 or 1.
|
|
19
|
+
|
|
20
|
+
Returns:
|
|
21
|
+
np.ndarray: the 3x3 Horodecki density matrix.
|
|
22
|
+
"""
|
|
23
|
+
return horodecki_toqito(a_param, dim=[3, 3]) # type: ignore
|
c3_otimes_c3/steering.py
ADDED
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
"""https://arxiv.org/abs/1405.0262
|
|
2
|
+
|
|
3
|
+
T. Moroder, O. Gittsovich, M. Huber, O. Gühne, "Steering Bound Entangled
|
|
4
|
+
States: A Counterexample to the Stronger Peres Conjecture", Phys. Rev. Lett.
|
|
5
|
+
113, 050404 (2014).
|
|
6
|
+
"""
|
|
7
|
+
|
|
8
|
+
import numpy as np
|
|
9
|
+
from math import sqrt
|
|
10
|
+
from utils import ketbra
|
|
11
|
+
|
|
12
|
+
|
|
13
|
+
def steering_state(m1: float, m2: float) -> np.ndarray:
|
|
14
|
+
"""A 3x3 bound entangled state that is steerable, parametrized by m1, m2.
|
|
15
|
+
|
|
16
|
+
Counterexample to the (stronger) Peres conjecture that bound entangled
|
|
17
|
+
states cannot be used to demonstrate EPR steering.
|
|
18
|
+
|
|
19
|
+
Args:
|
|
20
|
+
m1: first free real parameter.
|
|
21
|
+
m2: second free real parameter (with m1**2 + m2**2 <= 1).
|
|
22
|
+
|
|
23
|
+
Returns:
|
|
24
|
+
np.ndarray: the steerable bound entangled state.
|
|
25
|
+
"""
|
|
26
|
+
m3 = sqrt((1 - m1**2 - m2**2) / 2)
|
|
27
|
+
|
|
28
|
+
psi_1 = np.zeros(9, dtype=np.float64)
|
|
29
|
+
psi_2 = np.zeros(9, dtype=np.float64)
|
|
30
|
+
psi_3 = np.zeros(9, dtype=np.float64)
|
|
31
|
+
psi_t_3 = np.zeros(9, dtype=np.float64)
|
|
32
|
+
|
|
33
|
+
psi_1[1 * 3 + 2], psi_1[2 * 3 + 1] = 1 / sqrt(2), 1 / sqrt(2)
|
|
34
|
+
psi_2[0], psi_2[1 * 3 + 1], psi_2[2 * 3 + 2] = 1 / sqrt(3), 1 / sqrt(3), -1 / sqrt(3)
|
|
35
|
+
psi_3[1], psi_3[1 * 3], psi_3[1 * 3 + 1], psi_3[2 * 3 + 2] = m1, m2, m3, m3
|
|
36
|
+
psi_t_3[2], psi_t_3[2 * 3], psi_t_3[2 * 3 + 1], psi_t_3[1 * 3 + 2] = m1, -m2, m3, -m3
|
|
37
|
+
|
|
38
|
+
lambda1 = 1 - (2 + 3 * m1 * m2) / (4 - 2 * m1**2 + m1 * m2 - 2 * m2**2)
|
|
39
|
+
lambda3 = 1 / (4 - 2 * m1**2 + m1 * m2 - 2 * m2**2)
|
|
40
|
+
lambda2 = 1 - lambda1 - 2 * lambda3
|
|
41
|
+
|
|
42
|
+
return lambda1 * ketbra(psi_1, psi_1) + lambda2 * ketbra(psi_2, psi_2) + lambda3 * (ketbra(psi_3, psi_3) + ketbra(psi_t_3, psi_t_3))
|
|
File without changes
|
|
@@ -0,0 +1,159 @@
|
|
|
1
|
+
"""https://arxiv.org/abs/quant-ph/9908070
|
|
2
|
+
|
|
3
|
+
D. P. DiVincenzo, T. Mor, P. W. Shor, J. A. Smolin, B. M. Terhal,
|
|
4
|
+
"Unextendible Product Bases, Uncompletable Product Bases and Bound
|
|
5
|
+
Entanglement", Commun. Math. Phys. 238, 379 (2003), Section IV A. A
|
|
6
|
+
six-parameter family of unextendible product bases on C^3 (x) C^3 that
|
|
7
|
+
contains the Pyramid and Tiles UPBs (`pyramid_upb`, `tiles_upb`) as special
|
|
8
|
+
cases.
|
|
9
|
+
"""
|
|
10
|
+
|
|
11
|
+
from math import cos, sin, sqrt
|
|
12
|
+
|
|
13
|
+
import numpy as np
|
|
14
|
+
from utils import upb
|
|
15
|
+
|
|
16
|
+
|
|
17
|
+
def parametrized_basis(
|
|
18
|
+
gamma_a: float,
|
|
19
|
+
teta_a: float,
|
|
20
|
+
phi_a: float,
|
|
21
|
+
gamma_b: float,
|
|
22
|
+
teta_b: float,
|
|
23
|
+
phi_b: float,
|
|
24
|
+
) -> list[np.ndarray]:
|
|
25
|
+
"""The five product vectors of the six-parameter family of UPBs on C^3 (x) C^3.
|
|
26
|
+
|
|
27
|
+
Reduces to the Pyramid UPB for phi_a = phi_b = 0 and teta_a = teta_b =
|
|
28
|
+
gamma_a = gamma_b = arccos((sqrt(5) - 1) / 2), and to the Tiles UPB for
|
|
29
|
+
phi_a = phi_b = 0 and teta_a = teta_b = gamma_a = gamma_b = 3*pi/4.
|
|
30
|
+
|
|
31
|
+
Args:
|
|
32
|
+
gamma_a: Alice's gamma angle. Requires cos(gamma_a) != 0 and
|
|
33
|
+
sin(gamma_a) != 0 for the basis to be unextendible.
|
|
34
|
+
teta_a: Alice's theta angle. Requires cos(teta_a) != 0 and
|
|
35
|
+
sin(teta_a) != 0 for the basis to be unextendible.
|
|
36
|
+
phi_a: Alice's phase angle.
|
|
37
|
+
gamma_b: Bob's gamma angle, subject to the same restriction as gamma_a.
|
|
38
|
+
teta_b: Bob's theta angle, subject to the same restriction as teta_a.
|
|
39
|
+
phi_b: Bob's phase angle.
|
|
40
|
+
|
|
41
|
+
Returns:
|
|
42
|
+
list[np.ndarray]: the five normalized product vectors |a_i> (x) |b_i>
|
|
43
|
+
forming the unextendible product basis, as column vectors.
|
|
44
|
+
"""
|
|
45
|
+
N_a = sqrt(cos(gamma_a) ** 2 + sin(gamma_a) ** 2 * cos(teta_a) ** 2)
|
|
46
|
+
N_b = sqrt(cos(gamma_b) ** 2 + sin(gamma_b) ** 2 * cos(teta_b) ** 2)
|
|
47
|
+
|
|
48
|
+
a_0 = np.array(
|
|
49
|
+
[
|
|
50
|
+
1,
|
|
51
|
+
0,
|
|
52
|
+
0,
|
|
53
|
+
],
|
|
54
|
+
dtype=np.complex128,
|
|
55
|
+
)
|
|
56
|
+
a_1 = np.array(
|
|
57
|
+
[
|
|
58
|
+
0,
|
|
59
|
+
1,
|
|
60
|
+
0,
|
|
61
|
+
],
|
|
62
|
+
dtype=np.complex128,
|
|
63
|
+
)
|
|
64
|
+
a_2 = np.array(
|
|
65
|
+
[
|
|
66
|
+
cos(teta_a),
|
|
67
|
+
0,
|
|
68
|
+
sin(teta_a),
|
|
69
|
+
],
|
|
70
|
+
dtype=np.complex128,
|
|
71
|
+
)
|
|
72
|
+
a_3 = np.array(
|
|
73
|
+
[
|
|
74
|
+
sin(gamma_a) * sin(teta_a),
|
|
75
|
+
cos(gamma_a) * np.exp(1j * phi_a),
|
|
76
|
+
-sin(gamma_a) * cos(teta_a),
|
|
77
|
+
],
|
|
78
|
+
dtype=np.complex128,
|
|
79
|
+
)
|
|
80
|
+
a_4 = np.array(
|
|
81
|
+
[
|
|
82
|
+
0,
|
|
83
|
+
sin(gamma_a) * cos(teta_a) * np.exp(1j * phi_a) / N_a,
|
|
84
|
+
cos(gamma_a) / N_a,
|
|
85
|
+
],
|
|
86
|
+
dtype=np.complex128,
|
|
87
|
+
)
|
|
88
|
+
|
|
89
|
+
b_0 = np.array(
|
|
90
|
+
[
|
|
91
|
+
0,
|
|
92
|
+
1,
|
|
93
|
+
0,
|
|
94
|
+
],
|
|
95
|
+
dtype=np.complex128,
|
|
96
|
+
)
|
|
97
|
+
b_1 = np.array(
|
|
98
|
+
[
|
|
99
|
+
sin(gamma_b) * sin(teta_b),
|
|
100
|
+
cos(gamma_b) * np.exp(1j * phi_b),
|
|
101
|
+
-sin(gamma_b) * cos(teta_b),
|
|
102
|
+
],
|
|
103
|
+
dtype=np.complex128,
|
|
104
|
+
)
|
|
105
|
+
b_2 = np.array(
|
|
106
|
+
[
|
|
107
|
+
1,
|
|
108
|
+
0,
|
|
109
|
+
0,
|
|
110
|
+
],
|
|
111
|
+
dtype=np.complex128,
|
|
112
|
+
)
|
|
113
|
+
b_3 = np.array(
|
|
114
|
+
[
|
|
115
|
+
cos(teta_b),
|
|
116
|
+
0,
|
|
117
|
+
sin(teta_b),
|
|
118
|
+
],
|
|
119
|
+
dtype=np.complex128,
|
|
120
|
+
)
|
|
121
|
+
b_4 = np.array(
|
|
122
|
+
[
|
|
123
|
+
0,
|
|
124
|
+
sin(gamma_b) * cos(teta_b) * np.exp(1j * phi_b) / N_b,
|
|
125
|
+
cos(gamma_b) / N_b,
|
|
126
|
+
],
|
|
127
|
+
dtype=np.complex128,
|
|
128
|
+
)
|
|
129
|
+
|
|
130
|
+
alice = [a_0, a_1, a_2, a_3, a_4]
|
|
131
|
+
bob = [b_0, b_1, b_2, b_3, b_4]
|
|
132
|
+
return [np.kron(a, b).reshape(-1, 1) for a, b in zip(alice, bob)]
|
|
133
|
+
|
|
134
|
+
|
|
135
|
+
def parametrized_upb(
|
|
136
|
+
gamma_a: float,
|
|
137
|
+
teta_a: float,
|
|
138
|
+
phi_a: float,
|
|
139
|
+
gamma_b: float,
|
|
140
|
+
teta_b: float,
|
|
141
|
+
phi_b: float,
|
|
142
|
+
) -> np.ndarray:
|
|
143
|
+
"""The bound entangled state built from the six-parameter family of UPBs.
|
|
144
|
+
|
|
145
|
+
Args:
|
|
146
|
+
gamma_a: Alice's gamma angle. Requires cos(gamma_a) != 0 and
|
|
147
|
+
sin(gamma_a) != 0 for the basis to be unextendible.
|
|
148
|
+
teta_a: Alice's theta angle. Requires cos(teta_a) != 0 and
|
|
149
|
+
sin(teta_a) != 0 for the basis to be unextendible.
|
|
150
|
+
phi_a: Alice's phase angle.
|
|
151
|
+
gamma_b: Bob's gamma angle, subject to the same restriction as gamma_a.
|
|
152
|
+
teta_b: Bob's theta angle, subject to the same restriction as teta_a.
|
|
153
|
+
phi_b: Bob's phase angle.
|
|
154
|
+
|
|
155
|
+
Returns:
|
|
156
|
+
np.ndarray: the bound entangled state on the orthogonal complement of
|
|
157
|
+
the parametrized unextendible product basis.
|
|
158
|
+
"""
|
|
159
|
+
return upb(parametrized_basis(gamma_a, teta_a, phi_a, gamma_b, teta_b, phi_b))
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
"""https://arxiv.org/abs/quant-ph/9808030
|
|
2
|
+
|
|
3
|
+
C. H. Bennett, D. P. DiVincenzo, T. Mor, P. W. Shor, J. A. Smolin, B. M.
|
|
4
|
+
Terhal, "Unextendible Product Bases and Bound Entanglement", Phys. Rev. Lett.
|
|
5
|
+
82, 5385 (1999).
|
|
6
|
+
"""
|
|
7
|
+
|
|
8
|
+
import numpy as np
|
|
9
|
+
from utils import upb
|
|
10
|
+
|
|
11
|
+
|
|
12
|
+
def pyramid_basis() -> list[np.ndarray]:
|
|
13
|
+
"""The five product vectors of the "Pyramid" UPB on C^3 (x) C^3.
|
|
14
|
+
|
|
15
|
+
Returns:
|
|
16
|
+
list[np.ndarray]: the five normalized product vectors forming the
|
|
17
|
+
Pyramid unextendible product basis, as column vectors.
|
|
18
|
+
"""
|
|
19
|
+
h = 0.5 * np.sqrt(1 + np.sqrt(5))
|
|
20
|
+
vecs = []
|
|
21
|
+
for j in range(5):
|
|
22
|
+
a = np.array([np.cos(2 * np.pi * j / 5), np.sin(2 * np.pi * j / 5), h])
|
|
23
|
+
b = np.array([np.cos(4 * np.pi * j / 5), np.sin(4 * np.pi * j / 5), h])
|
|
24
|
+
a /= np.linalg.norm(a)
|
|
25
|
+
b /= np.linalg.norm(b)
|
|
26
|
+
vecs.append(np.kron(a, b).reshape(-1, 1))
|
|
27
|
+
return vecs
|
|
28
|
+
|
|
29
|
+
|
|
30
|
+
def pyramid_upb() -> np.ndarray:
|
|
31
|
+
"""The bound entangled state built from the Pyramid UPB.
|
|
32
|
+
|
|
33
|
+
Returns:
|
|
34
|
+
np.ndarray: the bound entangled state on the orthogonal complement of
|
|
35
|
+
the Pyramid UPB.
|
|
36
|
+
"""
|
|
37
|
+
return upb(pyramid_basis())
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
"""https://arxiv.org/abs/quant-ph/9808030
|
|
2
|
+
|
|
3
|
+
C. H. Bennett, D. P. DiVincenzo, T. Mor, P. W. Shor, J. A. Smolin, B. M.
|
|
4
|
+
Terhal, "Unextendible Product Bases and Bound Entanglement", Phys. Rev. Lett.
|
|
5
|
+
82, 5385 (1999).
|
|
6
|
+
"""
|
|
7
|
+
|
|
8
|
+
import numpy as np
|
|
9
|
+
from toqito.states import tile
|
|
10
|
+
from utils import upb
|
|
11
|
+
|
|
12
|
+
|
|
13
|
+
def tiles_upb() -> np.ndarray:
|
|
14
|
+
"""The bound entangled state built from the "Tiles" UPB on C^3 (x) C^3.
|
|
15
|
+
|
|
16
|
+
Returns:
|
|
17
|
+
np.ndarray: the bound entangled state on the orthogonal complement of
|
|
18
|
+
the Tiles unextendible product basis (`toqito.states.tile`).
|
|
19
|
+
"""
|
|
20
|
+
return upb([tile(i) for i in range(5)])
|
c4_otimes_c4/__init__.py
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
from c4_otimes_c4.pianni import pianni
|
c4_otimes_c4/pianni.py
ADDED
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
"""https://arxiv.org/abs/quant-ph/0411095
|
|
2
|
+
|
|
3
|
+
F. Benatti, R. Floreanini, M. Piani, "Non-decomposable quantum dynamical
|
|
4
|
+
semigroups and bound entangled states", Open Syst. Inf. Dyn. 11, 325 (2004).
|
|
5
|
+
|
|
6
|
+
Also presented as "the 4x4 bound entangled Piani state" in
|
|
7
|
+
https://arxiv.org/abs/2010.08372 (Appendix C5).
|
|
8
|
+
"""
|
|
9
|
+
|
|
10
|
+
from toqito.matrices import pauli
|
|
11
|
+
from toqito.states import max_entangled
|
|
12
|
+
from toqito.perms import permute_systems
|
|
13
|
+
import numpy as np
|
|
14
|
+
from utils import ketbra
|
|
15
|
+
|
|
16
|
+
|
|
17
|
+
def P_ij(i: int, j: int):
|
|
18
|
+
"""The projector onto the generalized Bell state |Psi_ij> = (1 (x) sigma_i (x) sigma_j)|Psi_4^+>.
|
|
19
|
+
|
|
20
|
+
Args:
|
|
21
|
+
i: index of the first Pauli matrix (0..3).
|
|
22
|
+
j: index of the second Pauli matrix (0..3).
|
|
23
|
+
|
|
24
|
+
Returns:
|
|
25
|
+
np.ndarray: the rank-1 projector P_ij on C^4 (x) C^4.
|
|
26
|
+
"""
|
|
27
|
+
sigma_ij = np.kron(np.identity(4), np.kron(pauli(i), pauli(j))) # type: ignore
|
|
28
|
+
ket_ij = sigma_ij @ max_entangled(4)
|
|
29
|
+
return ketbra(ket_ij, ket_ij)
|
|
30
|
+
|
|
31
|
+
|
|
32
|
+
def pianni():
|
|
33
|
+
"""The 4x4 bound entangled "Piani" state.
|
|
34
|
+
|
|
35
|
+
Uniform mixture of the six projections P_ij for (i, j) in
|
|
36
|
+
{(0,2), (1,1), (2,3), (3,1), (3,2), (3,3)}, indecomposable and PPT under
|
|
37
|
+
the bipartition AA'|BB' after regrouping the four underlying qubits.
|
|
38
|
+
|
|
39
|
+
Returns:
|
|
40
|
+
np.ndarray: the 16x16 bound entangled density matrix.
|
|
41
|
+
"""
|
|
42
|
+
rho = np.zeros((16, 16), dtype=np.complex128)
|
|
43
|
+
for i, j in [(0, 2), (1, 1), (2, 3), (3, 1), (3, 2), (3, 3)]:
|
|
44
|
+
rho += P_ij(i, j)
|
|
45
|
+
rho /= 6
|
|
46
|
+
return permute_systems(rho, [0, 2, 1, 3])
|
c5_otimes_c5/__init__.py
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
from c5_otimes_c5.sn3_grid_state import sn3_grid_state
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
"""https://arxiv.org/abs/2402.12966
|
|
2
|
+
|
|
3
|
+
R. Krebs, M. Gachechiladze, "High Schmidt number concentration in quantum
|
|
4
|
+
bound entangled states", Result 1 / Appendix B: the smallest known Schmidt
|
|
5
|
+
number 3 (hence "SN3") PPT bound entangled state, in local dimension 5x5.
|
|
6
|
+
"""
|
|
7
|
+
|
|
8
|
+
from cm_otimes_cn.generalized_grid_state import generalized_grid_state
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
def sn3_grid_state():
|
|
12
|
+
"""The smallest known Schmidt number 3 PPT bound entangled state, in 5x5.
|
|
13
|
+
|
|
14
|
+
Returns:
|
|
15
|
+
np.ndarray: the Schmidt number 3 (SN3) generalized grid state rho_5,5.
|
|
16
|
+
"""
|
|
17
|
+
return generalized_grid_state(
|
|
18
|
+
(5, 5),
|
|
19
|
+
# loops
|
|
20
|
+
[(0, 0)],
|
|
21
|
+
[(1, 0)],
|
|
22
|
+
[(0, 1)],
|
|
23
|
+
[(4, 1)],
|
|
24
|
+
[(1, 4)],
|
|
25
|
+
# double loops
|
|
26
|
+
[(3, 2)],
|
|
27
|
+
[(2, 3)],
|
|
28
|
+
[(3, 2)],
|
|
29
|
+
[(2, 3)],
|
|
30
|
+
# edges
|
|
31
|
+
[(1, 2), (3, 4)],
|
|
32
|
+
[(2, 1), (4, 3)],
|
|
33
|
+
[(2, 2), (3, 3)],
|
|
34
|
+
# hyperedge
|
|
35
|
+
[(0, 2), (1, 1), (2, 0)],
|
|
36
|
+
)
|
cd_otimes_cd/__init__.py
ADDED
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
"""https://arxiv.org/abs/quant-ph/9908070
|
|
2
|
+
|
|
3
|
+
D. P. DiVincenzo, T. Mor, P. W. Shor, J. A. Smolin, B. M. Terhal,
|
|
4
|
+
"Unextendible Product Bases, Uncompletable Product Bases and Bound
|
|
5
|
+
Entanglement", Commun. Math. Phys. 238, 379 (2003), Section V B, Theorem 5. A
|
|
6
|
+
"tile" construction generalizing the Tiles UPB (`c3_otimes_c3.tiles_upb`) to
|
|
7
|
+
arbitrary even dimension.
|
|
8
|
+
"""
|
|
9
|
+
|
|
10
|
+
import numpy as np
|
|
11
|
+
from utils import upb
|
|
12
|
+
|
|
13
|
+
|
|
14
|
+
def gen_tiles1_basis(d: int) -> list[np.ndarray]:
|
|
15
|
+
"""The product vectors of the GenTiles1 UPB on C^d (x) C^d.
|
|
16
|
+
|
|
17
|
+
Built from d/2 - 1 "vertical" and d/2 - 1 "horizontal" families of tile
|
|
18
|
+
states (Eqs. 5.4-5.5) plus a "stopper" state (Eq. 5.6), for a total of
|
|
19
|
+
d^2 - 2d + 1 states.
|
|
20
|
+
|
|
21
|
+
Args:
|
|
22
|
+
d: local dimension of both parties. Must be even and >= 4.
|
|
23
|
+
|
|
24
|
+
Returns:
|
|
25
|
+
list[np.ndarray]: the normalized product vectors forming the
|
|
26
|
+
GenTiles1 unextendible product basis, as column vectors.
|
|
27
|
+
"""
|
|
28
|
+
if d < 4 or d % 2 != 0:
|
|
29
|
+
raise ValueError("d must be even and >= 4")
|
|
30
|
+
|
|
31
|
+
omega = np.exp(1j * 4 * np.pi / d)
|
|
32
|
+
basis = []
|
|
33
|
+
|
|
34
|
+
for m in range(1, d // 2):
|
|
35
|
+
for k in range(d):
|
|
36
|
+
# |V_mk> = |k> (x) |omega_{m,k+1}>
|
|
37
|
+
ket_k = np.zeros(d, dtype=np.complex128)
|
|
38
|
+
ket_k[k] = 1
|
|
39
|
+
ket_omega = np.zeros(d, dtype=np.complex128)
|
|
40
|
+
for j in range(d // 2):
|
|
41
|
+
ket_omega[(j + k + 1) % d] += omega ** (j * m)
|
|
42
|
+
ket_omega /= np.linalg.norm(ket_omega)
|
|
43
|
+
basis.append(np.kron(ket_k, ket_omega).reshape(-1, 1))
|
|
44
|
+
|
|
45
|
+
for m in range(1, d // 2):
|
|
46
|
+
for k in range(d):
|
|
47
|
+
# |H_mk> = |omega_{m,k}> (x) |k>
|
|
48
|
+
ket_omega = np.zeros(d, dtype=np.complex128)
|
|
49
|
+
for j in range(d // 2):
|
|
50
|
+
ket_omega[(j + k) % d] += omega ** (j * m)
|
|
51
|
+
ket_omega /= np.linalg.norm(ket_omega)
|
|
52
|
+
ket_k = np.zeros(d, dtype=np.complex128)
|
|
53
|
+
ket_k[k] = 1
|
|
54
|
+
basis.append(np.kron(ket_omega, ket_k).reshape(-1, 1))
|
|
55
|
+
|
|
56
|
+
# |F> = sum_i sum_j |i> (x) |j>
|
|
57
|
+
stopper = np.ones(d * d, dtype=np.complex128) / d
|
|
58
|
+
basis.append(stopper.reshape(-1, 1))
|
|
59
|
+
|
|
60
|
+
return basis
|
|
61
|
+
|
|
62
|
+
|
|
63
|
+
def gen_tiles1(d: int) -> np.ndarray:
|
|
64
|
+
"""The bound entangled state built from the GenTiles1 UPB on C^d (x) C^d.
|
|
65
|
+
|
|
66
|
+
Args:
|
|
67
|
+
d: local dimension of both parties. Must be even and >= 4.
|
|
68
|
+
|
|
69
|
+
Returns:
|
|
70
|
+
np.ndarray: the bound entangled state on the orthogonal complement of
|
|
71
|
+
the GenTiles1 unextendible product basis.
|
|
72
|
+
"""
|
|
73
|
+
return upb(gen_tiles1_basis(d))
|
cd_otimes_cd/yu_oh.py
ADDED
|
@@ -0,0 +1,145 @@
|
|
|
1
|
+
"""https://arxiv.org/abs/1509.08991
|
|
2
|
+
|
|
3
|
+
S. Yu, C. H. Oh, "A family of nonlocal bound entangled states", Phys. Rev. A
|
|
4
|
+
95, 032111 (2017).
|
|
5
|
+
"""
|
|
6
|
+
|
|
7
|
+
from toqito.states import max_entangled
|
|
8
|
+
import numpy as np
|
|
9
|
+
from math import sqrt
|
|
10
|
+
from utils import ketbra
|
|
11
|
+
|
|
12
|
+
|
|
13
|
+
def psi_ij(d: int, i: int, j: int):
|
|
14
|
+
"""The antisymmetric basis vector |ij> - |ji> of C^d (x) C^d.
|
|
15
|
+
|
|
16
|
+
Args:
|
|
17
|
+
d: local dimension.
|
|
18
|
+
i: first index, 0 <= i < d.
|
|
19
|
+
j: second index, 0 <= j < d.
|
|
20
|
+
|
|
21
|
+
Returns:
|
|
22
|
+
np.ndarray: the (unnormalized) vector |ij> - |ji>.
|
|
23
|
+
"""
|
|
24
|
+
ket = np.zeros(d * d)
|
|
25
|
+
ket[i * d + j] = 1
|
|
26
|
+
ket[j * d + i] = -1
|
|
27
|
+
return ket
|
|
28
|
+
|
|
29
|
+
|
|
30
|
+
def teta_d_gen(d: int):
|
|
31
|
+
"""Generate the family of vectors {theta_p} used to build phi_k, by induction on the dimension.
|
|
32
|
+
|
|
33
|
+
Args:
|
|
34
|
+
d: local dimension.
|
|
35
|
+
|
|
36
|
+
Returns:
|
|
37
|
+
list[np.ndarray]: the d-1 vectors theta_p in C^d.
|
|
38
|
+
"""
|
|
39
|
+
Teta_d = [
|
|
40
|
+
np.array([0.0, 1.0] + [0.0] * (d - 2)),
|
|
41
|
+
np.array([0.0, -1.0] + [0.0] * (d - 2)),
|
|
42
|
+
]
|
|
43
|
+
for di in range(3, d + 1):
|
|
44
|
+
ket_dm1 = np.zeros(d, dtype=np.float64)
|
|
45
|
+
ket_dm1[di - 1] = 1.0
|
|
46
|
+
sqrtddm2 = sqrt(di * (di - 2))
|
|
47
|
+
Teta_d_new = [(sqrtddm2 * teta_p - ket_dm1) / (di - 1) for teta_p in Teta_d]
|
|
48
|
+
Teta_d = Teta_d_new + [ket_dm1]
|
|
49
|
+
return Teta_d
|
|
50
|
+
|
|
51
|
+
|
|
52
|
+
def phi_k(d: int, k: int):
|
|
53
|
+
"""Helper vector phi_k used in the construction of the Yu-Oh state.
|
|
54
|
+
|
|
55
|
+
Args:
|
|
56
|
+
d: local dimension.
|
|
57
|
+
k: index, 1 <= k < d.
|
|
58
|
+
|
|
59
|
+
Returns:
|
|
60
|
+
np.ndarray: the vector phi_k in C^d (x) C^d.
|
|
61
|
+
"""
|
|
62
|
+
ret = np.zeros(d**2, dtype=np.float64)
|
|
63
|
+
for teta_p in teta_d_gen(d):
|
|
64
|
+
innerprod = teta_p[k]
|
|
65
|
+
ret += np.kron(teta_p, teta_p) * innerprod
|
|
66
|
+
ret *= ((d - 1) ** (3 / 2)) / (d * sqrt(d - 2))
|
|
67
|
+
return ret
|
|
68
|
+
|
|
69
|
+
|
|
70
|
+
def psi_k(d: int, k: int, x: float, y: float, z: float):
|
|
71
|
+
"""Helper vector psi_k used in the construction of the Yu-Oh state.
|
|
72
|
+
|
|
73
|
+
Args:
|
|
74
|
+
d: local dimension.
|
|
75
|
+
k: index, 1 <= k < d.
|
|
76
|
+
x: first free parameter of the Yu-Oh state.
|
|
77
|
+
y: second free parameter of the Yu-Oh state.
|
|
78
|
+
z: sqrt(1 - x**2 - y**2).
|
|
79
|
+
|
|
80
|
+
Returns:
|
|
81
|
+
np.ndarray: the vector psi_k in C^d (x) C^d.
|
|
82
|
+
"""
|
|
83
|
+
ret: np.ndarray = np.zeros(d**2)
|
|
84
|
+
ret[k] = x
|
|
85
|
+
ret[k * d] = y
|
|
86
|
+
ret += z * phi_k(d, k)
|
|
87
|
+
return ret
|
|
88
|
+
|
|
89
|
+
|
|
90
|
+
def yu_oh(d: int, x: float, y: float):
|
|
91
|
+
"""The Yu-Oh nonlocal bound entangled state, for local dimension d >= 3.
|
|
92
|
+
|
|
93
|
+
A family of PPT entangled states in C^d (x) C^d, parametrized by (x, y),
|
|
94
|
+
that violate a Bell inequality (hence are nonlocal despite being bound
|
|
95
|
+
entangled). See `is_valid_yu_oh_input` for the validity domain of (x, y).
|
|
96
|
+
|
|
97
|
+
Args:
|
|
98
|
+
d: local dimension, d >= 3.
|
|
99
|
+
x: first free parameter.
|
|
100
|
+
y: second free parameter.
|
|
101
|
+
|
|
102
|
+
Returns:
|
|
103
|
+
np.ndarray: the Yu-Oh bound entangled state.
|
|
104
|
+
"""
|
|
105
|
+
assert is_valid_yu_oh_input(d, x, y)
|
|
106
|
+
z = sqrt(1 - x**2 - y**2)
|
|
107
|
+
delta = z**2 / (d - 2) - x * y
|
|
108
|
+
R = d * x * y + (d - 1) * (d - 2) * delta + d - 1
|
|
109
|
+
|
|
110
|
+
max_ent_ket: np.ndarray = max_entangled(d) * sqrt(d) # type: ignore
|
|
111
|
+
ret = x * y / R * ketbra(max_ent_ket, max_ent_ket)
|
|
112
|
+
|
|
113
|
+
psi_ij_sum = np.zeros((d**2, d**2))
|
|
114
|
+
for j in range(1, d - 1):
|
|
115
|
+
for i in range(j + 1, d):
|
|
116
|
+
psi_ij_val = psi_ij(d, i, j)
|
|
117
|
+
psi_ij_sum += ketbra(psi_ij_val, psi_ij_val)
|
|
118
|
+
ret += delta / R * psi_ij_sum
|
|
119
|
+
|
|
120
|
+
psi_k_sum = np.zeros((d**2, d**2))
|
|
121
|
+
for k in range(1, d):
|
|
122
|
+
psi_k_val = psi_k(d, k, x, y, z)
|
|
123
|
+
psi_k_sum += ketbra(psi_k_val, psi_k_val)
|
|
124
|
+
ret += psi_k_sum / R
|
|
125
|
+
return ret
|
|
126
|
+
|
|
127
|
+
|
|
128
|
+
def is_valid_yu_oh_input(d: int, x: float, y: float) -> bool:
|
|
129
|
+
"""Whether (x, y) lie in the valid parameter domain for `yu_oh`.
|
|
130
|
+
|
|
131
|
+
Args:
|
|
132
|
+
d: local dimension.
|
|
133
|
+
x: first free parameter.
|
|
134
|
+
y: second free parameter.
|
|
135
|
+
|
|
136
|
+
Returns:
|
|
137
|
+
bool: True if x**2 + y**2 <= 1 and the resulting delta is positive.
|
|
138
|
+
"""
|
|
139
|
+
if x**2 + y**2 > 1:
|
|
140
|
+
return False
|
|
141
|
+
z = sqrt(1 - x**2 - y**2)
|
|
142
|
+
delta = z**2 / (d - 2) - x * y
|
|
143
|
+
if delta <= 0:
|
|
144
|
+
return False
|
|
145
|
+
return True
|
cm_otimes_cn/__init__.py
ADDED
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
from cm_otimes_cn.generalized_grid_state import generalized_grid_state
|
|
2
|
+
from cm_otimes_cn.grid_state import grid_state
|
|
3
|
+
from cm_otimes_cn.random_not_bound_entangled import random_NPT, random_PPT, random_PPT_close_to_the_PPT_edge
|
|
4
|
+
from cm_otimes_cn.gen_tiles import gen_tiles2
|
|
@@ -0,0 +1,80 @@
|
|
|
1
|
+
"""https://arxiv.org/abs/quant-ph/9908070
|
|
2
|
+
|
|
3
|
+
D. P. DiVincenzo, T. Mor, P. W. Shor, J. A. Smolin, B. M. Terhal,
|
|
4
|
+
"Unextendible Product Bases, Uncompletable Product Bases and Bound
|
|
5
|
+
Entanglement", Commun. Math. Phys. 238, 379 (2003), Section V B, Theorem 6. A
|
|
6
|
+
"tile" construction generalizing the Tiles UPB (`c3_otimes_c3.tiles_upb`) to
|
|
7
|
+
arbitrary m (x) n dimension.
|
|
8
|
+
"""
|
|
9
|
+
|
|
10
|
+
import numpy as np
|
|
11
|
+
from utils import upb
|
|
12
|
+
|
|
13
|
+
|
|
14
|
+
def gen_tiles2_basis(m_n: tuple[int, int]) -> list[np.ndarray]:
|
|
15
|
+
"""The product vectors of the GenTiles2 UPB on C^m (x) C^n.
|
|
16
|
+
|
|
17
|
+
Built from m "short" tile states (Eq. 5.9), m * (n - 3) "long" tile
|
|
18
|
+
states (Eq. 5.10), and a "stopper" state (Eq. 5.11), for a total of
|
|
19
|
+
m*n - 2m + 1 states.
|
|
20
|
+
|
|
21
|
+
Args:
|
|
22
|
+
m_n: dimensions (m, n) of the C^m (x) C^n bipartite system. Requires
|
|
23
|
+
n > 3, m >= 3, and n >= m. Note m = n = 3 does not yield a UPB
|
|
24
|
+
(excluded by n > 3).
|
|
25
|
+
|
|
26
|
+
Returns:
|
|
27
|
+
list[np.ndarray]: the normalized product vectors forming the
|
|
28
|
+
GenTiles2 unextendible product basis, as column vectors.
|
|
29
|
+
"""
|
|
30
|
+
m, n = m_n
|
|
31
|
+
if not (n > 3 and m >= 3 and n >= m):
|
|
32
|
+
raise ValueError("requires n > 3, m >= 3, and n >= m")
|
|
33
|
+
|
|
34
|
+
basis = []
|
|
35
|
+
|
|
36
|
+
for j in range(m):
|
|
37
|
+
# |S_j> = 1/sqrt(2) (|j> - |j+1 mod m>) (x) |j>
|
|
38
|
+
ket_a = np.zeros(m, dtype=np.complex128)
|
|
39
|
+
ket_a[j] = 1
|
|
40
|
+
ket_a[(j + 1) % m] -= 1
|
|
41
|
+
ket_a /= np.linalg.norm(ket_a)
|
|
42
|
+
ket_b = np.zeros(n, dtype=np.complex128)
|
|
43
|
+
ket_b[j] = 1
|
|
44
|
+
basis.append(np.kron(ket_a, ket_b).reshape(-1, 1))
|
|
45
|
+
|
|
46
|
+
omega = np.exp(1j * 2 * np.pi / (n - 2))
|
|
47
|
+
for j in range(m):
|
|
48
|
+
ket_a = np.zeros(m, dtype=np.complex128)
|
|
49
|
+
ket_a[j] = 1
|
|
50
|
+
for k in range(1, n - 2):
|
|
51
|
+
# |L_jk> = |j> (x) 1/sqrt(n-2) (sum_{i=0}^{m-3} w^ik |i+j+1 mod m>
|
|
52
|
+
# + sum_{i=m-2}^{n-3} w^ik |i+2>)
|
|
53
|
+
ket_b = np.zeros(n, dtype=np.complex128)
|
|
54
|
+
for i in range(m - 2):
|
|
55
|
+
ket_b[(i + j + 1) % m] += omega ** (i * k)
|
|
56
|
+
for i in range(m - 2, n - 2):
|
|
57
|
+
ket_b[i + 2] += omega ** (i * k)
|
|
58
|
+
ket_b /= np.linalg.norm(ket_b)
|
|
59
|
+
basis.append(np.kron(ket_a, ket_b).reshape(-1, 1))
|
|
60
|
+
|
|
61
|
+
# |F> = 1/sqrt(nm) sum_i sum_j |i> (x) |j>
|
|
62
|
+
stopper = np.ones(m * n, dtype=np.complex128) / np.sqrt(m * n)
|
|
63
|
+
basis.append(stopper.reshape(-1, 1))
|
|
64
|
+
|
|
65
|
+
return basis
|
|
66
|
+
|
|
67
|
+
|
|
68
|
+
def gen_tiles2(m_n: tuple[int, int]) -> np.ndarray:
|
|
69
|
+
"""The bound entangled state built from the GenTiles2 UPB on C^m (x) C^n.
|
|
70
|
+
|
|
71
|
+
Args:
|
|
72
|
+
m_n: dimensions (m, n) of the C^m (x) C^n bipartite system. Requires
|
|
73
|
+
n > 3, m >= 3, and n >= m. Note m = n = 3 does not yield a UPB
|
|
74
|
+
(excluded by n > 3).
|
|
75
|
+
|
|
76
|
+
Returns:
|
|
77
|
+
np.ndarray: the bound entangled state on the orthogonal complement of
|
|
78
|
+
the GenTiles2 unextendible product basis.
|
|
79
|
+
"""
|
|
80
|
+
return upb(gen_tiles2_basis(m_n))
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
"""https://arxiv.org/abs/2402.12966
|
|
2
|
+
|
|
3
|
+
R. Krebs, M. Gachechiladze, "High Schmidt number concentration in quantum
|
|
4
|
+
bound entangled states". Generalizes quantum grid states (see
|
|
5
|
+
`cm_otimes_cn.grid_state`) to hyperedges spanning more than two vertices.
|
|
6
|
+
"""
|
|
7
|
+
|
|
8
|
+
import numpy as np
|
|
9
|
+
from utils import ketbra
|
|
10
|
+
|
|
11
|
+
|
|
12
|
+
def grid_component(m_n: tuple[int, int], *ij: tuple[int, int]) -> np.ndarray:
|
|
13
|
+
m, n = m_n
|
|
14
|
+
e = np.zeros(m * n)
|
|
15
|
+
for i, j in ij:
|
|
16
|
+
if i >= m or j >= n:
|
|
17
|
+
raise IndexError(f"Vertex ({i},{j}) does not belong to the graph, m={m}, n={n}")
|
|
18
|
+
e[i * n + j] += 1
|
|
19
|
+
return e
|
|
20
|
+
|
|
21
|
+
|
|
22
|
+
def generalized_grid_state(m_n: tuple[int, int], *hyperedges: list[tuple[int, int]]):
|
|
23
|
+
"""A generalized grid state
|
|
24
|
+
|
|
25
|
+
Args:
|
|
26
|
+
m_n: grid dimensions (m, n).
|
|
27
|
+
*hyperedges: each hyperedge is a list of vertices (i, j) it spans.
|
|
28
|
+
|
|
29
|
+
Returns:
|
|
30
|
+
np.ndarray: the generalized grid state on C^m (x) C^n.
|
|
31
|
+
"""
|
|
32
|
+
m, n = m_n
|
|
33
|
+
rho = np.zeros((m * n, m * n))
|
|
34
|
+
for edge in hyperedges:
|
|
35
|
+
gc = grid_component(m_n, *edge)
|
|
36
|
+
rho += ketbra(gc, gc)
|
|
37
|
+
rho /= np.trace(rho)
|
|
38
|
+
return rho
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
"""https://arxiv.org/abs/1705.09261
|
|
2
|
+
|
|
3
|
+
J. Lockhart, O. Gühne, S. Severini, "Entanglement properties of quantum grid
|
|
4
|
+
states", Phys. Rev. A 97, 062340 (2018).
|
|
5
|
+
"""
|
|
6
|
+
|
|
7
|
+
import numpy as np
|
|
8
|
+
from math import sqrt
|
|
9
|
+
from utils import ketbra
|
|
10
|
+
|
|
11
|
+
|
|
12
|
+
def ket(m_n: tuple[int, int], ij: tuple[int, int]):
|
|
13
|
+
m, n = m_n
|
|
14
|
+
i, j = ij
|
|
15
|
+
z = np.zeros(m * n)
|
|
16
|
+
if i >= m or j >= n:
|
|
17
|
+
raise IndexError(f"Vertex ({i},{j}) does not belong to the graph, m={m}, n={n}")
|
|
18
|
+
z[i * n + j] = 1
|
|
19
|
+
return z
|
|
20
|
+
|
|
21
|
+
|
|
22
|
+
def grid_component(m_n: tuple[int, int], ij: tuple[int, int], kl: tuple[int, int]) -> np.ndarray:
|
|
23
|
+
return 1 / sqrt(2) * (ket(m_n, ij) - ket(m_n, kl))
|
|
24
|
+
|
|
25
|
+
|
|
26
|
+
def grid_state(m_n: tuple[int, int], *edges: tuple[tuple[int, int], tuple[int, int]]) -> np.ndarray:
|
|
27
|
+
"""A quantum grid state: the uniform mixture of pure states over a set of graph edges.
|
|
28
|
+
|
|
29
|
+
Args:
|
|
30
|
+
m_n: grid dimensions (m, n).
|
|
31
|
+
*edges: each edge is a pair of vertices ((i, j), (k, l)).
|
|
32
|
+
|
|
33
|
+
Returns:
|
|
34
|
+
np.ndarray: the grid state on C^m (x) C^n.
|
|
35
|
+
"""
|
|
36
|
+
m, n = m_n
|
|
37
|
+
ret = np.zeros((m * n, m * n))
|
|
38
|
+
for ij, kl in edges:
|
|
39
|
+
gc = grid_component(m_n, ij, kl)
|
|
40
|
+
ret += ketbra(gc, gc)
|
|
41
|
+
ret /= len(edges)
|
|
42
|
+
return ret
|
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
from toqito.rand import random_density_matrix
|
|
2
|
+
from toqito.state_props import is_ppt
|
|
3
|
+
import numpy as np
|
|
4
|
+
|
|
5
|
+
|
|
6
|
+
def random_NPT(m_n: tuple[int, int]) -> np.ndarray:
|
|
7
|
+
"""A uniformly random density matrix with a non-positive partial transpose (rejection sampling).
|
|
8
|
+
|
|
9
|
+
Args:
|
|
10
|
+
m_n: dimensions (m, n) of the C^m (x) C^n bipartite system.
|
|
11
|
+
|
|
12
|
+
Returns:
|
|
13
|
+
np.ndarray: a random NPT (hence necessarily entangled) density matrix.
|
|
14
|
+
"""
|
|
15
|
+
m, n = m_n
|
|
16
|
+
while True:
|
|
17
|
+
rho = random_density_matrix(m * n)
|
|
18
|
+
if not is_ppt(rho, dim=[m, n]):
|
|
19
|
+
return rho
|
|
20
|
+
|
|
21
|
+
|
|
22
|
+
def random_PPT(m_n: tuple[int, int]) -> np.ndarray:
|
|
23
|
+
"""A uniformly random density matrix with a positive partial transpose (rejection sampling).
|
|
24
|
+
|
|
25
|
+
Args:
|
|
26
|
+
m_n: dimensions (m, n) of the C^m (x) C^n bipartite system.
|
|
27
|
+
|
|
28
|
+
Returns:
|
|
29
|
+
np.ndarray: a random PPT density matrix.
|
|
30
|
+
"""
|
|
31
|
+
m, n = m_n
|
|
32
|
+
while True:
|
|
33
|
+
rho = random_density_matrix(m * n)
|
|
34
|
+
if is_ppt(rho, dim=[m, n]):
|
|
35
|
+
return rho
|
|
36
|
+
|
|
37
|
+
|
|
38
|
+
def random_PPT_close_to_the_PPT_edge(m_n, precision: int) -> np.ndarray:
|
|
39
|
+
"""A random PPT state close to the boundary of the PPT set.
|
|
40
|
+
|
|
41
|
+
Obtained by bisecting the segment between a random PPT and a random NPT
|
|
42
|
+
state: at each step the midpoint replaces whichever endpoint is on its
|
|
43
|
+
own side, halving the distance to the PPT/NPT boundary.
|
|
44
|
+
|
|
45
|
+
Args:
|
|
46
|
+
m_n: dimensions (m, n) of the C^m (x) C^n bipartite system.
|
|
47
|
+
precision: number of bisection steps.
|
|
48
|
+
|
|
49
|
+
Returns:
|
|
50
|
+
np.ndarray: a PPT density matrix close to the PPT boundary.
|
|
51
|
+
"""
|
|
52
|
+
m, n = m_n
|
|
53
|
+
ppt: np.ndarray = random_PPT(m_n)
|
|
54
|
+
not_ppt: np.ndarray = random_NPT(m_n)
|
|
55
|
+
|
|
56
|
+
for _ in range(precision):
|
|
57
|
+
temp = (ppt + not_ppt) / 2
|
|
58
|
+
if is_ppt(temp, dim=[m, n]):
|
|
59
|
+
ppt = temp
|
|
60
|
+
else:
|
|
61
|
+
not_ppt = temp
|
|
62
|
+
return ppt / np.trace(ppt)
|
utils/__init__.py
ADDED
utils/ketbra.py
ADDED
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import numpy as np
|
|
2
|
+
|
|
3
|
+
|
|
4
|
+
def ketbra(a: np.ndarray, b: np.ndarray) -> np.ndarray:
|
|
5
|
+
"""The outer product |a><b|.
|
|
6
|
+
|
|
7
|
+
Args:
|
|
8
|
+
a: the "ket" vector.
|
|
9
|
+
b: the "bra" vector (its complex conjugate is used).
|
|
10
|
+
|
|
11
|
+
Returns:
|
|
12
|
+
np.ndarray: the rank-1 operator |a><b|.
|
|
13
|
+
"""
|
|
14
|
+
return np.outer(a, b.conj())
|
utils/upb.py
ADDED
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
import numpy as np
|
|
2
|
+
from utils import ketbra
|
|
3
|
+
|
|
4
|
+
|
|
5
|
+
def upb(basis: list[np.ndarray]) -> np.ndarray:
|
|
6
|
+
"""Bound entangled state built from an unextendible product basis (UPB).
|
|
7
|
+
|
|
8
|
+
The uniform mixture over the orthogonal complement of a UPB is PPT (each
|
|
9
|
+
|v_i><v_i| being a product-state projector, partial transposition leaves
|
|
10
|
+
it unchanged) yet has no product vector in its range, hence is entangled:
|
|
11
|
+
a bound entangled state.
|
|
12
|
+
|
|
13
|
+
Reference: C. H. Bennett, D. P. DiVincenzo, T. Mor, P. W. Shor, J. A.
|
|
14
|
+
Smolin, B. M. Terhal, "Unextendible Product Bases and Bound Entanglement",
|
|
15
|
+
Phys. Rev. Lett. 82, 5385 (1999), https://arxiv.org/abs/quant-ph/9808030
|
|
16
|
+
|
|
17
|
+
Args:
|
|
18
|
+
basis: the product vectors (as column vectors) forming the UPB.
|
|
19
|
+
|
|
20
|
+
Returns:
|
|
21
|
+
np.ndarray: the corresponding bound entangled density matrix.
|
|
22
|
+
"""
|
|
23
|
+
d_total: int = basis[0].shape[0]
|
|
24
|
+
rho = np.identity(d_total, dtype=np.complex128)
|
|
25
|
+
for i in range(len(basis)):
|
|
26
|
+
rho -= ketbra(basis[i], basis[i])
|
|
27
|
+
return rho / (d_total - len(basis))
|