qLDPC 0.4.1__tar.gz → 0.4.2.dev20261004__tar.gz
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.
- {qldpc-0.4.1 → qldpc-0.4.2.dev20261004}/PKG-INFO +3 -2
- {qldpc-0.4.1 → qldpc-0.4.2.dev20261004}/README.md +2 -1
- {qldpc-0.4.1 → qldpc-0.4.2.dev20261004}/pyproject.toml +10 -2
- {qldpc-0.4.1 → qldpc-0.4.2.dev20261004}/pyproject.toml.orig +7 -1
- {qldpc-0.4.1 → qldpc-0.4.2.dev20261004}/src/qldpc/circuits/benchmarking_test.py +2 -2
- {qldpc-0.4.1 → qldpc-0.4.2.dev20261004}/src/qldpc/codes/code_capacity.py +77 -51
- {qldpc-0.4.1 → qldpc-0.4.2.dev20261004}/src/qldpc/codes/code_capacity_test.py +281 -14
- {qldpc-0.4.1 → qldpc-0.4.2.dev20261004}/src/qldpc/codes/common.py +52 -111
- {qldpc-0.4.1 → qldpc-0.4.2.dev20261004}/src/qldpc/codes/common_test.py +131 -14
- {qldpc-0.4.1 → qldpc-0.4.2.dev20261004}/src/qldpc/decoders/__init__.py +101 -24
- {qldpc-0.4.1 → qldpc-0.4.2.dev20261004}/src/qldpc/decoders/adapters/error_decoders.py +51 -3
- {qldpc-0.4.1 → qldpc-0.4.2.dev20261004}/src/qldpc/decoders/adapters/error_decoders_test.py +20 -1
- {qldpc-0.4.1 → qldpc-0.4.2.dev20261004}/src/qldpc/decoders/capabilities.py +7 -27
- {qldpc-0.4.1 → qldpc-0.4.2.dev20261004}/src/qldpc/decoders/capabilities_test.py +5 -26
- {qldpc-0.4.1 → qldpc-0.4.2.dev20261004}/src/qldpc/decoders/common.py +14 -11
- {qldpc-0.4.1 → qldpc-0.4.2.dev20261004}/src/qldpc/decoders/common_test.py +11 -11
- qldpc-0.4.2.dev20261004/src/qldpc/decoders/construction/factories.py +58 -0
- qldpc-0.4.2.dev20261004/src/qldpc/decoders/construction/factories_test.py +85 -0
- {qldpc-0.4.1 → qldpc-0.4.2.dev20261004}/src/qldpc/decoders/construction/legacy.py +63 -81
- {qldpc-0.4.1 → qldpc-0.4.2.dev20261004}/src/qldpc/decoders/construction/legacy_test.py +103 -32
- {qldpc-0.4.1 → qldpc-0.4.2.dev20261004}/src/qldpc/decoders/construction/resolution.py +67 -17
- {qldpc-0.4.1 → qldpc-0.4.2.dev20261004}/src/qldpc/decoders/construction/resolution_test.py +109 -22
- {qldpc-0.4.1 → qldpc-0.4.2.dev20261004}/src/qldpc/decoders/construction/specs.py +55 -124
- {qldpc-0.4.1 → qldpc-0.4.2.dev20261004}/src/qldpc/decoders/construction/specs_test.py +60 -60
- {qldpc-0.4.1 → qldpc-0.4.2.dev20261004}/src/qldpc/decoders/custom/__init__.py +14 -4
- qldpc-0.4.2.dev20261004/src/qldpc/decoders/custom/_lookup_enumeration.py +231 -0
- qldpc-0.4.2.dev20261004/src/qldpc/decoders/custom/_lookup_enumeration_test.py +159 -0
- {qldpc-0.4.1 → qldpc-0.4.2.dev20261004}/src/qldpc/decoders/custom/composition_test.py +9 -9
- {qldpc-0.4.1 → qldpc-0.4.2.dev20261004}/src/qldpc/decoders/custom/guf.py +16 -8
- {qldpc-0.4.1 → qldpc-0.4.2.dev20261004}/src/qldpc/decoders/custom/guf_test.py +4 -4
- {qldpc-0.4.1 → qldpc-0.4.2.dev20261004}/src/qldpc/decoders/custom/ilp.py +65 -39
- {qldpc-0.4.1 → qldpc-0.4.2.dev20261004}/src/qldpc/decoders/custom/ilp_test.py +21 -10
- {qldpc-0.4.1 → qldpc-0.4.2.dev20261004}/src/qldpc/decoders/custom/lookup.py +91 -281
- {qldpc-0.4.1 → qldpc-0.4.2.dev20261004}/src/qldpc/decoders/custom/lookup_test.py +110 -94
- {qldpc-0.4.1 → qldpc-0.4.2.dev20261004}/src/qldpc/decoders/custom_test.py +8 -0
- {qldpc-0.4.1 → qldpc-0.4.2.dev20261004}/src/qldpc/decoders/dems_test.py +14 -8
- {qldpc-0.4.1 → qldpc-0.4.2.dev20261004}/src/qldpc/decoders/external/frontier.py +53 -11
- {qldpc-0.4.1 → qldpc-0.4.2.dev20261004}/src/qldpc/decoders/external/frontier_test.py +28 -7
- {qldpc-0.4.1 → qldpc-0.4.2.dev20261004}/src/qldpc/decoders/external/ldpc.py +110 -30
- {qldpc-0.4.1 → qldpc-0.4.2.dev20261004}/src/qldpc/decoders/external/ldpc_test.py +30 -2
- {qldpc-0.4.1 → qldpc-0.4.2.dev20261004}/src/qldpc/decoders/external/pymatching.py +84 -13
- {qldpc-0.4.1 → qldpc-0.4.2.dev20261004}/src/qldpc/decoders/external/pymatching_test.py +17 -0
- {qldpc-0.4.1 → qldpc-0.4.2.dev20261004}/src/qldpc/decoders/external/relay_bp.py +154 -20
- {qldpc-0.4.1 → qldpc-0.4.2.dev20261004}/src/qldpc/decoders/external/relay_bp_test.py +29 -9
- {qldpc-0.4.1 → qldpc-0.4.2.dev20261004}/src/qldpc/decoders/external/tesseract.py +80 -23
- {qldpc-0.4.1 → qldpc-0.4.2.dev20261004}/src/qldpc/decoders/external/tesseract_test.py +22 -6
- qldpc-0.4.2.dev20261004/src/qldpc/decoders/legacy_api_test.py +233 -0
- {qldpc-0.4.1 → qldpc-0.4.2.dev20261004}/src/qldpc/decoders/protocols.py +77 -4
- {qldpc-0.4.1 → qldpc-0.4.2.dev20261004}/src/qldpc/decoders/protocols_test.py +5 -3
- {qldpc-0.4.1 → qldpc-0.4.2.dev20261004}/src/qldpc/decoders/sinter/core.py +9 -52
- {qldpc-0.4.1 → qldpc-0.4.2.dev20261004}/src/qldpc/decoders/sinter/core_test.py +33 -24
- {qldpc-0.4.1 → qldpc-0.4.2.dev20261004}/src/qldpc/decoders/sinter/subgraph.py +4 -6
- {qldpc-0.4.1 → qldpc-0.4.2.dev20261004}/src/qldpc/decoders/sinter/subgraph_test.py +1 -1
- {qldpc-0.4.1 → qldpc-0.4.2.dev20261004}/src/qldpc/decoders/sinter/window.py +10 -14
- {qldpc-0.4.1 → qldpc-0.4.2.dev20261004}/src/qldpc/decoders/sinter/window_test.py +1 -1
- {qldpc-0.4.1 → qldpc-0.4.2.dev20261004}/COPYRIGHT +0 -0
- {qldpc-0.4.1 → qldpc-0.4.2.dev20261004}/LICENSE +0 -0
- {qldpc-0.4.1 → qldpc-0.4.2.dev20261004}/src/qldpc/__init__.py +0 -0
- {qldpc-0.4.1 → qldpc-0.4.2.dev20261004}/src/qldpc/_util.py +0 -0
- {qldpc-0.4.1 → qldpc-0.4.2.dev20261004}/src/qldpc/_util_test.py +0 -0
- {qldpc-0.4.1 → qldpc-0.4.2.dev20261004}/src/qldpc/abstract/__init__.py +0 -0
- {qldpc-0.4.1 → qldpc-0.4.2.dev20261004}/src/qldpc/abstract/_monomials.py +0 -0
- {qldpc-0.4.1 → qldpc-0.4.2.dev20261004}/src/qldpc/abstract/_monomials_test.py +0 -0
- {qldpc-0.4.1 → qldpc-0.4.2.dev20261004}/src/qldpc/abstract/groups.py +0 -0
- {qldpc-0.4.1 → qldpc-0.4.2.dev20261004}/src/qldpc/abstract/groups_test.py +0 -0
- {qldpc-0.4.1 → qldpc-0.4.2.dev20261004}/src/qldpc/abstract/linalg.py +0 -0
- {qldpc-0.4.1 → qldpc-0.4.2.dev20261004}/src/qldpc/abstract/linalg_test.py +0 -0
- {qldpc-0.4.1 → qldpc-0.4.2.dev20261004}/src/qldpc/abstract/ring_array.py +0 -0
- {qldpc-0.4.1 → qldpc-0.4.2.dev20261004}/src/qldpc/abstract/ring_array_test.py +0 -0
- {qldpc-0.4.1 → qldpc-0.4.2.dev20261004}/src/qldpc/abstract/rings.py +0 -0
- {qldpc-0.4.1 → qldpc-0.4.2.dev20261004}/src/qldpc/abstract/rings_test.py +0 -0
- {qldpc-0.4.1 → qldpc-0.4.2.dev20261004}/src/qldpc/abstract/wedderburn_artin.py +0 -0
- {qldpc-0.4.1 → qldpc-0.4.2.dev20261004}/src/qldpc/abstract/wedderburn_artin_test.py +0 -0
- {qldpc-0.4.1 → qldpc-0.4.2.dev20261004}/src/qldpc/cache.py +0 -0
- {qldpc-0.4.1 → qldpc-0.4.2.dev20261004}/src/qldpc/cache_test.py +0 -0
- {qldpc-0.4.1 → qldpc-0.4.2.dev20261004}/src/qldpc/circuits/__init__.py +0 -0
- {qldpc-0.4.1 → qldpc-0.4.2.dev20261004}/src/qldpc/circuits/benchmarking.py +0 -0
- {qldpc-0.4.1 → qldpc-0.4.2.dev20261004}/src/qldpc/circuits/bookkeeping.py +0 -0
- {qldpc-0.4.1 → qldpc-0.4.2.dev20261004}/src/qldpc/circuits/bookkeeping_test.py +0 -0
- {qldpc-0.4.1 → qldpc-0.4.2.dev20261004}/src/qldpc/circuits/common.py +0 -0
- {qldpc-0.4.1 → qldpc-0.4.2.dev20261004}/src/qldpc/circuits/common_test.py +0 -0
- {qldpc-0.4.1 → qldpc-0.4.2.dev20261004}/src/qldpc/circuits/conftest.py +0 -0
- {qldpc-0.4.1 → qldpc-0.4.2.dev20261004}/src/qldpc/circuits/encoding.py +0 -0
- {qldpc-0.4.1 → qldpc-0.4.2.dev20261004}/src/qldpc/circuits/encoding_test.py +0 -0
- {qldpc-0.4.1 → qldpc-0.4.2.dev20261004}/src/qldpc/circuits/memory/__init__.py +0 -0
- {qldpc-0.4.1 → qldpc-0.4.2.dev20261004}/src/qldpc/circuits/memory/alpha_syndrome.py +0 -0
- {qldpc-0.4.1 → qldpc-0.4.2.dev20261004}/src/qldpc/circuits/memory/alpha_syndrome_test.py +0 -0
- {qldpc-0.4.1 → qldpc-0.4.2.dev20261004}/src/qldpc/circuits/memory/memory.py +0 -0
- {qldpc-0.4.1 → qldpc-0.4.2.dev20261004}/src/qldpc/circuits/memory/memory_test.py +0 -0
- {qldpc-0.4.1 → qldpc-0.4.2.dev20261004}/src/qldpc/circuits/memory/syndrome_measurement.py +0 -0
- {qldpc-0.4.1 → qldpc-0.4.2.dev20261004}/src/qldpc/circuits/memory/syndrome_measurement_test.py +0 -0
- {qldpc-0.4.1 → qldpc-0.4.2.dev20261004}/src/qldpc/circuits/noise_model.py +0 -0
- {qldpc-0.4.1 → qldpc-0.4.2.dev20261004}/src/qldpc/circuits/noise_model_test.py +0 -0
- {qldpc-0.4.1 → qldpc-0.4.2.dev20261004}/src/qldpc/circuits/transversal.py +0 -0
- {qldpc-0.4.1 → qldpc-0.4.2.dev20261004}/src/qldpc/circuits/transversal_test.py +0 -0
- {qldpc-0.4.1 → qldpc-0.4.2.dev20261004}/src/qldpc/codes/__init__.py +0 -0
- {qldpc-0.4.1 → qldpc-0.4.2.dev20261004}/src/qldpc/codes/classical.py +0 -0
- {qldpc-0.4.1 → qldpc-0.4.2.dev20261004}/src/qldpc/codes/classical_test.py +0 -0
- {qldpc-0.4.1 → qldpc-0.4.2.dev20261004}/src/qldpc/codes/distance.py +0 -0
- {qldpc-0.4.1 → qldpc-0.4.2.dev20261004}/src/qldpc/codes/distance_test.py +0 -0
- {qldpc-0.4.1 → qldpc-0.4.2.dev20261004}/src/qldpc/codes/monte_carlo.py +0 -0
- {qldpc-0.4.1 → qldpc-0.4.2.dev20261004}/src/qldpc/codes/monte_carlo_test.py +0 -0
- {qldpc-0.4.1 → qldpc-0.4.2.dev20261004}/src/qldpc/codes/quantum.py +0 -0
- {qldpc-0.4.1 → qldpc-0.4.2.dev20261004}/src/qldpc/codes/quantum_test.py +0 -0
- {qldpc-0.4.1 → qldpc-0.4.2.dev20261004}/src/qldpc/conftest.py +0 -0
- {qldpc-0.4.1 → qldpc-0.4.2.dev20261004}/src/qldpc/decoders/adapters/__init__.py +0 -0
- {qldpc-0.4.1 → qldpc-0.4.2.dev20261004}/src/qldpc/decoders/adapters/observable_decoders.py +0 -0
- {qldpc-0.4.1 → qldpc-0.4.2.dev20261004}/src/qldpc/decoders/adapters/observable_decoders_test.py +0 -0
- {qldpc-0.4.1 → qldpc-0.4.2.dev20261004}/src/qldpc/decoders/conftest.py +0 -0
- {qldpc-0.4.1 → qldpc-0.4.2.dev20261004}/src/qldpc/decoders/construction/__init__.py +0 -0
- {qldpc-0.4.1 → qldpc-0.4.2.dev20261004}/src/qldpc/decoders/custom/composition.py +0 -0
- {qldpc-0.4.1 → qldpc-0.4.2.dev20261004}/src/qldpc/decoders/dems.py +0 -0
- {qldpc-0.4.1 → qldpc-0.4.2.dev20261004}/src/qldpc/decoders/external/__init__.py +0 -0
- {qldpc-0.4.1 → qldpc-0.4.2.dev20261004}/src/qldpc/decoders/sinter/__init__.py +0 -0
- {qldpc-0.4.1 → qldpc-0.4.2.dev20261004}/src/qldpc/decoders/sinter_test.py +0 -0
- {qldpc-0.4.1 → qldpc-0.4.2.dev20261004}/src/qldpc/decoders_test.py +0 -0
- {qldpc-0.4.1 → qldpc-0.4.2.dev20261004}/src/qldpc/experimental/__init__.py +0 -0
- {qldpc-0.4.1 → qldpc-0.4.2.dev20261004}/src/qldpc/experimental/surgery/__init__.py +0 -0
- {qldpc-0.4.1 → qldpc-0.4.2.dev20261004}/src/qldpc/experimental/surgery/_compiler.py +0 -0
- {qldpc-0.4.1 → qldpc-0.4.2.dev20261004}/src/qldpc/experimental/surgery/_compiler_test.py +0 -0
- {qldpc-0.4.1 → qldpc-0.4.2.dev20261004}/src/qldpc/experimental/surgery/bridge.py +0 -0
- {qldpc-0.4.1 → qldpc-0.4.2.dev20261004}/src/qldpc/experimental/surgery/bridge_test.py +0 -0
- {qldpc-0.4.1 → qldpc-0.4.2.dev20261004}/src/qldpc/experimental/surgery/cheeger.py +0 -0
- {qldpc-0.4.1 → qldpc-0.4.2.dev20261004}/src/qldpc/experimental/surgery/cheeger_test.py +0 -0
- {qldpc-0.4.1 → qldpc-0.4.2.dev20261004}/src/qldpc/experimental/surgery/circuit.py +0 -0
- {qldpc-0.4.1 → qldpc-0.4.2.dev20261004}/src/qldpc/experimental/surgery/circuit_test.py +0 -0
- {qldpc-0.4.1 → qldpc-0.4.2.dev20261004}/src/qldpc/experimental/surgery/conftest.py +0 -0
- {qldpc-0.4.1 → qldpc-0.4.2.dev20261004}/src/qldpc/experimental/surgery/construction.py +0 -0
- {qldpc-0.4.1 → qldpc-0.4.2.dev20261004}/src/qldpc/experimental/surgery/construction_test.py +0 -0
- {qldpc-0.4.1 → qldpc-0.4.2.dev20261004}/src/qldpc/experimental/surgery/gadget.py +0 -0
- {qldpc-0.4.1 → qldpc-0.4.2.dev20261004}/src/qldpc/experimental/surgery/gadget_test.py +0 -0
- {qldpc-0.4.1 → qldpc-0.4.2.dev20261004}/src/qldpc/external/__init__.py +0 -0
- {qldpc-0.4.1 → qldpc-0.4.2.dev20261004}/src/qldpc/external/codes.py +0 -0
- {qldpc-0.4.1 → qldpc-0.4.2.dev20261004}/src/qldpc/external/codes_test.py +0 -0
- {qldpc-0.4.1 → qldpc-0.4.2.dev20261004}/src/qldpc/external/gap.py +0 -0
- {qldpc-0.4.1 → qldpc-0.4.2.dev20261004}/src/qldpc/external/gap_test.py +0 -0
- {qldpc-0.4.1 → qldpc-0.4.2.dev20261004}/src/qldpc/external/groups.py +0 -0
- {qldpc-0.4.1 → qldpc-0.4.2.dev20261004}/src/qldpc/external/groups_test.py +0 -0
- {qldpc-0.4.1 → qldpc-0.4.2.dev20261004}/src/qldpc/external/sqetch.py +0 -0
- {qldpc-0.4.1 → qldpc-0.4.2.dev20261004}/src/qldpc/external/sqetch_test.py +0 -0
- {qldpc-0.4.1 → qldpc-0.4.2.dev20261004}/src/qldpc/math.py +0 -0
- {qldpc-0.4.1 → qldpc-0.4.2.dev20261004}/src/qldpc/math_test.py +0 -0
- {qldpc-0.4.1 → qldpc-0.4.2.dev20261004}/src/qldpc/objects.py +0 -0
- {qldpc-0.4.1 → qldpc-0.4.2.dev20261004}/src/qldpc/objects_test.py +0 -0
- {qldpc-0.4.1 → qldpc-0.4.2.dev20261004}/src/qldpc/py.typed +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: qldpc
|
|
3
|
-
Version: 0.4.
|
|
3
|
+
Version: 0.4.2.dev20261004
|
|
4
4
|
Summary: Tools for constructing and analyzing quantum low density parity check (qLDPC) codes.
|
|
5
5
|
Keywords: LDPC,low density parity check codes,quantum computing,quantum error correction
|
|
6
6
|
Author: Michael A. Perlin
|
|
@@ -106,7 +106,7 @@ python -m pip install qldpc
|
|
|
106
106
|
#### Decoders
|
|
107
107
|
|
|
108
108
|
qLDPC installs `ldpc` and `pymatching` by default, which include a host of decoders.
|
|
109
|
-
|
|
109
|
+
Install the optional decoder integrations published as qLDPC extras for your platform with:
|
|
110
110
|
|
|
111
111
|
```bash
|
|
112
112
|
python -m pip install 'qldpc[decoders]'
|
|
@@ -120,6 +120,7 @@ python -m pip install 'qldpc[tesseract]'
|
|
|
120
120
|
```
|
|
121
121
|
|
|
122
122
|
The [Tesseract](https://github.com/quantumlib/tesseract-decoder) decoder requires CPython 3.12–3.14 on macOS arm64 or Linux x86-64.
|
|
123
|
+
[Frontier](https://github.com/aleverrier/frontier) is not published on PyPI and is not included in an extra; see the [decoder guide](https://qldpc.readthedocs.io/decoders.html) for availability and build-time installation guidance.
|
|
123
124
|
|
|
124
125
|
#### GAP integration
|
|
125
126
|
|
|
@@ -41,7 +41,7 @@ python -m pip install qldpc
|
|
|
41
41
|
#### Decoders
|
|
42
42
|
|
|
43
43
|
qLDPC installs `ldpc` and `pymatching` by default, which include a host of decoders.
|
|
44
|
-
|
|
44
|
+
Install the optional decoder integrations published as qLDPC extras for your platform with:
|
|
45
45
|
|
|
46
46
|
```bash
|
|
47
47
|
python -m pip install 'qldpc[decoders]'
|
|
@@ -55,6 +55,7 @@ python -m pip install 'qldpc[tesseract]'
|
|
|
55
55
|
```
|
|
56
56
|
|
|
57
57
|
The [Tesseract](https://github.com/quantumlib/tesseract-decoder) decoder requires CPython 3.12–3.14 on macOS arm64 or Linux x86-64.
|
|
58
|
+
[Frontier](https://github.com/aleverrier/frontier) is not published on PyPI and is not included in an extra; see the [decoder guide](https://qldpc.readthedocs.io/decoders.html) for availability and build-time installation guidance.
|
|
58
59
|
|
|
59
60
|
#### GAP integration
|
|
60
61
|
|
|
@@ -4,7 +4,7 @@ requires = ["uv-build>=0.9.18,<0.13"]
|
|
|
4
4
|
|
|
5
5
|
[project]
|
|
6
6
|
name = "qldpc"
|
|
7
|
-
version = "0.4.
|
|
7
|
+
version = "0.4.2.dev20261004"
|
|
8
8
|
description = "Tools for constructing and analyzing quantum low density parity check (qLDPC) codes."
|
|
9
9
|
readme = "README.md"
|
|
10
10
|
keywords = [
|
|
@@ -93,6 +93,11 @@ ci-lint = [
|
|
|
93
93
|
"checks-superstaq>=0.5.67",
|
|
94
94
|
"pyproject-fmt>=2",
|
|
95
95
|
]
|
|
96
|
+
ci-notebooks = [
|
|
97
|
+
"jupyter>=1.1.1",
|
|
98
|
+
"matplotlib>=3.10",
|
|
99
|
+
"pip>=24",
|
|
100
|
+
]
|
|
96
101
|
ci-test = [
|
|
97
102
|
"checks-superstaq>=0.5.67",
|
|
98
103
|
"pytest>=8",
|
|
@@ -141,7 +146,10 @@ show_error_codes = true
|
|
|
141
146
|
|
|
142
147
|
[tool.pytest.ini_options]
|
|
143
148
|
addopts = "--disable-socket"
|
|
144
|
-
filterwarnings = [
|
|
149
|
+
filterwarnings = [
|
|
150
|
+
"error::DeprecationWarning",
|
|
151
|
+
"ignore:(?s).*The problem is either infeasible or unbounded.*:UserWarning",
|
|
152
|
+
]
|
|
145
153
|
|
|
146
154
|
[tool.coverage.run]
|
|
147
155
|
include = ["./*"]
|
|
@@ -4,7 +4,7 @@ requires = [ "uv-build>=0.9.18,<0.13" ]
|
|
|
4
4
|
|
|
5
5
|
[project]
|
|
6
6
|
name = "qldpc"
|
|
7
|
-
version = "0.4.
|
|
7
|
+
version = "0.4.2.dev20261004"
|
|
8
8
|
description = "Tools for constructing and analyzing quantum low density parity check (qLDPC) codes."
|
|
9
9
|
readme = "README.md"
|
|
10
10
|
keywords = [
|
|
@@ -90,6 +90,11 @@ ci-lint = [
|
|
|
90
90
|
"checks-superstaq>=0.5.67",
|
|
91
91
|
"pyproject-fmt>=2",
|
|
92
92
|
]
|
|
93
|
+
ci-notebooks = [
|
|
94
|
+
"jupyter>=1.1.1",
|
|
95
|
+
"matplotlib>=3.10",
|
|
96
|
+
"pip>=24",
|
|
97
|
+
]
|
|
93
98
|
ci-test = [
|
|
94
99
|
"checks-superstaq>=0.5.67",
|
|
95
100
|
"pytest>=8",
|
|
@@ -136,6 +141,7 @@ show_error_codes = true
|
|
|
136
141
|
[tool.pytest]
|
|
137
142
|
ini_options.addopts = "--disable-socket" # forbid tests from making network calls
|
|
138
143
|
ini_options.filterwarnings = [
|
|
144
|
+
"error::DeprecationWarning", # tests use the modern API
|
|
139
145
|
"ignore:(?s).*The problem is either infeasible or unbounded.*:UserWarning", # from cvxpy
|
|
140
146
|
]
|
|
141
147
|
|
|
@@ -189,9 +189,9 @@ def test_erasure_counts_as_a_discard() -> None:
|
|
|
189
189
|
|
|
190
190
|
def compile_decoder_for_dem(
|
|
191
191
|
self, dem: stim.DetectorErrorModel
|
|
192
|
-
) -> decoders.CompiledSinterDecoder:
|
|
192
|
+
) -> decoders.sinter.CompiledSinterDecoder:
|
|
193
193
|
compiled = super().compile_decoder_for_dem(dem)
|
|
194
|
-
assert isinstance(compiled, decoders.CompiledTrivialDecoder)
|
|
194
|
+
assert isinstance(compiled, decoders.sinter.CompiledTrivialDecoder)
|
|
195
195
|
compiled.packed_observable_size += 2
|
|
196
196
|
return compiled
|
|
197
197
|
|
|
@@ -10,8 +10,8 @@ by converting the physical errors that it infers into observable values.
|
|
|
10
10
|
from __future__ import annotations
|
|
11
11
|
|
|
12
12
|
import dataclasses
|
|
13
|
+
import warnings
|
|
13
14
|
from collections.abc import Mapping
|
|
14
|
-
from typing import cast
|
|
15
15
|
|
|
16
16
|
import galois
|
|
17
17
|
import numpy as np
|
|
@@ -19,6 +19,7 @@ import numpy.typing as npt
|
|
|
19
19
|
import scipy.sparse
|
|
20
20
|
import stim
|
|
21
21
|
|
|
22
|
+
from qldpc._util import get_external_caller_stacklevel
|
|
22
23
|
from qldpc.decoders.adapters.observable_decoders import (
|
|
23
24
|
BitPackedObservableDecoder,
|
|
24
25
|
ErrorsToFieldObservablesDecoder,
|
|
@@ -26,21 +27,21 @@ from qldpc.decoders.adapters.observable_decoders import (
|
|
|
26
27
|
)
|
|
27
28
|
from qldpc.decoders.capabilities import (
|
|
28
29
|
compiles_for_dem,
|
|
29
|
-
constructs_observable_decoder,
|
|
30
30
|
is_prebuilt_observable_decoder,
|
|
31
31
|
)
|
|
32
|
-
from qldpc.decoders.common import PLACEHOLDER_ERROR_RATE
|
|
33
|
-
from qldpc.decoders.construction.
|
|
34
|
-
from qldpc.decoders.construction.resolution import reject_prebuilt_decoder
|
|
32
|
+
from qldpc.decoders.common import PLACEHOLDER_ERROR_RATE, ObservableDecodingFallbackWarning
|
|
33
|
+
from qldpc.decoders.construction.factories import DEMDecoderFactory
|
|
34
|
+
from qldpc.decoders.construction.resolution import _resolve_error_decoder, reject_prebuilt_decoder
|
|
35
35
|
from qldpc.decoders.construction.specs import (
|
|
36
36
|
DecoderInput,
|
|
37
37
|
DecoderSpec,
|
|
38
|
-
ObservableDecoderConstructor,
|
|
39
38
|
)
|
|
40
39
|
from qldpc.decoders.dems import DetectorErrorModelArrays
|
|
41
40
|
from qldpc.decoders.protocols import ErrorDecoder, ObservableDecoder
|
|
42
41
|
from qldpc.decoders.sinter.core import CompiledSinterDecoder
|
|
43
42
|
|
|
43
|
+
_MAX_SPEC_REPR_LENGTH = 80 # truncate long option values in warnings
|
|
44
|
+
|
|
44
45
|
|
|
45
46
|
def get_code_capacity_dem(
|
|
46
47
|
syndrome_matrix: galois.FieldArray,
|
|
@@ -69,8 +70,8 @@ def get_code_capacity_dem(
|
|
|
69
70
|
field = type(syndrome_matrix)
|
|
70
71
|
if getattr(field, "order", 2) != 2:
|
|
71
72
|
raise ValueError(
|
|
72
|
-
"
|
|
73
|
-
f" it cannot decode a code over {field.name}. Pass decoder
|
|
73
|
+
"An observable decoder built from a Stim detector error model requires a binary code, so"
|
|
74
|
+
f" it cannot decode a code over {field.name}. Pass a decoder specification such as"
|
|
74
75
|
" decoders.guf(), or a prebuilt observable decoder (such as an ObservableLookupDecoder)"
|
|
75
76
|
" built for this code, instead"
|
|
76
77
|
)
|
|
@@ -231,44 +232,32 @@ def get_code_capacity_decoder(
|
|
|
231
232
|
) -> CodeCapacityDecoder:
|
|
232
233
|
"""Build an observable decoder for one sector of a code-capacity experiment.
|
|
233
234
|
|
|
234
|
-
Code-capacity sampling
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
Sinter decoder with a decode_shots_bit_packed method, that is not also an error decoder) is
|
|
245
|
-
used as is. It must predict the observable values ``observable_matrix @ error`` from the
|
|
246
|
-
syndrome ``syndrome_matrix @ error``.
|
|
247
|
-
- Anything else (None, decoder settings, a constructor, or a prebuilt error decoder, together
|
|
248
|
-
with any deprecated decoder_args) builds an error decoder for syndrome_matrix, exactly as
|
|
249
|
-
qldpc.decoders.resolve_decoder does. The observable values of the errors that it infers are
|
|
250
|
-
its predictions. A decoder that is both an error decoder and an observable decoder, such as a
|
|
251
|
-
RelayBPDecoder, is used as an error decoder.
|
|
252
|
-
|
|
253
|
-
A DecoderSpec with ``infers_errors=True`` builds an error decoder. A DecoderSpec with
|
|
254
|
-
``infers_errors=False``, a Sinter-style decoder, or an observable-decoder constructor builds an
|
|
255
|
-
observable decoder from the code-capacity detector error model. A prebuilt observable decoder
|
|
256
|
-
is used directly.
|
|
235
|
+
Code-capacity sampling predicts ``observable_matrix @ error`` from the syndrome
|
|
236
|
+
``syndrome_matrix @ error``. Pass a decoder specification such as ``decoders.bp_osd(...)``
|
|
237
|
+
as ``decoder=``.
|
|
238
|
+
|
|
239
|
+
For a binary code, a specification with native observable support is first built as an
|
|
240
|
+
observable decoder for the code-capacity detector error model. If that build raises a
|
|
241
|
+
ValueError, for example because the specification sets matrix-only options or the backend
|
|
242
|
+
rejects the model's structure, an ObservableDecodingFallbackWarning is emitted and an error
|
|
243
|
+
decoder is built for syndrome_matrix instead. Wrap a specification as
|
|
244
|
+
``decoders.from_matrix(spec.build)`` to select error decoding explicitly.
|
|
257
245
|
|
|
258
246
|
Args:
|
|
259
247
|
syndrome_matrix: The matrix that maps an error to its syndrome.
|
|
260
248
|
observable_matrix: The matrix that maps an error to its observable values, or None if every
|
|
261
249
|
error location is itself an observable.
|
|
262
|
-
decoder:
|
|
250
|
+
decoder: A decoder specification for this sector, or None for the default decoder.
|
|
263
251
|
decoder_args: Deprecated keyword-based decoder options, which build an error decoder.
|
|
264
252
|
dem_errors: The errors of the error mechanisms of the detector error model for which a
|
|
265
253
|
Sinter-style decoder is compiled, as columns of a matrix. Defaults to the identity
|
|
266
254
|
matrix, making each error location an error mechanism.
|
|
267
255
|
symplectic_dem_errors: Whether the detector error model has one X, Z, and Y mechanism per
|
|
268
256
|
qudit. Cannot be combined with dem_errors.
|
|
269
|
-
dem_error_weights: Relative probabilities for the detector error model's error mechanisms
|
|
270
|
-
|
|
271
|
-
|
|
257
|
+
dem_error_weights: Relative probabilities for the detector error model's error mechanisms
|
|
258
|
+
when building a native observable decoder or compiling a Sinter-style decoder. These
|
|
259
|
+
are scaled by a fixed placeholder error rate, so decoder decisions do not change when
|
|
260
|
+
the returned estimator is evaluated at different physical error rates.
|
|
272
261
|
prebuilt_rejection_reason: If not None, reject a prebuilt (error or observable) decoder,
|
|
273
262
|
with this reason; see help(qldpc.decoders.reject_prebuilt_decoder). A Sinter-style
|
|
274
263
|
decoder is compiled here, so it is not rejected.
|
|
@@ -310,8 +299,7 @@ def get_code_capacity_decoder(
|
|
|
310
299
|
require_dimensions=True,
|
|
311
300
|
)
|
|
312
301
|
|
|
313
|
-
|
|
314
|
-
if not decoder_args and (observable_spec or constructs_observable_decoder(decoder)):
|
|
302
|
+
if not decoder_args and isinstance(decoder, DEMDecoderFactory):
|
|
315
303
|
dem = get_code_capacity_dem(
|
|
316
304
|
syndrome_matrix,
|
|
317
305
|
observable_matrix,
|
|
@@ -319,26 +307,64 @@ def get_code_capacity_decoder(
|
|
|
319
307
|
symplectic_errors=symplectic_dem_errors,
|
|
320
308
|
error_probs=dem_error_probs,
|
|
321
309
|
)
|
|
322
|
-
if isinstance(decoder, DecoderSpec):
|
|
323
|
-
observable_decoder = decoder.build_observable_decoder(dem)
|
|
324
|
-
source = "A decoder spec"
|
|
325
|
-
else:
|
|
326
|
-
observable_decoder = cast(ObservableDecoderConstructor, decoder)(dem)
|
|
327
|
-
source = "An observable decoder constructor"
|
|
328
310
|
return _get_observable_code_capacity_decoder(
|
|
329
|
-
|
|
311
|
+
decoder.build(dem),
|
|
330
312
|
syndrome_matrix,
|
|
331
313
|
observable_matrix,
|
|
332
|
-
|
|
314
|
+
"A from_dem factory",
|
|
333
315
|
require_dimensions=False,
|
|
334
316
|
)
|
|
335
317
|
|
|
336
|
-
|
|
337
|
-
|
|
338
|
-
|
|
339
|
-
|
|
340
|
-
|
|
341
|
-
|
|
318
|
+
native_error: Exception | None = None
|
|
319
|
+
if not decoder_args and isinstance(decoder, DecoderSpec):
|
|
320
|
+
is_binary = getattr(type(syndrome_matrix), "order", 2) == 2
|
|
321
|
+
if not decoder.infers_errors or (is_binary and decoder.predicts_observables_natively):
|
|
322
|
+
dem = get_code_capacity_dem(
|
|
323
|
+
syndrome_matrix,
|
|
324
|
+
observable_matrix,
|
|
325
|
+
dem_errors,
|
|
326
|
+
symplectic_errors=symplectic_dem_errors,
|
|
327
|
+
error_probs=dem_error_probs,
|
|
328
|
+
)
|
|
329
|
+
if not decoder.infers_errors:
|
|
330
|
+
# an observable-only specification has nothing to fall back to
|
|
331
|
+
observable_decoder = decoder.build_observable_decoder(dem)
|
|
332
|
+
else:
|
|
333
|
+
try:
|
|
334
|
+
observable_decoder = decoder.build_observable_decoder(dem)
|
|
335
|
+
except ValueError as error:
|
|
336
|
+
native_error = error
|
|
337
|
+
if native_error is None:
|
|
338
|
+
return _get_observable_code_capacity_decoder(
|
|
339
|
+
observable_decoder,
|
|
340
|
+
syndrome_matrix,
|
|
341
|
+
observable_matrix,
|
|
342
|
+
"A decoder specification",
|
|
343
|
+
require_dimensions=False,
|
|
344
|
+
)
|
|
345
|
+
spec_repr = repr(decoder)
|
|
346
|
+
if len(spec_repr) > _MAX_SPEC_REPR_LENGTH:
|
|
347
|
+
spec_repr = spec_repr[: _MAX_SPEC_REPR_LENGTH - 4] + "...)"
|
|
348
|
+
warnings.warn(
|
|
349
|
+
f"{spec_repr} could not build an observable decoder for this code-capacity"
|
|
350
|
+
f" detector error model ({type(native_error).__name__}: {native_error}), so qLDPC"
|
|
351
|
+
" is decoding errors with the syndrome matrix instead. Pass"
|
|
352
|
+
" decoder=decoders.from_matrix(spec.build) to select error decoding explicitly",
|
|
353
|
+
ObservableDecodingFallbackWarning,
|
|
354
|
+
stacklevel=get_external_caller_stacklevel(),
|
|
355
|
+
)
|
|
356
|
+
|
|
357
|
+
try:
|
|
358
|
+
error_decoder = _resolve_error_decoder(
|
|
359
|
+
syndrome_matrix,
|
|
360
|
+
decoder, # type:ignore[arg-type]
|
|
361
|
+
decoder_args,
|
|
362
|
+
warn_deprecated=warn_deprecated,
|
|
363
|
+
)
|
|
364
|
+
except ValueError as error:
|
|
365
|
+
if native_error is not None:
|
|
366
|
+
raise error from native_error
|
|
367
|
+
raise
|
|
342
368
|
return CodeCapacityDecoder.from_error_decoder(error_decoder, syndrome_matrix, observable_matrix)
|
|
343
369
|
|
|
344
370
|
|