qldpc 0.3.3__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.3.3/PKG-INFO +163 -0
- qldpc-0.3.3/README.md +111 -0
- qldpc-0.3.3/pyproject.toml +109 -0
- qldpc-0.3.3/src/qldpc/__init__.py +17 -0
- qldpc-0.3.3/src/qldpc/_util.py +68 -0
- qldpc-0.3.3/src/qldpc/_util_test.py +54 -0
- qldpc-0.3.3/src/qldpc/abstract/__init__.py +68 -0
- qldpc-0.3.3/src/qldpc/abstract/groups.py +1022 -0
- qldpc-0.3.3/src/qldpc/abstract/groups_test.py +314 -0
- qldpc-0.3.3/src/qldpc/abstract/linalg.py +192 -0
- qldpc-0.3.3/src/qldpc/abstract/linalg_test.py +122 -0
- qldpc-0.3.3/src/qldpc/abstract/rings.py +1146 -0
- qldpc-0.3.3/src/qldpc/abstract/rings_test.py +318 -0
- qldpc-0.3.3/src/qldpc/abstract/wedderburn_artin.py +918 -0
- qldpc-0.3.3/src/qldpc/abstract/wedderburn_artin_test.py +172 -0
- qldpc-0.3.3/src/qldpc/cache.py +103 -0
- qldpc-0.3.3/src/qldpc/cache_test.py +70 -0
- qldpc-0.3.3/src/qldpc/circuits/__init__.py +101 -0
- qldpc-0.3.3/src/qldpc/circuits/benchmarking.py +430 -0
- qldpc-0.3.3/src/qldpc/circuits/benchmarking_test.py +152 -0
- qldpc-0.3.3/src/qldpc/circuits/bookkeeping.py +292 -0
- qldpc-0.3.3/src/qldpc/circuits/bookkeeping_test.py +97 -0
- qldpc-0.3.3/src/qldpc/circuits/common.py +181 -0
- qldpc-0.3.3/src/qldpc/circuits/common_test.py +113 -0
- qldpc-0.3.3/src/qldpc/circuits/encoding.py +311 -0
- qldpc-0.3.3/src/qldpc/circuits/encoding_test.py +169 -0
- qldpc-0.3.3/src/qldpc/circuits/memory/__init__.py +27 -0
- qldpc-0.3.3/src/qldpc/circuits/memory/alpha_syndrome.py +377 -0
- qldpc-0.3.3/src/qldpc/circuits/memory/alpha_syndrome_test.py +83 -0
- qldpc-0.3.3/src/qldpc/circuits/memory/memory.py +550 -0
- qldpc-0.3.3/src/qldpc/circuits/memory/memory_test.py +112 -0
- qldpc-0.3.3/src/qldpc/circuits/memory/syndrome_measurement.py +193 -0
- qldpc-0.3.3/src/qldpc/circuits/memory/syndrome_measurement_test.py +127 -0
- qldpc-0.3.3/src/qldpc/circuits/noise_model.py +1873 -0
- qldpc-0.3.3/src/qldpc/circuits/noise_model_test.py +1206 -0
- qldpc-0.3.3/src/qldpc/circuits/transversal.py +499 -0
- qldpc-0.3.3/src/qldpc/circuits/transversal_test.py +149 -0
- qldpc-0.3.3/src/qldpc/codes/__init__.py +101 -0
- qldpc-0.3.3/src/qldpc/codes/classical.py +409 -0
- qldpc-0.3.3/src/qldpc/codes/classical_test.py +122 -0
- qldpc-0.3.3/src/qldpc/codes/common.py +3586 -0
- qldpc-0.3.3/src/qldpc/codes/common_test.py +897 -0
- qldpc-0.3.3/src/qldpc/codes/distance.py +351 -0
- qldpc-0.3.3/src/qldpc/codes/distance_test.py +622 -0
- qldpc-0.3.3/src/qldpc/codes/quantum.py +2558 -0
- qldpc-0.3.3/src/qldpc/codes/quantum_test.py +795 -0
- qldpc-0.3.3/src/qldpc/conftest.py +54 -0
- qldpc-0.3.3/src/qldpc/decoders/__init__.py +75 -0
- qldpc-0.3.3/src/qldpc/decoders/custom.py +1031 -0
- qldpc-0.3.3/src/qldpc/decoders/custom_test.py +374 -0
- qldpc-0.3.3/src/qldpc/decoders/dems.py +614 -0
- qldpc-0.3.3/src/qldpc/decoders/dems_test.py +314 -0
- qldpc-0.3.3/src/qldpc/decoders/retrieval.py +332 -0
- qldpc-0.3.3/src/qldpc/decoders/retrieval_test.py +82 -0
- qldpc-0.3.3/src/qldpc/decoders/sinter.py +793 -0
- qldpc-0.3.3/src/qldpc/decoders/sinter_test.py +250 -0
- qldpc-0.3.3/src/qldpc/external/__init__.py +3 -0
- qldpc-0.3.3/src/qldpc/external/codes.py +196 -0
- qldpc-0.3.3/src/qldpc/external/codes_test.py +88 -0
- qldpc-0.3.3/src/qldpc/external/gap.py +191 -0
- qldpc-0.3.3/src/qldpc/external/gap_test.py +161 -0
- qldpc-0.3.3/src/qldpc/external/groups.py +657 -0
- qldpc-0.3.3/src/qldpc/external/groups_test.py +292 -0
- qldpc-0.3.3/src/qldpc/math.py +363 -0
- qldpc-0.3.3/src/qldpc/math_test.py +134 -0
- qldpc-0.3.3/src/qldpc/objects.py +582 -0
- qldpc-0.3.3/src/qldpc/objects_test.py +154 -0
- qldpc-0.3.3/src/qldpc/py.typed +0 -0
qldpc-0.3.3/PKG-INFO
ADDED
|
@@ -0,0 +1,163 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: qldpc
|
|
3
|
+
Version: 0.3.3
|
|
4
|
+
Summary: Tools for constructing and analyzing quantum low density parity check (qLDPC) codes.
|
|
5
|
+
Keywords: LDPC,low density parity check codes,quantum computing,quantum error correction
|
|
6
|
+
Author: Michael A. Perlin
|
|
7
|
+
Author-email: Michael A. Perlin <mika.perlin@gmail.com>
|
|
8
|
+
License-Expression: Apache-2.0
|
|
9
|
+
Classifier: Development Status :: 3 - Alpha
|
|
10
|
+
Classifier: Intended Audience :: Science/Research
|
|
11
|
+
Classifier: Natural Language :: English
|
|
12
|
+
Classifier: Programming Language :: Python :: 3 :: Only
|
|
13
|
+
Classifier: Programming Language :: Python :: 3.10
|
|
14
|
+
Classifier: Programming Language :: Python :: 3.11
|
|
15
|
+
Classifier: Programming Language :: Python :: 3.12
|
|
16
|
+
Classifier: Programming Language :: Python :: 3.13
|
|
17
|
+
Classifier: Topic :: Scientific/Engineering :: Mathematics
|
|
18
|
+
Classifier: Topic :: Scientific/Engineering :: Physics
|
|
19
|
+
Requires-Dist: cvxpy>=1.3.2
|
|
20
|
+
Requires-Dist: diskcache>=5
|
|
21
|
+
Requires-Dist: galois>=0.4.2
|
|
22
|
+
Requires-Dist: ldpc>=2.4.1
|
|
23
|
+
Requires-Dist: networkx>=2.6.2
|
|
24
|
+
Requires-Dist: numpy>=1.24
|
|
25
|
+
Requires-Dist: platformdirs>=4
|
|
26
|
+
Requires-Dist: pymatching>=2.1
|
|
27
|
+
Requires-Dist: pyperclip>=1.11
|
|
28
|
+
Requires-Dist: scipy>=1.14.1
|
|
29
|
+
Requires-Dist: sinter>=1.16
|
|
30
|
+
Requires-Dist: stim>=1.16
|
|
31
|
+
Requires-Dist: sympy>=1.12
|
|
32
|
+
Requires-Dist: checks-superstaq>=0.5.62 ; extra == 'dev'
|
|
33
|
+
Requires-Dist: jupyter>=1.1.1 ; extra == 'dev'
|
|
34
|
+
Requires-Dist: pypandoc-binary>=1.13 ; extra == 'dev'
|
|
35
|
+
Requires-Dist: pyproject-fmt>=2 ; extra == 'dev'
|
|
36
|
+
Requires-Dist: python-lsp-server[all]>=1.14 ; extra == 'dev'
|
|
37
|
+
Requires-Dist: qldpc[docs,relay-bp,tsim] ; extra == 'dev'
|
|
38
|
+
Requires-Dist: ipython>=8 ; extra == 'docs'
|
|
39
|
+
Requires-Dist: nbsphinx>=0.9 ; extra == 'docs'
|
|
40
|
+
Requires-Dist: sphinx>=7 ; extra == 'docs'
|
|
41
|
+
Requires-Dist: sphinx-autoapi>=3 ; extra == 'docs'
|
|
42
|
+
Requires-Dist: sphinx-rtd-theme>=2 ; extra == 'docs'
|
|
43
|
+
Requires-Dist: relay-bp[stim]==0.2.1 ; extra == 'relay-bp'
|
|
44
|
+
Requires-Dist: bloqade-tsim>=0.1.4 ; extra == 'tsim'
|
|
45
|
+
Requires-Python: >=3.10
|
|
46
|
+
Project-URL: Repository, https://github.com/qLDPCOrg/qLDPC
|
|
47
|
+
Provides-Extra: dev
|
|
48
|
+
Provides-Extra: docs
|
|
49
|
+
Provides-Extra: relay-bp
|
|
50
|
+
Provides-Extra: tsim
|
|
51
|
+
Description-Content-Type: text/markdown
|
|
52
|
+
|
|
53
|
+
# qLDPC
|
|
54
|
+
|
|
55
|
+
This library contains tools for constructing and analyzing [quantum low density parity check (qLDPC) codes](https://errorcorrectionzoo.org/c/qldpc). At least, that was the original motivation for this library. In practice, the tools here work just as well for [stabilizer](https://errorcorrectionzoo.org/c/stabilizer) and [subsystem](https://errorcorrectionzoo.org/c/oecc) codes more broadly.
|
|
56
|
+
|
|
57
|
+
In a nutshell, `qLDPC` provides methods to build a variety of built-in and custom codes, represented under the hood by a parity check matrix. Once a code is constructed, `qLDPC` automates various tasks of common interest, integrating with a variety of external tools (including [`ldpc`](https://github.com/quantumgizmos/ldpc), [`stim`](https://github.com/quantumlib/Stim), [`sinter`](https://pypi.org/project/sinter), [`QDistRnd`](https://docs.gap-system.org/pkg/qdistrnd/doc/chap1_mj.html), and [`MAGMA`](https://magma.maths.usyd.edu.au/magma), among others). Automated tasks include:
|
|
58
|
+
- constructing a code from a variety of code families,
|
|
59
|
+
- constructing a canonical basis of logical Pauli operators,
|
|
60
|
+
- computing (or upper-bounding) code distance,
|
|
61
|
+
- computing logical error rates in a code-capacity model,
|
|
62
|
+
- computing the logical error rates and post-selection rates of state preparation circuits,
|
|
63
|
+
- constructing circuits of interest, such as memory experiments and logical encoding circuits,
|
|
64
|
+
- defining custom Pauli noise models,
|
|
65
|
+
- using a decoder of your choice for any of the above (or other, unlisted) tasks.
|
|
66
|
+
|
|
67
|
+
See the [`examples`](https://github.com/qLDPCOrg/qLDPC/tree/main/examples) directory for some demonstrations and use-cases.
|
|
68
|
+
|
|
69
|
+
Where possible, this library strives to support codes over arbitrary finite (Galois) fields -- that is, for Galois qudits of any prime power dimension. Circuit-related utilities are, however, limited to qubit codes.
|
|
70
|
+
|
|
71
|
+
## 📦 Installation
|
|
72
|
+
|
|
73
|
+
This library requires Python>=3.10, and can be installed from the Python Package Index (PyPI) with
|
|
74
|
+
```
|
|
75
|
+
pip install qldpc
|
|
76
|
+
```
|
|
77
|
+
|
|
78
|
+
To install a local version of qLDPC from source:
|
|
79
|
+
```
|
|
80
|
+
git clone https://github.com/qLDPCOrg/qLDPC.git
|
|
81
|
+
pip install -e qLDPC
|
|
82
|
+
```
|
|
83
|
+
You can also `pip install -e 'qLDPC[dev]'` to additionally install some development tools.
|
|
84
|
+
|
|
85
|
+
### GAP
|
|
86
|
+
|
|
87
|
+
Some features in `qLDPC` require an installation of the [GAP](https://www.gap-system.org) computer algebra system. If you (a) use Linux or macOS, and (b) use `conda` to manage your python environment, then you can obtain GAP by running
|
|
88
|
+
```
|
|
89
|
+
conda install -c conda-forge gap
|
|
90
|
+
```
|
|
91
|
+
or `conda install -c conda-forge gap-core`. Installations without `conda` should also work, as long as `gap` is a recognized command in the command line. Unfortunately, [GAP](https://www.gap-system.org) integration is clunky in Windows because I have not figured out how to call [GAP](https://www.gap-system.org) from the Windows command prompt. If you figure this out, [please let me know](https://github.com/qLDPCOrg/qLDPC/issues/294)!
|
|
92
|
+
|
|
93
|
+
### macOS
|
|
94
|
+
|
|
95
|
+
If you use macOS you may need to install `cvxpy` manually by following the instructions [here](https://www.cvxpy.org/install) before installing `qLDPC`. If you use `conda` to manage your python environment, you can obtain `cvxpy` by running
|
|
96
|
+
```
|
|
97
|
+
conda install -c conda-forge cvxpy
|
|
98
|
+
```
|
|
99
|
+
|
|
100
|
+
## 🚀 Features
|
|
101
|
+
|
|
102
|
+
Notable features include:
|
|
103
|
+
- `ClassicalCode`: class for representing classical linear error-correcting codes over finite fields.
|
|
104
|
+
- Various pre-defined classical code families, including `RepetitionCode`, `HammingCode`, `SimplexCode`, `ReedMullerCode`, `ReedSolomonCode`, `TannerCode`, and more.
|
|
105
|
+
- Communication with the [GAP](https://www.gap-system.org)/[`GUAVA`](https://www.gap-system.org/Packages/guava.html) package for [even more codes](https://docs.gap-system.org/pkg/guava/doc/chap5.html).
|
|
106
|
+
- `QuditCode`: class for constructing [Galois-qudit codes](https://errorcorrectionzoo.org/c/galois_into_galois), including both [stabilizer](https://errorcorrectionzoo.org/c/galois_stabilizer) and [subsystem](https://errorcorrectionzoo.org/c/oecc) codes.
|
|
107
|
+
- `QuditCode.get_logical_ops`: method to construct a complete basis of nontrivial logical Pauli operators for a `QuditCode`.
|
|
108
|
+
- `QuditCode.get_distance`: method to compute the exact code distance of a `QuditCode` (i.e., the minimum weight of a nontrivial logical operator). Includes options to compute an upper bound on code distance using [`QDistRnd`](https://docs.gap-system.org/pkg/qdistrnd/doc/chap1_mj.html) or (for CSS codes) a decoder-based method introduced in [arXiv:2308.07915](https://arxiv.org/abs/2308.07915).
|
|
109
|
+
- `QuditCode.concatenate`: method to [concatenate](https://errorcorrectionzoo.org/c/quantum_concatenated) `QuditCode`s in various ways.
|
|
110
|
+
- `CSSCode`: subclass of `QuditCode` for the special case of constructing a [quantum CSS code](https://errorcorrectionzoo.org/c/css) out of two mutually compatible `ClassicalCode`s. Special cases (subclasses) with specialized constructors and helper methods include:
|
|
111
|
+
- Common codes such as the `SteaneCode` and `TetrahedralCode`.
|
|
112
|
+
- Common code families such as the `SurfaceCode`, `ToricCode`, `BaconShorCode`, and `QuantumHammingCode`.
|
|
113
|
+
- `TBCode`: [two-block quantum codes](https://errorcorrectionzoo.org/c/two_block_quantum).
|
|
114
|
+
- `QCCode`: quasi-cyclic two-block codes (also known as [multivariate bicycle codes](https://arxiv.org/abs/2406.19151), generalizing the `BBCode` below).
|
|
115
|
+
- `BBCode`: [bivariate bicycle codes](https://errorcorrectionzoo.org/c/quantum_quasi_cyclic), as in [arXiv:2308.07915](https://arxiv.org/abs/2308.07915) and [arXiv:2311.16980](https://arxiv.org/abs/2311.16980). See also [`examples/bivariate_bicycle_codes.ipynb`](https://github.com/qLDPCOrg/qLDPC/blob/main/examples/bivariate_bicycle_codes.ipynb).
|
|
116
|
+
- `HGPCode`: [hypergraph product codes](https://errorcorrectionzoo.org/c/hypergraph_product), first introduced in [arXiv:0903.0566](https://arxiv.org/abs/0903.0566).
|
|
117
|
+
- `CHGPCode` / `CRCode`: cyclic hypergraph product and repeated cyclic hypergraph product codes, as in [arXiv:2511.09683](https://arxiv.org/abs/2511.09683).
|
|
118
|
+
- `SHPCode`: [subsystem hypergraph product codes](https://errorcorrectionzoo.org/c/subsystem_quantum_parity), as in [arXiv:2002.06257](https://arxiv.org/abs/2002.06257).
|
|
119
|
+
- `SHYPSCode`: [subsystem hypergraph product simplex codes](https://errorcorrectionzoo.org/c/shyps), as in [arXiv:2502.07150](https://arxiv.org/abs/2502.07150).
|
|
120
|
+
- `LPCode`: [lifted product codes](https://errorcorrectionzoo.org/c/lifted_product), as in [arXiv:2012.04068](https://arxiv.org/abs/2012.04068) and [arXiv:2202.01702](https://arxiv.org/abs/2202.01702).
|
|
121
|
+
- `SLPCode`: [subsystem lifted product codes](https://errorcorrectionzoo.org/c/subsystem_lifted_product), as in [arXiv:2404.18302](https://arxiv.org/abs/2404.18302).
|
|
122
|
+
- `QTCode`: [quantum Tanner codes](https://errorcorrectionzoo.org/c/quantum_tanner), as in [arXiv:2202.13641](https://arxiv.org/abs/2202.13641), [arXiv:2206.07571](https://arxiv.org/abs/2206.07571), and [arXiv:2508.05095](https://arxiv.org/abs/2508.05095).
|
|
123
|
+
- `qldpc.decoders`: module for decoding code and circuit errors.
|
|
124
|
+
- BP-OSD, BP-LSD, and belief-find (via [`ldpc`](https://github.com/quantumgizmos/ldpc)), Relay-BP (via [`relay-bp`](https://pypi.org/project/relay-bp)), minimum-weight perfect matching (via [`pymatching`](https://github.com/oscarhiggott/PyMatching)), lookup-table decoding, and others. Includes an interface for using custom decoders.
|
|
125
|
+
- `SinterDecoder`: class to construct circuit-level decoders that are usable by [`sinter`](https://pypi.org/project/sinter).
|
|
126
|
+
- `SlidingWindowDecoder`: the overlapping-recovery sliding-window decoder of [arXiv:quant-ph/0110143](https://arxiv.org/abs/quant-ph/0110143) and [arXiv:2209.08552](https://arxiv.org/abs/2209.08552).
|
|
127
|
+
- `SequentialWindowDecoder`: a generalization of the `SlidingWindowDecoder` for arbitrary decoding and commit regions.
|
|
128
|
+
- `DetectorErrorModelArrays`: representation of a `stim.DetectorErrorModel` with `scipy.sparse` and `numpy` arrays (`detector_flip_matrix`, `observable_flip_matrix`, `error_probs`).
|
|
129
|
+
- `qldpc.circuits`: module for [`stim`](https://github.com/quantumlib/Stim) circuits and circuit utilities, including:
|
|
130
|
+
- `get_memory_experiment`: circuit to test the performance of a code as a quantum memory (using various pre-built syndrome measurement strategies), appropriately annotated with detectors and observables.
|
|
131
|
+
- `get_state_prep_diagnostic_circuit`, `get_state_prep_diagnostic_tasks`, `get_logical_error_and_discard_rate`: helper methods for computing the logical error rates and post-selection rates of state preparation circuits.
|
|
132
|
+
- `NoiseModel`: class for constructing expressive Pauli noise models, which map noiseless circuits to noisy circuits. Built-in subclasses include a single-parameter `DepolarizingNoiseModel` and a superconducting-inspired `SI1000NoiseModel`.
|
|
133
|
+
- `get_encoding_circuit`: circuit to encode physical states of qubits into logical states of a code, for example to prepare a logical all-|0> state. (Warning: current encoding circuits are not fault-tolerant. The construction of fault-tolerant encoding circuits is an [open issue](https://github.com/qLDPCOrg/qLDPC/issues/327).)
|
|
134
|
+
- `get_transversal_ops`: logical tableaus and physical circuits for the SWAP-transversal logical Clifford gates of a code, constructed via the code automorphism method of [arXiv:2409.18175](https://arxiv.org/abs/2409.18175). (Warning: exponential complexity.)
|
|
135
|
+
- `get_transversal_circuit`: find a SWAP-transversal physical circuit (if any) that implements a given logical Clifford operation in a code. (Warning: exponential complexity.)
|
|
136
|
+
- `qldpc.abstract`: module for abstract algebra (groups, rings, modules, and representations thereof).
|
|
137
|
+
- Various pre-defined groups (mostly borrowed from [SymPy](https://docs.sympy.org/latest/modules/combinatorics/named_groups.html)).
|
|
138
|
+
- Communication with the [GAP](https://www.gap-system.org) computer algebra system and [GroupNames.org](https://people.maths.bris.ac.uk/~matyd/GroupNames) for constructing [even more groups](https://docs.gap-system.org/doc/ref/chap50.html).
|
|
139
|
+
- `qldpc.objects`: module for constructing helper objects such as Cayley complexes and chain complexes, which are instrumental for the construction of various quantum codes.
|
|
140
|
+
|
|
141
|
+
## 🤔 Questions and issues
|
|
142
|
+
|
|
143
|
+
This project aspires to one day have a proper [documentation page](https://qldpc.readthedocs.io/en/latest). In the meantime, I recommend looking at source code and the detailed comments therein, as well as `help(qldpc.object_of_interest)`. `qLDPC` requires every file (such as [`src/qldpc/codes/quantum.py`](https://github.com/qLDPCOrg/qLDPC/blob/main/src/qldpc/codes/quantum.py)) to be covered by its own test file (such as [`src/qldpc/codes/quantum_test.py`](https://github.com/qLDPCOrg/qLDPC/blob/main/src/qldpc/codes/quantum_test.py)), so test files are a good place to look for example usage of any function, class, etc. Finally, the [`examples`](https://github.com/qLDPCOrg/qLDPC/tree/main/examples) directory has some helpful notebooks to get you started.
|
|
144
|
+
|
|
145
|
+
If you have any questions, feedback, or requests, please [open an issue on GitHub](https://github.com/qLDPCOrg/qLDPC/issues/new) or email me at [mika.perlin@gmail.com](mailto:mika.perlin@gmail.com)!
|
|
146
|
+
|
|
147
|
+
## ⚓ Attribution
|
|
148
|
+
|
|
149
|
+
If you use this software in your work, please cite with:
|
|
150
|
+
```
|
|
151
|
+
@misc{perlin2023qldpc,
|
|
152
|
+
author = {Perlin, Michael A.},
|
|
153
|
+
title = {{qLDPC}},
|
|
154
|
+
year = {2023},
|
|
155
|
+
publisher = {GitHub},
|
|
156
|
+
journal = {GitHub repository},
|
|
157
|
+
howpublished = {\url{https://github.com/qLDPCOrg/qLDPC}},
|
|
158
|
+
}
|
|
159
|
+
```
|
|
160
|
+
This may require adding `\usepackage{url}` to your LaTeX file header. Alternatively, you can cite
|
|
161
|
+
```
|
|
162
|
+
Michael A. Perlin. qLDPC. https://github.com/qLDPCOrg/qLDPC, 2023.
|
|
163
|
+
```
|
qldpc-0.3.3/README.md
ADDED
|
@@ -0,0 +1,111 @@
|
|
|
1
|
+
# qLDPC
|
|
2
|
+
|
|
3
|
+
This library contains tools for constructing and analyzing [quantum low density parity check (qLDPC) codes](https://errorcorrectionzoo.org/c/qldpc). At least, that was the original motivation for this library. In practice, the tools here work just as well for [stabilizer](https://errorcorrectionzoo.org/c/stabilizer) and [subsystem](https://errorcorrectionzoo.org/c/oecc) codes more broadly.
|
|
4
|
+
|
|
5
|
+
In a nutshell, `qLDPC` provides methods to build a variety of built-in and custom codes, represented under the hood by a parity check matrix. Once a code is constructed, `qLDPC` automates various tasks of common interest, integrating with a variety of external tools (including [`ldpc`](https://github.com/quantumgizmos/ldpc), [`stim`](https://github.com/quantumlib/Stim), [`sinter`](https://pypi.org/project/sinter), [`QDistRnd`](https://docs.gap-system.org/pkg/qdistrnd/doc/chap1_mj.html), and [`MAGMA`](https://magma.maths.usyd.edu.au/magma), among others). Automated tasks include:
|
|
6
|
+
- constructing a code from a variety of code families,
|
|
7
|
+
- constructing a canonical basis of logical Pauli operators,
|
|
8
|
+
- computing (or upper-bounding) code distance,
|
|
9
|
+
- computing logical error rates in a code-capacity model,
|
|
10
|
+
- computing the logical error rates and post-selection rates of state preparation circuits,
|
|
11
|
+
- constructing circuits of interest, such as memory experiments and logical encoding circuits,
|
|
12
|
+
- defining custom Pauli noise models,
|
|
13
|
+
- using a decoder of your choice for any of the above (or other, unlisted) tasks.
|
|
14
|
+
|
|
15
|
+
See the [`examples`](https://github.com/qLDPCOrg/qLDPC/tree/main/examples) directory for some demonstrations and use-cases.
|
|
16
|
+
|
|
17
|
+
Where possible, this library strives to support codes over arbitrary finite (Galois) fields -- that is, for Galois qudits of any prime power dimension. Circuit-related utilities are, however, limited to qubit codes.
|
|
18
|
+
|
|
19
|
+
## 📦 Installation
|
|
20
|
+
|
|
21
|
+
This library requires Python>=3.10, and can be installed from the Python Package Index (PyPI) with
|
|
22
|
+
```
|
|
23
|
+
pip install qldpc
|
|
24
|
+
```
|
|
25
|
+
|
|
26
|
+
To install a local version of qLDPC from source:
|
|
27
|
+
```
|
|
28
|
+
git clone https://github.com/qLDPCOrg/qLDPC.git
|
|
29
|
+
pip install -e qLDPC
|
|
30
|
+
```
|
|
31
|
+
You can also `pip install -e 'qLDPC[dev]'` to additionally install some development tools.
|
|
32
|
+
|
|
33
|
+
### GAP
|
|
34
|
+
|
|
35
|
+
Some features in `qLDPC` require an installation of the [GAP](https://www.gap-system.org) computer algebra system. If you (a) use Linux or macOS, and (b) use `conda` to manage your python environment, then you can obtain GAP by running
|
|
36
|
+
```
|
|
37
|
+
conda install -c conda-forge gap
|
|
38
|
+
```
|
|
39
|
+
or `conda install -c conda-forge gap-core`. Installations without `conda` should also work, as long as `gap` is a recognized command in the command line. Unfortunately, [GAP](https://www.gap-system.org) integration is clunky in Windows because I have not figured out how to call [GAP](https://www.gap-system.org) from the Windows command prompt. If you figure this out, [please let me know](https://github.com/qLDPCOrg/qLDPC/issues/294)!
|
|
40
|
+
|
|
41
|
+
### macOS
|
|
42
|
+
|
|
43
|
+
If you use macOS you may need to install `cvxpy` manually by following the instructions [here](https://www.cvxpy.org/install) before installing `qLDPC`. If you use `conda` to manage your python environment, you can obtain `cvxpy` by running
|
|
44
|
+
```
|
|
45
|
+
conda install -c conda-forge cvxpy
|
|
46
|
+
```
|
|
47
|
+
|
|
48
|
+
## 🚀 Features
|
|
49
|
+
|
|
50
|
+
Notable features include:
|
|
51
|
+
- `ClassicalCode`: class for representing classical linear error-correcting codes over finite fields.
|
|
52
|
+
- Various pre-defined classical code families, including `RepetitionCode`, `HammingCode`, `SimplexCode`, `ReedMullerCode`, `ReedSolomonCode`, `TannerCode`, and more.
|
|
53
|
+
- Communication with the [GAP](https://www.gap-system.org)/[`GUAVA`](https://www.gap-system.org/Packages/guava.html) package for [even more codes](https://docs.gap-system.org/pkg/guava/doc/chap5.html).
|
|
54
|
+
- `QuditCode`: class for constructing [Galois-qudit codes](https://errorcorrectionzoo.org/c/galois_into_galois), including both [stabilizer](https://errorcorrectionzoo.org/c/galois_stabilizer) and [subsystem](https://errorcorrectionzoo.org/c/oecc) codes.
|
|
55
|
+
- `QuditCode.get_logical_ops`: method to construct a complete basis of nontrivial logical Pauli operators for a `QuditCode`.
|
|
56
|
+
- `QuditCode.get_distance`: method to compute the exact code distance of a `QuditCode` (i.e., the minimum weight of a nontrivial logical operator). Includes options to compute an upper bound on code distance using [`QDistRnd`](https://docs.gap-system.org/pkg/qdistrnd/doc/chap1_mj.html) or (for CSS codes) a decoder-based method introduced in [arXiv:2308.07915](https://arxiv.org/abs/2308.07915).
|
|
57
|
+
- `QuditCode.concatenate`: method to [concatenate](https://errorcorrectionzoo.org/c/quantum_concatenated) `QuditCode`s in various ways.
|
|
58
|
+
- `CSSCode`: subclass of `QuditCode` for the special case of constructing a [quantum CSS code](https://errorcorrectionzoo.org/c/css) out of two mutually compatible `ClassicalCode`s. Special cases (subclasses) with specialized constructors and helper methods include:
|
|
59
|
+
- Common codes such as the `SteaneCode` and `TetrahedralCode`.
|
|
60
|
+
- Common code families such as the `SurfaceCode`, `ToricCode`, `BaconShorCode`, and `QuantumHammingCode`.
|
|
61
|
+
- `TBCode`: [two-block quantum codes](https://errorcorrectionzoo.org/c/two_block_quantum).
|
|
62
|
+
- `QCCode`: quasi-cyclic two-block codes (also known as [multivariate bicycle codes](https://arxiv.org/abs/2406.19151), generalizing the `BBCode` below).
|
|
63
|
+
- `BBCode`: [bivariate bicycle codes](https://errorcorrectionzoo.org/c/quantum_quasi_cyclic), as in [arXiv:2308.07915](https://arxiv.org/abs/2308.07915) and [arXiv:2311.16980](https://arxiv.org/abs/2311.16980). See also [`examples/bivariate_bicycle_codes.ipynb`](https://github.com/qLDPCOrg/qLDPC/blob/main/examples/bivariate_bicycle_codes.ipynb).
|
|
64
|
+
- `HGPCode`: [hypergraph product codes](https://errorcorrectionzoo.org/c/hypergraph_product), first introduced in [arXiv:0903.0566](https://arxiv.org/abs/0903.0566).
|
|
65
|
+
- `CHGPCode` / `CRCode`: cyclic hypergraph product and repeated cyclic hypergraph product codes, as in [arXiv:2511.09683](https://arxiv.org/abs/2511.09683).
|
|
66
|
+
- `SHPCode`: [subsystem hypergraph product codes](https://errorcorrectionzoo.org/c/subsystem_quantum_parity), as in [arXiv:2002.06257](https://arxiv.org/abs/2002.06257).
|
|
67
|
+
- `SHYPSCode`: [subsystem hypergraph product simplex codes](https://errorcorrectionzoo.org/c/shyps), as in [arXiv:2502.07150](https://arxiv.org/abs/2502.07150).
|
|
68
|
+
- `LPCode`: [lifted product codes](https://errorcorrectionzoo.org/c/lifted_product), as in [arXiv:2012.04068](https://arxiv.org/abs/2012.04068) and [arXiv:2202.01702](https://arxiv.org/abs/2202.01702).
|
|
69
|
+
- `SLPCode`: [subsystem lifted product codes](https://errorcorrectionzoo.org/c/subsystem_lifted_product), as in [arXiv:2404.18302](https://arxiv.org/abs/2404.18302).
|
|
70
|
+
- `QTCode`: [quantum Tanner codes](https://errorcorrectionzoo.org/c/quantum_tanner), as in [arXiv:2202.13641](https://arxiv.org/abs/2202.13641), [arXiv:2206.07571](https://arxiv.org/abs/2206.07571), and [arXiv:2508.05095](https://arxiv.org/abs/2508.05095).
|
|
71
|
+
- `qldpc.decoders`: module for decoding code and circuit errors.
|
|
72
|
+
- BP-OSD, BP-LSD, and belief-find (via [`ldpc`](https://github.com/quantumgizmos/ldpc)), Relay-BP (via [`relay-bp`](https://pypi.org/project/relay-bp)), minimum-weight perfect matching (via [`pymatching`](https://github.com/oscarhiggott/PyMatching)), lookup-table decoding, and others. Includes an interface for using custom decoders.
|
|
73
|
+
- `SinterDecoder`: class to construct circuit-level decoders that are usable by [`sinter`](https://pypi.org/project/sinter).
|
|
74
|
+
- `SlidingWindowDecoder`: the overlapping-recovery sliding-window decoder of [arXiv:quant-ph/0110143](https://arxiv.org/abs/quant-ph/0110143) and [arXiv:2209.08552](https://arxiv.org/abs/2209.08552).
|
|
75
|
+
- `SequentialWindowDecoder`: a generalization of the `SlidingWindowDecoder` for arbitrary decoding and commit regions.
|
|
76
|
+
- `DetectorErrorModelArrays`: representation of a `stim.DetectorErrorModel` with `scipy.sparse` and `numpy` arrays (`detector_flip_matrix`, `observable_flip_matrix`, `error_probs`).
|
|
77
|
+
- `qldpc.circuits`: module for [`stim`](https://github.com/quantumlib/Stim) circuits and circuit utilities, including:
|
|
78
|
+
- `get_memory_experiment`: circuit to test the performance of a code as a quantum memory (using various pre-built syndrome measurement strategies), appropriately annotated with detectors and observables.
|
|
79
|
+
- `get_state_prep_diagnostic_circuit`, `get_state_prep_diagnostic_tasks`, `get_logical_error_and_discard_rate`: helper methods for computing the logical error rates and post-selection rates of state preparation circuits.
|
|
80
|
+
- `NoiseModel`: class for constructing expressive Pauli noise models, which map noiseless circuits to noisy circuits. Built-in subclasses include a single-parameter `DepolarizingNoiseModel` and a superconducting-inspired `SI1000NoiseModel`.
|
|
81
|
+
- `get_encoding_circuit`: circuit to encode physical states of qubits into logical states of a code, for example to prepare a logical all-|0> state. (Warning: current encoding circuits are not fault-tolerant. The construction of fault-tolerant encoding circuits is an [open issue](https://github.com/qLDPCOrg/qLDPC/issues/327).)
|
|
82
|
+
- `get_transversal_ops`: logical tableaus and physical circuits for the SWAP-transversal logical Clifford gates of a code, constructed via the code automorphism method of [arXiv:2409.18175](https://arxiv.org/abs/2409.18175). (Warning: exponential complexity.)
|
|
83
|
+
- `get_transversal_circuit`: find a SWAP-transversal physical circuit (if any) that implements a given logical Clifford operation in a code. (Warning: exponential complexity.)
|
|
84
|
+
- `qldpc.abstract`: module for abstract algebra (groups, rings, modules, and representations thereof).
|
|
85
|
+
- Various pre-defined groups (mostly borrowed from [SymPy](https://docs.sympy.org/latest/modules/combinatorics/named_groups.html)).
|
|
86
|
+
- Communication with the [GAP](https://www.gap-system.org) computer algebra system and [GroupNames.org](https://people.maths.bris.ac.uk/~matyd/GroupNames) for constructing [even more groups](https://docs.gap-system.org/doc/ref/chap50.html).
|
|
87
|
+
- `qldpc.objects`: module for constructing helper objects such as Cayley complexes and chain complexes, which are instrumental for the construction of various quantum codes.
|
|
88
|
+
|
|
89
|
+
## 🤔 Questions and issues
|
|
90
|
+
|
|
91
|
+
This project aspires to one day have a proper [documentation page](https://qldpc.readthedocs.io/en/latest). In the meantime, I recommend looking at source code and the detailed comments therein, as well as `help(qldpc.object_of_interest)`. `qLDPC` requires every file (such as [`src/qldpc/codes/quantum.py`](https://github.com/qLDPCOrg/qLDPC/blob/main/src/qldpc/codes/quantum.py)) to be covered by its own test file (such as [`src/qldpc/codes/quantum_test.py`](https://github.com/qLDPCOrg/qLDPC/blob/main/src/qldpc/codes/quantum_test.py)), so test files are a good place to look for example usage of any function, class, etc. Finally, the [`examples`](https://github.com/qLDPCOrg/qLDPC/tree/main/examples) directory has some helpful notebooks to get you started.
|
|
92
|
+
|
|
93
|
+
If you have any questions, feedback, or requests, please [open an issue on GitHub](https://github.com/qLDPCOrg/qLDPC/issues/new) or email me at [mika.perlin@gmail.com](mailto:mika.perlin@gmail.com)!
|
|
94
|
+
|
|
95
|
+
## ⚓ Attribution
|
|
96
|
+
|
|
97
|
+
If you use this software in your work, please cite with:
|
|
98
|
+
```
|
|
99
|
+
@misc{perlin2023qldpc,
|
|
100
|
+
author = {Perlin, Michael A.},
|
|
101
|
+
title = {{qLDPC}},
|
|
102
|
+
year = {2023},
|
|
103
|
+
publisher = {GitHub},
|
|
104
|
+
journal = {GitHub repository},
|
|
105
|
+
howpublished = {\url{https://github.com/qLDPCOrg/qLDPC}},
|
|
106
|
+
}
|
|
107
|
+
```
|
|
108
|
+
This may require adding `\usepackage{url}` to your LaTeX file header. Alternatively, you can cite
|
|
109
|
+
```
|
|
110
|
+
Michael A. Perlin. qLDPC. https://github.com/qLDPCOrg/qLDPC, 2023.
|
|
111
|
+
```
|
|
@@ -0,0 +1,109 @@
|
|
|
1
|
+
[build-system]
|
|
2
|
+
build-backend = "uv_build"
|
|
3
|
+
requires = [ "uv-build>=0.9.18,<0.10" ]
|
|
4
|
+
|
|
5
|
+
[project]
|
|
6
|
+
name = "qldpc"
|
|
7
|
+
version = "0.3.3"
|
|
8
|
+
description = "Tools for constructing and analyzing quantum low density parity check (qLDPC) codes."
|
|
9
|
+
readme = "README.md"
|
|
10
|
+
keywords = [
|
|
11
|
+
"LDPC",
|
|
12
|
+
"low density parity check codes",
|
|
13
|
+
"quantum computing",
|
|
14
|
+
"quantum error correction",
|
|
15
|
+
]
|
|
16
|
+
license = "Apache-2.0"
|
|
17
|
+
authors = [ { name = "Michael A. Perlin", email = "mika.perlin@gmail.com" } ]
|
|
18
|
+
requires-python = ">=3.10"
|
|
19
|
+
classifiers = [
|
|
20
|
+
"Development Status :: 3 - Alpha",
|
|
21
|
+
"Intended Audience :: Science/Research",
|
|
22
|
+
"Natural Language :: English",
|
|
23
|
+
"Programming Language :: Python :: 3 :: Only",
|
|
24
|
+
"Programming Language :: Python :: 3.10",
|
|
25
|
+
"Programming Language :: Python :: 3.11",
|
|
26
|
+
"Programming Language :: Python :: 3.12",
|
|
27
|
+
"Programming Language :: Python :: 3.13",
|
|
28
|
+
"Topic :: Scientific/Engineering :: Mathematics",
|
|
29
|
+
"Topic :: Scientific/Engineering :: Physics",
|
|
30
|
+
]
|
|
31
|
+
dependencies = [
|
|
32
|
+
"cvxpy>=1.3.2",
|
|
33
|
+
"diskcache>=5",
|
|
34
|
+
"galois>=0.4.2",
|
|
35
|
+
"ldpc>=2.4.1",
|
|
36
|
+
"networkx>=2.6.2",
|
|
37
|
+
"numpy>=1.24",
|
|
38
|
+
"platformdirs>=4",
|
|
39
|
+
"pymatching>=2.1",
|
|
40
|
+
"pyperclip>=1.11",
|
|
41
|
+
"scipy>=1.14.1",
|
|
42
|
+
"sinter>=1.16",
|
|
43
|
+
"stim>=1.16",
|
|
44
|
+
"sympy>=1.12",
|
|
45
|
+
]
|
|
46
|
+
optional-dependencies.dev = [
|
|
47
|
+
"checks-superstaq>=0.5.62",
|
|
48
|
+
"jupyter>=1.1.1",
|
|
49
|
+
"pypandoc-binary>=1.13", # bundles pandoc for building the notebook docs locally
|
|
50
|
+
"pyproject-fmt>=2", # pyproject.toml formatting, run by checks/format_.py
|
|
51
|
+
"python-lsp-server[all]>=1.14",
|
|
52
|
+
"qldpc[docs,relay-bp,tsim]",
|
|
53
|
+
]
|
|
54
|
+
optional-dependencies.docs = [
|
|
55
|
+
"ipython>=8", # for nbsphinx's IPython.sphinxext.ipython_console_highlighting extension
|
|
56
|
+
"nbsphinx>=0.9",
|
|
57
|
+
"sphinx>=7",
|
|
58
|
+
"sphinx-autoapi>=3",
|
|
59
|
+
"sphinx-rtd-theme>=2",
|
|
60
|
+
]
|
|
61
|
+
optional-dependencies.relay-bp = [ "relay-bp[stim]==0.2.1" ]
|
|
62
|
+
optional-dependencies.tsim = [ "bloqade-tsim>=0.1.4" ]
|
|
63
|
+
urls.Repository = "https://github.com/qLDPCOrg/qLDPC"
|
|
64
|
+
|
|
65
|
+
# Check script configuration:
|
|
66
|
+
[tool.ruff]
|
|
67
|
+
line-length = 100
|
|
68
|
+
lint.extend-select = [
|
|
69
|
+
"ANN204", # return-type annotations on special methods (e.g. __init__)
|
|
70
|
+
"D205", # blank line between a docstring's summary and its body
|
|
71
|
+
"D212", # multi-line docstring summary starts on the first line
|
|
72
|
+
"D415", # docstring summary ends with punctuation (. ? !)
|
|
73
|
+
"D417", # a documented function documents all of its arguments
|
|
74
|
+
"I", # sorted / grouped imports (isort)
|
|
75
|
+
"RUF022", # sorted __all__ in __init__.py files
|
|
76
|
+
"W505", # docstring & comment line length (see max-doc-length below)
|
|
77
|
+
]
|
|
78
|
+
lint.pycodestyle.max-doc-length = 100
|
|
79
|
+
lint.pydocstyle.convention = "google"
|
|
80
|
+
|
|
81
|
+
[tool.pyproject-fmt]
|
|
82
|
+
# Cap the auto-generated "Programming Language :: Python" classifiers at the highest supported/tested
|
|
83
|
+
# Python, so the set stays accurate and stable across pyproject-fmt versions.
|
|
84
|
+
max_supported_python = "3.13"
|
|
85
|
+
|
|
86
|
+
[tool.mypy]
|
|
87
|
+
ignore_missing_imports = true
|
|
88
|
+
disallow_any_generics = true
|
|
89
|
+
disallow_untyped_defs = true
|
|
90
|
+
disallow_incomplete_defs = true
|
|
91
|
+
warn_unused_ignores = true
|
|
92
|
+
pretty = true
|
|
93
|
+
install_types = true
|
|
94
|
+
no_implicit_optional = true
|
|
95
|
+
non_interactive = true
|
|
96
|
+
show_error_codes = true
|
|
97
|
+
|
|
98
|
+
[tool.pytest]
|
|
99
|
+
ini_options.addopts = "--disable-socket" # forbid tests from making network calls
|
|
100
|
+
ini_options.filterwarnings = [
|
|
101
|
+
"ignore:(?s).*The problem is either infeasible or unbounded.*:UserWarning", # from cvxpy
|
|
102
|
+
]
|
|
103
|
+
|
|
104
|
+
[tool.coverage]
|
|
105
|
+
run.include = [ "./*" ]
|
|
106
|
+
report.exclude_lines = [ "if TYPE_CHECKING:", "pragma: no cover" ]
|
|
107
|
+
report.fail_under = 100
|
|
108
|
+
report.show_missing = true
|
|
109
|
+
report.skip_covered = true
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import importlib.metadata
|
|
2
|
+
|
|
3
|
+
from . import abstract, cache, circuits, codes, decoders, external, math, objects
|
|
4
|
+
|
|
5
|
+
__version__ = importlib.metadata.version("qldpc")
|
|
6
|
+
|
|
7
|
+
__all__ = [
|
|
8
|
+
"__version__",
|
|
9
|
+
"abstract",
|
|
10
|
+
"cache",
|
|
11
|
+
"circuits",
|
|
12
|
+
"codes",
|
|
13
|
+
"decoders",
|
|
14
|
+
"external",
|
|
15
|
+
"math",
|
|
16
|
+
"objects",
|
|
17
|
+
]
|
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
"""Miscellaneous internal utilities.
|
|
2
|
+
|
|
3
|
+
Copyright 2023 The qLDPC Authors and Infleqtion Inc.
|
|
4
|
+
|
|
5
|
+
Licensed under the Apache License, Version 2.0 (the "License");
|
|
6
|
+
you may not use this file except in compliance with the License.
|
|
7
|
+
You may obtain a copy of the License at
|
|
8
|
+
|
|
9
|
+
http://www.apache.org/licenses/LICENSE-2.0
|
|
10
|
+
|
|
11
|
+
Unless required by applicable law or agreed to in writing, software
|
|
12
|
+
distributed under the License is distributed on an "AS IS" BASIS,
|
|
13
|
+
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
14
|
+
See the License for the specific language governing permissions and
|
|
15
|
+
limitations under the License.
|
|
16
|
+
"""
|
|
17
|
+
|
|
18
|
+
from __future__ import annotations
|
|
19
|
+
|
|
20
|
+
import importlib.util
|
|
21
|
+
import sys
|
|
22
|
+
from collections.abc import Callable
|
|
23
|
+
from types import ModuleType
|
|
24
|
+
from typing import TYPE_CHECKING, TypeVar
|
|
25
|
+
|
|
26
|
+
CallableType = TypeVar("CallableType", bound=Callable[..., object])
|
|
27
|
+
|
|
28
|
+
|
|
29
|
+
def lazy_import(name: str) -> ModuleType:
|
|
30
|
+
"""Import a module lazily, deferring its execution until its first attribute access.
|
|
31
|
+
|
|
32
|
+
Uses importlib.util.LazyLoader so a heavy but rarely-used dependency stays out of ``import
|
|
33
|
+
qldpc`` while call sites keep using ``module.attr`` exactly as if it had been imported eagerly.
|
|
34
|
+
"""
|
|
35
|
+
if (module := sys.modules.get(name)) is not None:
|
|
36
|
+
return module
|
|
37
|
+
spec = importlib.util.find_spec(name)
|
|
38
|
+
assert spec is not None and spec.loader is not None
|
|
39
|
+
spec.loader = importlib.util.LazyLoader(spec.loader)
|
|
40
|
+
module = importlib.util.module_from_spec(spec)
|
|
41
|
+
sys.modules[name] = module
|
|
42
|
+
spec.loader.exec_module(module)
|
|
43
|
+
return module
|
|
44
|
+
|
|
45
|
+
|
|
46
|
+
# networkx is loaded lazily to keep it and its ~110 ms import out of ``import qldpc``.
|
|
47
|
+
# Call sites import it as ``from qldpc._util import networkx as nx``.
|
|
48
|
+
if TYPE_CHECKING:
|
|
49
|
+
import networkx
|
|
50
|
+
else:
|
|
51
|
+
networkx = lazy_import("networkx")
|
|
52
|
+
|
|
53
|
+
|
|
54
|
+
def format_docstring(**substitutions: object) -> Callable[[CallableType], CallableType]:
|
|
55
|
+
"""Substitute named values into a function's docstring via str.format.
|
|
56
|
+
|
|
57
|
+
This lets a docstring reference values (such as module-level constants) by name, for example
|
|
58
|
+
"Default: {error_rate}.", without making the docstring an f-string. An f-string cannot be used
|
|
59
|
+
as a docstring: Python evaluates it as an ordinary expression and leaves __doc__ set to None,
|
|
60
|
+
silently discarding the documentation.
|
|
61
|
+
"""
|
|
62
|
+
|
|
63
|
+
def decorator(func: CallableType) -> CallableType:
|
|
64
|
+
if func.__doc__ is not None:
|
|
65
|
+
func.__doc__ = func.__doc__.format(**substitutions)
|
|
66
|
+
return func
|
|
67
|
+
|
|
68
|
+
return decorator
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
"""Unit tests for _util.py.
|
|
2
|
+
|
|
3
|
+
Copyright 2023 The qLDPC Authors and Infleqtion Inc.
|
|
4
|
+
|
|
5
|
+
Licensed under the Apache License, Version 2.0 (the "License");
|
|
6
|
+
you may not use this file except in compliance with the License.
|
|
7
|
+
You may obtain a copy of the License at
|
|
8
|
+
|
|
9
|
+
http://www.apache.org/licenses/LICENSE-2.0
|
|
10
|
+
|
|
11
|
+
Unless required by applicable law or agreed to in writing, software
|
|
12
|
+
distributed under the License is distributed on an "AS IS" BASIS,
|
|
13
|
+
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
14
|
+
See the License for the specific language governing permissions and
|
|
15
|
+
limitations under the License.
|
|
16
|
+
"""
|
|
17
|
+
|
|
18
|
+
import sys
|
|
19
|
+
from types import ModuleType
|
|
20
|
+
|
|
21
|
+
from qldpc._util import format_docstring, lazy_import
|
|
22
|
+
|
|
23
|
+
|
|
24
|
+
def test_lazy_import() -> None:
|
|
25
|
+
"""A lazily imported module is only executed on first attribute access."""
|
|
26
|
+
name = "colorsys" # a small stdlib module not otherwise imported by the test suite
|
|
27
|
+
sys.modules.pop(name, None)
|
|
28
|
+
|
|
29
|
+
module = lazy_import(name) # uncached path
|
|
30
|
+
assert isinstance(module, ModuleType)
|
|
31
|
+
assert callable(module.rgb_to_hls) # force the deferred execution
|
|
32
|
+
|
|
33
|
+
assert lazy_import(name) is module # cached path returns the same module
|
|
34
|
+
|
|
35
|
+
|
|
36
|
+
def test_format_docstring() -> None:
|
|
37
|
+
"""Named values are substituted into a docstring."""
|
|
38
|
+
|
|
39
|
+
@format_docstring(value=1e-3, name="tag")
|
|
40
|
+
def func() -> None:
|
|
41
|
+
"""A docstring with a {value} and a {name}."""
|
|
42
|
+
|
|
43
|
+
assert func.__doc__ == "A docstring with a 0.001 and a tag."
|
|
44
|
+
|
|
45
|
+
|
|
46
|
+
def test_format_docstring_without_docstring() -> None:
|
|
47
|
+
"""A function without a docstring is left untouched."""
|
|
48
|
+
|
|
49
|
+
@format_docstring(value=1)
|
|
50
|
+
def func() -> None:
|
|
51
|
+
return None
|
|
52
|
+
|
|
53
|
+
assert func.__doc__ is None
|
|
54
|
+
assert func() is None
|
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
from .groups import (
|
|
2
|
+
PSL,
|
|
3
|
+
SL,
|
|
4
|
+
AbelianGroup,
|
|
5
|
+
AlternatingGroup,
|
|
6
|
+
CyclicGroup,
|
|
7
|
+
DihedralGroup,
|
|
8
|
+
Group,
|
|
9
|
+
GroupMember,
|
|
10
|
+
ProjectiveSpecialLinearGroup,
|
|
11
|
+
QuaternionGroup,
|
|
12
|
+
SmallGroup,
|
|
13
|
+
SpecialLinearGroup,
|
|
14
|
+
SymmetricGroup,
|
|
15
|
+
TrivialGroup,
|
|
16
|
+
get_coefficient_and_exponents,
|
|
17
|
+
iter_monomial_terms,
|
|
18
|
+
resolve_field,
|
|
19
|
+
)
|
|
20
|
+
from .linalg import (
|
|
21
|
+
block_diag,
|
|
22
|
+
get_howell_dual,
|
|
23
|
+
kron,
|
|
24
|
+
matmul,
|
|
25
|
+
)
|
|
26
|
+
from .rings import (
|
|
27
|
+
Element,
|
|
28
|
+
GroupRing,
|
|
29
|
+
Protograph,
|
|
30
|
+
RingArray,
|
|
31
|
+
RingMember,
|
|
32
|
+
)
|
|
33
|
+
from .wedderburn_artin import (
|
|
34
|
+
WedderburnArtinComponentTransformer,
|
|
35
|
+
WedderburnArtinTransformer,
|
|
36
|
+
)
|
|
37
|
+
|
|
38
|
+
__all__ = [
|
|
39
|
+
"GF2",
|
|
40
|
+
"PSL",
|
|
41
|
+
"SL",
|
|
42
|
+
"AbelianGroup",
|
|
43
|
+
"AlternatingGroup",
|
|
44
|
+
"CyclicGroup",
|
|
45
|
+
"DihedralGroup",
|
|
46
|
+
"Element",
|
|
47
|
+
"Group",
|
|
48
|
+
"GroupMember",
|
|
49
|
+
"GroupRing",
|
|
50
|
+
"ProjectiveSpecialLinearGroup",
|
|
51
|
+
"Protograph",
|
|
52
|
+
"QuaternionGroup",
|
|
53
|
+
"RingArray",
|
|
54
|
+
"RingMember",
|
|
55
|
+
"SmallGroup",
|
|
56
|
+
"SpecialLinearGroup",
|
|
57
|
+
"SymmetricGroup",
|
|
58
|
+
"TrivialGroup",
|
|
59
|
+
"WedderburnArtinComponentTransformer",
|
|
60
|
+
"WedderburnArtinTransformer",
|
|
61
|
+
"block_diag",
|
|
62
|
+
"get_coefficient_and_exponents",
|
|
63
|
+
"get_howell_dual",
|
|
64
|
+
"iter_monomial_terms",
|
|
65
|
+
"kron",
|
|
66
|
+
"matmul",
|
|
67
|
+
"resolve_field",
|
|
68
|
+
]
|