| .. | ||
| 01_werner_qubit_symbolic.py | ||
| 02_werner_qutrit_symbolic.py | ||
| 03_dps_level2_demo.py | ||
| 04_tiles_noise_scan.py | ||
| 05_local_filtering.py | ||
| 06_dps_level2_filtered.py | ||
| 07_dps_level3_single.py | ||
| 08_dps_level_k_bisection.py | ||
| 09_dps_level3_filtered_bisection.py | ||
| common.py | ||
| dps_hierarchy.py | ||
| dps_level3_bisection_state.json | ||
| dps_level3_filtered_bisection_state.json | ||
| README.md | ||
| requirements.txt | ||
Entanglement-detection scripts from this chat
This is the code from a conversation that started with the "symmetric shadow
maps" paper (symmetric_shadow_maps_formal.tex) and worked outward through a
chain of entanglement-detection techniques on the two-qutrit Tiles
bound-entangled state (Bennett-DiVincenzo-Mor-Shor-Smolin-Terhal UPB state,
already used as a benchmark in the paper): symmetric-state sanity checks,
DPS symmetric-extension SDPs, noise-robustness thresholds, local filtering,
and (in progress) a third DPS extension level.
Note: none of this has been re-run/verified after being assembled into this package (per your request) -- it's a straight extraction of the code from the chat. The numbers quoted in each docstring/comment are what the sandbox actually produced during the conversation; treat them as "expected results to check against" rather than guaranteed.
Setup
pip install -r requirements.txt
scs is the default (open-source, first-order) SDP solver used throughout.
If you have a MOSEK license (free for academics), it is very likely much
faster for these problem sizes -- just change SOLVER = cp.SCS to
SOLVER = cp.MOSEK near the top of scripts 03, 04, 06, 07, 08.
Files, in the order they came up in the conversation
| File | What it does | Expected result | Rough runtime |
|---|---|---|---|
common.py |
Shared utilities: Gell-Mann generators (paper convention), Tiles state, qutrit Werner state, correlation-matrix/shadow-map criterion, plain PPT check, operator-Sinkhorn filter. Imported by scripts 03-06. | -- | -- |
dps_hierarchy.py |
General, level-k-parametrized DPS symmetric-extension SDP builder (used for levels 2 and 3, and usable for higher k). |
-- | -- |
01_werner_qubit_symbolic.py |
Exact (sympy) check: 2-qubit Werner state, SU(2) symmetry forces the correlation matrix ∝ I. |
Shadow-map threshold exactly matches PPT: p_c = 1/3 both ways. | seconds |
02_werner_qutrit_symbolic.py |
Same, generalized to qutrits (antisymmetric-subspace Werner state). | Shadow-map threshold p_c = 1/2, but true threshold (Werner 1989) is p_c = 1/4 -- the order-1 criterion is valid but NOT tight in d=3 (unlike d=2). | under a minute |
03_dps_level2_demo.py |
DPS level 2 via dps_hierarchy. Sanity check on Werner qutrit; then the interesting case: Tiles state, where plain PPT is exactly blind (min eigenvalue ≈ 0) but DPS-2 detects it. |
Werner: consistent with p=1/4 away from the boundary. Tiles: PPT feasible=True, DPS-2 feasible=False (detected). Robust across solver tolerances 1e-5..1e-8. | under a minute |
04_tiles_noise_scan.py |
Noise-threshold bisection for (a) the plain shadow-map criterion and (b) DPS level 2, on the noisy Tiles family. | Shadow-map p_c ≈ 0.9493 (5.07% tolerance); DPS-2 p_c ≈ 0.951 (4.9%) -- i.e. DPS-2 barely improves on the much cheaper order-1 criterion for this state. | a few minutes (DPS-2 bisection) |
05_local_filtering.py |
Operator-Sinkhorn local filtering (SLOCC normal form) + the plain shadow-map criterion on the filtered state. | p_c ≈ 0.8722 (12.78% tolerance) -- matches the literature's "Filter Covariance Matrix Criterion" (Gittsovich, Gühne, Hyllus, Eisert, arXiv:0803.0757, Prop. IV.13: p_c = 0.8723, 12.77%) to ~4 decimal places. | seconds |
06_dps_level2_filtered.py |
DPS level 2 applied to the filtered state (combining both levers). | p_c ≈ 0.9426 (5.74%) -- filtering helps DPS-2 only marginally, much less than it helps the plain shadow-map (05). Filtering and DPS-extension-order are not equally powerful levers here, and don't simply stack. | a few minutes |
07_dps_level3_single.py |
A single DPS level-3 feasibility check on the pure Tiles state, to confirm level 3 is tractable at all. | status = infeasible (detected). Took ~137s with SCS in the original sandbox. | ~1-3 minutes |
08_dps_level_k_bisection.py |
General, resumable bisection for the DPS level-k noise threshold, one step per invocation, progress saved to JSON. Defaults to LEVEL=3. |
See below -- in progress. | ~2-4 min per step with SCS (k=3) |
dps_level3_bisection_state.json |
Saved progress for the level-3 bisection from the original session (8 SCS solves already spent). | Current bracket: [0.90982, 0.91080], i.e. p_c ≈ 0.910-0.911. |
-- |
09_dps_level3_filtered_bisection.py |
Combines local filtering (05) with DPS level 3 (07/08): filter the state, then run the level-3 SDP on it. Resumable, same pattern as 08. | Untested/in progress -- based on the level-2 precedent (06), expect only a modest improvement over plain level 3, not a jump to ~13%. Starting bracket is an educated guess, not a proven bound (see the script's docstring). | most expensive script here: ~85-140s per solve, ~12-16 solves for a full bisection |
Where the level-3 bisection currently stands
{"lo": 0.90982, "hi": 0.91080, "iter": 8}
So DPS level 3 detects entanglement for p ≳ 0.910, i.e. roughly
9.0% noise tolerance -- already better than level 2's 4.9-5.7%, but
still well short of the 12.77-12.78% that local filtering alone achieves.
Just re-run 08_dps_level_k_bisection.py (it picks up the saved state
automatically) to narrow this further.
The overall picture that emerged (for reference)
| Method | p_c | Noise tolerance |
|---|---|---|
| plain PPT | ~1.0 | ~0% (knife-edge) |
| shadow-map / de Vicente Bloch criterion (order 1) | 0.9493 | 5.07% |
| DPS level 2 | 0.9510 | 4.90% |
| DPS level 2 + filtering | 0.9426 | 5.74% |
| DPS level 3 (partial result so far) | ~0.910 | ~9.0% (narrowing) |
| local filtering + shadow-map (order 1) | 0.8722 | 12.78% |
| literature: Filter-CMC (Prop. IV.13) | 0.8723 | 12.77% |
| literature: best known positive map | 0.8744 | 12.56% |
Headline takeaway: for this particular state, local filtering (a SLOCC pre-processing step) is a far bigger lever than increasing the DPS extension order, and the two don't stack additively -- filtering the state and then applying the cheapest possible (order-1) criterion already matches a specialized literature result almost exactly, while adding DPS levels on top gives comparatively little.
A performance note on why level 3+ gets slow
The DPS SDP variable is parametrized on A ⊗ Sym^k(B), dimension
d · C(d+k-1, k) -- polynomial in k (this is the "exploit the built-in
Bose symmetry of the extension copies" trick). But the PPT constraint
itself has to be checked on the full, unsymmetrized embedding
A ⊗ B_1 ⊗ ... ⊗ B_k, dimension d^(k+1) -- exponential in k. Since
SDP solver cost is governed by the size of the PSD cone (the PPT
constraint), not by the number of free variables, this is why level 3
(81×81 cone) is already much slower than level 2 (27×27 cone), and level 4
(243×243) would be slower still. A proper fix would exploit
representation-theoretic structure of the PPT constraint itself, not just
of the extension -- that's a bigger undertaking than what's implemented
here.
If you have MOSEK (or another interior-point solver): try it first for levels 3-4. Interior-point methods are usually much faster than SCS on small/medium, dense SDPs like these -- SCS is tuned for large sparse problems and is likely the main reason level 3 took ~137s-227s per solve here rather than a fraction of a second.