A package for decoding quantum error correcting codes using minimum-weight perfect matching.
Project description
PyMatching
PyMatching is a fast Python/C++ library for decoding quantum error correcting codes (QECC) using the Minimum Weight Perfect Matching (MWPM) decoder. PyMatching can decode codes for which each error generates a pair of syndrome defects (or only a single defect at a boundary). Codes that satisfy these properties include two-dimensional topological codes such as the toric code, the surface code and 2D hyperbolic codes, amongst others. PyMatching can also be used as a subroutine to decode other codes, such as the 3D toric code and the color code. PyMatching can handle boundaries, measurement errors and weighted edges in the matching graph. Since the core algorithms are written in C++, PyMatching is much faster than a pure Python NetworkX implementation.
Documentation for PyMatching can be found at: pymatching.readthedocs.io
Installation
PyMatching can be downloaded and installed from PyPI with the command:
pip install pymatching
This is the recommended way to install PyMatching since pip will fetch the pre-compiled binaries, rather than building the C++ extension from source on your machine. Note that PyMatching requires Python 3.
If instead you would like to install PyMatching from source, clone the repository (using the --recursive
flag to include the lib/pybind11 submodule) and then use pip
to install:
git clone --recursive https://github.com/oscarhiggott/PyMatching.git
pip install -e ./PyMatching
The installation may take a few minutes since the C++ extension has to be compiled. If you'd also like to run the tests, first install pytest, and then run:
pytest ./PyMatching/tests ./PyMatching/src
Usage
In order to decode a parity check matrix H
(a scipy.sparse
matrix) with syndrome vector z
(a bitstring which is a numpy array of dtype int), first construct the Matching
object after importing it:
from pymatching import Matching
m = Matching(H)
Now to decode, simply run:
c = m.decode(z)
which outputs a bitstring c
, which is a numpy array of ints corresponding to the minimum-weight correction. Note that the m
by n
parity check matrix H
should correspond to the Z (or X) stabilisers of a CSS code with n
qubits, m
Z (or X) stabilisers, and with either one or two non-zero entries per column.
To decode instead in the presence of measurement errors, each stabiliser measurement is repeated L
times, and decoding then takes place over a 3D matching graph (see Section IV B of this paper), which can be constructed directly from the check matrix H
using:
m = Matching(H, repetitions=L)
and then decoded from an m
by L
numpy array syndrome z
using:
c = m.decode(z)
The Matching object can also be constructed from a NetworkX graph instead of a check matrix, and can handle weighted edges. For full details see the documentation.
Performance
While all the functionality of PyMatching is available via the Python bindings, the core algorithms and data structures are implemented in C++, with the help of the LEMON and Boost Graph libraries. PyMatching also uses a local variant of the MWPM decoder (explained in the Appendix of this paper) that has a runtime that is approximately linear, rather than quadratic, in the number of nodes. As a result, PyMatching is orders of magnitude faster than a standard pure Python NetworkX implementation, as shown here for decoding the toric code under an independent noise model with p=0.05 and noiseless syndrome measurements:
Exact vs. local matching
PyMatching includes both the standard "exact" minimum-weight perfect matching decoder, as well as a close approximation of it, called local matching, which is much faster.
Local matching allows each node corresponding to a syndrome defect (-1 measurement) to be matched to one of the num_neighbours
defects that are closest to it in the matching graph.
By default, PyMatching uses local matching with num_neighbours=30
, but a different choice of num_neighbours
can be set when decoding, e.g.:
c = m.decode(z, num_neighbours=40)
Note that by setting num_neighbours=sum(z)
, local matching corresponds to exact matching.
Rather than setting num_neighbours=sum(z)
, an alternative option for using exact matching is provided by setting num_neighbours=None
. If this option is chosen, the shortest paths between all pairs of nodes in the matching graph are pre-computed and cached the first time m.decode
is called, and then reused for later uses of m.decode
. This differs from local matching, where shortest paths are computed on the fly.
As a result, setting num_neighbours=None
is more memory intensive than local matching, with the required memory scaling quadratically with the number of nodes in the matching graph, however for exact matching it is faster than setting num_neighbours=sum(z)
.
For typical decoding problems, local matching is an extremely close approximation of exact matching even for small num_neighbours
. The following graph shows the threshold of local matching for the toric code with noisy syndrome measurements (a 3D matching graph), as a function of num_neighbours
. For num_neighbours>=16
, the local matching threshold is consistent with the 2.92% threshold found with exact matching:
The runtime of local matching scales linearly with num_neighbours
, as shown by the following graph, generated using an L=20 toric code:
A more detailed description and analysis of local matching can be found in the PyMatching paper.
Note that PyMatching used num_neighbours=20
as a default for v0.3.1 and earlier.
Attribution
When using PyMatching for research, please cite:
@article{higgott2021pymatching,
title={{PyMatching}: A Python package for decoding quantum codes with minimum-weight perfect matching},
author={Higgott, Oscar},
journal={arXiv preprint arXiv:2105.13082},
year={2021}
}
Please also consider citing the LEMON and Boost Graph libraries.
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distributions
Hashes for PyMatching-0.5.0-cp310-cp310-musllinux_1_1_x86_64.whl
Algorithm | Hash digest | |
---|---|---|
SHA256 | 1f8f74a731295403ab2c779f46022950a0d69803aefe9b07ab2f9ff97978ad17 |
|
MD5 | 42e1d9c18aecaa03127fee05133f2049 |
|
BLAKE2b-256 | 5be78cde08195e67eecf8e97a83fc4f21bd0dbe3a70de0b775aa678bd9bed39e |
Hashes for PyMatching-0.5.0-cp310-cp310-musllinux_1_1_i686.whl
Algorithm | Hash digest | |
---|---|---|
SHA256 | af1d5ed5e6dbf08666e06a89628de60cd73e400aabf6dcb302c010129ffe7447 |
|
MD5 | 5c8ad7cc111fc4469b85d980b624912f |
|
BLAKE2b-256 | 2bfe09bed392da6177eb028067fb20b1690bc53a992707bbf2d3009b38a3ce02 |
Hashes for PyMatching-0.5.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl
Algorithm | Hash digest | |
---|---|---|
SHA256 | 403d920b18fe5d2e8df8f51517664bc0da9c036db04827e9c98c26edbc9e3607 |
|
MD5 | ad0605eaa5747bf78d583f63eec282e4 |
|
BLAKE2b-256 | 0645126bf765fb67ee122c97365f5893ceaf5d37a30c66b0e2a085232b16148a |
Hashes for PyMatching-0.5.0-cp310-cp310-manylinux_2_17_i686.manylinux2014_i686.whl
Algorithm | Hash digest | |
---|---|---|
SHA256 | 133d3fa1574b3fcf1e18e2d7e571123e954a376067726e5d861b65317c032a1b |
|
MD5 | eb807180081caa644c974a7ff7ba06ec |
|
BLAKE2b-256 | 84175cfc206f7cfef57d9de833350596707b84cf8202705560e5ee581610d7a1 |
Hashes for PyMatching-0.5.0-cp310-cp310-macosx_10_9_x86_64.whl
Algorithm | Hash digest | |
---|---|---|
SHA256 | 277f213a87988ef908fa7c740123f4a88454893f8bdadab300029afc4f274e0f |
|
MD5 | fbcb6b10d410aab706c113e92cd3dd5e |
|
BLAKE2b-256 | 7577a395b224d3093dca305df34c4e3aa85bf738d032148961646e1e34009548 |
Hashes for PyMatching-0.5.0-cp39-cp39-win_amd64.whl
Algorithm | Hash digest | |
---|---|---|
SHA256 | 16ba4994217918064e3c5dc3747250b2b7ed164344b33cfcf477049f65c2e652 |
|
MD5 | 6f376ae28bf5e2e7e86036c2eb863fa4 |
|
BLAKE2b-256 | 8468eb28db1f60a15649396799b9e78b929e2f55d0caa47c0093f55e45fca2da |
Hashes for PyMatching-0.5.0-cp39-cp39-musllinux_1_1_x86_64.whl
Algorithm | Hash digest | |
---|---|---|
SHA256 | 387ceac78d24baddf5d4baeaf20dbfda3fdcc30d6aefef542db615e76d86843d |
|
MD5 | 8778a6e1c75f536e0408e710612ba1a8 |
|
BLAKE2b-256 | 23e3d2572b702fede236ef9a55df1c5a9ed3f720f39103ad7b15834281076113 |
Hashes for PyMatching-0.5.0-cp39-cp39-musllinux_1_1_i686.whl
Algorithm | Hash digest | |
---|---|---|
SHA256 | eacbce8171615d4e1dfa4da3f9660787ec110e12d03e34409275baf0db07af30 |
|
MD5 | 1ac10cf36a21325d55d15d218915a936 |
|
BLAKE2b-256 | a0e9472ff23d14be544138a3ce88cf547ba97bf26316dd8283065a5da54da556 |
Hashes for PyMatching-0.5.0-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl
Algorithm | Hash digest | |
---|---|---|
SHA256 | 8b3b830ae3e1e49f54b048e8c3cc9806ffce7c577bfc6889d4478ca1c3d45989 |
|
MD5 | 0693547872628b1e6e13edf7c3b3c56c |
|
BLAKE2b-256 | e9581b1255b16c005479e0109b2c3677f1a3a463c387c9e481bfa1ce7fbb4ee2 |
Hashes for PyMatching-0.5.0-cp39-cp39-manylinux_2_17_i686.manylinux2014_i686.whl
Algorithm | Hash digest | |
---|---|---|
SHA256 | fca43b9584ad17af1b88ab90a9ca7c85272616f607d858c50b41fcc8b0edcde4 |
|
MD5 | 48b587591527bc9d014af50a6b385876 |
|
BLAKE2b-256 | caeb9718da649ca543ca37610babf7dd6767bade47ee29a6f28a1196f9c5d249 |
Hashes for PyMatching-0.5.0-cp39-cp39-macosx_10_9_x86_64.whl
Algorithm | Hash digest | |
---|---|---|
SHA256 | 8f5f9663737583f12bfab725107135d3303649033c8e1a057a061a25b85588c0 |
|
MD5 | 6deb7b4e41ddedca104628ce9f33ab0c |
|
BLAKE2b-256 | db0aa779272ecc55329b41a03a1dba2ed5c06db59eddba11cbd85bdfb7ab3cae |
Hashes for PyMatching-0.5.0-cp38-cp38-win_amd64.whl
Algorithm | Hash digest | |
---|---|---|
SHA256 | ede8b2d11bf73d5a7702c8776438ac5e83dc61fbdd22bc3e55be59d1815f9864 |
|
MD5 | 728e1f954da7b406a38721046c860434 |
|
BLAKE2b-256 | c9c9135fa944ab0d8e49832dd125bf6c73d9b3f2c5c97902a469bdca351cc036 |
Hashes for PyMatching-0.5.0-cp38-cp38-musllinux_1_1_x86_64.whl
Algorithm | Hash digest | |
---|---|---|
SHA256 | 351bb7c0621d71a84b1f7b93609b0eacdd3fb04f39f8913e294ec405b0449fd3 |
|
MD5 | a89d38c9685ddf204eb3ee37878faa92 |
|
BLAKE2b-256 | 36e81f515bf8764b3ab6ac1c25d95aa37d1a8119dd98899c973c4af77711ad05 |
Hashes for PyMatching-0.5.0-cp38-cp38-musllinux_1_1_i686.whl
Algorithm | Hash digest | |
---|---|---|
SHA256 | d0367e176185edd6c80db3594bb8fc75708e5c529900e7e50a7238185cf2a448 |
|
MD5 | f7b098d0bfb1a91e3a414f667969027d |
|
BLAKE2b-256 | f0c0b1ace3b62d12bfd34ef5abdefec8eb34c309b6bb0d0a5ebcc8c51000d4fe |
Hashes for PyMatching-0.5.0-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl
Algorithm | Hash digest | |
---|---|---|
SHA256 | 30f1adecdfee1628bae5b24649ad65e39938420bab17c7d49f02be54031d7031 |
|
MD5 | 4b83a671da71ba5c671870a3623cf277 |
|
BLAKE2b-256 | dcea45539e20376561320d8b2dc96b91d2fe38ea9feaf1fc316e5958dad5e827 |
Hashes for PyMatching-0.5.0-cp38-cp38-manylinux_2_17_i686.manylinux2014_i686.whl
Algorithm | Hash digest | |
---|---|---|
SHA256 | 3afc17703b704cf486b3ae685a849e84238ca4478a0d20ad528b5cf6bbf5c40f |
|
MD5 | 45ee4b6815dcf639f10941e78f5bff9a |
|
BLAKE2b-256 | c64d37266e7227d9a2da003d6e7e6c312714da0e8873d25184ee10b13b8114ff |
Hashes for PyMatching-0.5.0-cp38-cp38-macosx_10_9_x86_64.whl
Algorithm | Hash digest | |
---|---|---|
SHA256 | 5c251b09b3ccab8f8351bad5305d4f7ae16cc30ec228ad6d4dcdbfbfdb86df6a |
|
MD5 | 1e7e6440091cc46be184523764937151 |
|
BLAKE2b-256 | 6628a3280704c3ca096f9ea5752a125cf0148b9e4c5e487f3ee78c53142a2075 |
Hashes for PyMatching-0.5.0-cp37-cp37m-win_amd64.whl
Algorithm | Hash digest | |
---|---|---|
SHA256 | a2dd05f854e15c1df52fad381a77d7c323789025fd2aed5035eae14555ef3ad4 |
|
MD5 | bf2a36067536baac8b0617c3f832f255 |
|
BLAKE2b-256 | a0e97a05930a1e9810a0973cffc8902210f065174b8f2bf8294533552fd73482 |
Hashes for PyMatching-0.5.0-cp37-cp37m-musllinux_1_1_x86_64.whl
Algorithm | Hash digest | |
---|---|---|
SHA256 | 067d9eeaf0caf36263fac9f02e9df7e1abbb737ec96ba782530f5e2a78d4efc2 |
|
MD5 | d059fd265ade204a6d37ba95dc80c171 |
|
BLAKE2b-256 | fb473c37044a6ce5cf42d9ce4596eeb5afa1a3b86c5b74a6b1b138ea24477d2c |
Hashes for PyMatching-0.5.0-cp37-cp37m-musllinux_1_1_i686.whl
Algorithm | Hash digest | |
---|---|---|
SHA256 | 4231a0ab8c4d3eb2b7583c0708c2a069c86b13e497f4f4fbc7b93fd4ebe7002f |
|
MD5 | 6a20bd5cb0f05a46657785b00e5442ee |
|
BLAKE2b-256 | d80f7c2bcd708bbab8186f4c57c959459c75f0166ae4848dff5c1ed4a20d729d |
Hashes for PyMatching-0.5.0-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl
Algorithm | Hash digest | |
---|---|---|
SHA256 | aad03f49036b67848a3b84ba16d2c179416c927734c735e78d450813f84480ed |
|
MD5 | 83931cfd89d5ecdbeb196be6350c5841 |
|
BLAKE2b-256 | 1f5b4d475c0b14cafc1d5ecd4ee4d4275b051ba825cf0cdb86af17ec83b24a61 |
Hashes for PyMatching-0.5.0-cp37-cp37m-manylinux_2_17_i686.manylinux2014_i686.whl
Algorithm | Hash digest | |
---|---|---|
SHA256 | 9f2116e42c8eeac87222646709cba2f5691d8a93eeeaf8bb076ffc5d7ee006a2 |
|
MD5 | 950f89fb9349763571d40a6c403a6edb |
|
BLAKE2b-256 | fcb4223168a69badbc55e903a4eed755c5a2196eeb88a69a69767b064e3774c0 |
Hashes for PyMatching-0.5.0-cp37-cp37m-macosx_10_9_x86_64.whl
Algorithm | Hash digest | |
---|---|---|
SHA256 | 292eae7da27b25a4b197becffa7440af5adfb6a0452778d43416faf07f3910cd |
|
MD5 | 76a5830ca8a1342a455e06acbfd73614 |
|
BLAKE2b-256 | f9267df46abe2c695b4690a2f666aeade2794624853792d35a21febd15c96309 |
Hashes for PyMatching-0.5.0-cp36-cp36m-win_amd64.whl
Algorithm | Hash digest | |
---|---|---|
SHA256 | d6aea1437c14b703abec198702e613db0df3463cdd11dd21a01ec935d786d1f0 |
|
MD5 | 5de49a07d0d123043b655f2669ed0f96 |
|
BLAKE2b-256 | 908489038f71ab508abf3dac85c641200338c481d5dce1aaeb1df960bff5254a |
Hashes for PyMatching-0.5.0-cp36-cp36m-musllinux_1_1_x86_64.whl
Algorithm | Hash digest | |
---|---|---|
SHA256 | 1947990e1ab1524e0264b326889d3956f9b15ed36299775c08019203cc489917 |
|
MD5 | 761b9e598c8d787ff696c55d2d3701c4 |
|
BLAKE2b-256 | eb8b2c822aabfd3b506b62577a2575052a29855dbb7bbe806022d44eb7d16bc5 |
Hashes for PyMatching-0.5.0-cp36-cp36m-musllinux_1_1_i686.whl
Algorithm | Hash digest | |
---|---|---|
SHA256 | 30253c1e20d10d003635670f3af112632e704eb37c20f4323759a80bd52a5a1c |
|
MD5 | e56f07c9ac2795779611215cd3058c99 |
|
BLAKE2b-256 | 4f7904bf949d9078a454b0a23659192079f6259509d3674e04bc9df2d3e2b326 |
Hashes for PyMatching-0.5.0-cp36-cp36m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl
Algorithm | Hash digest | |
---|---|---|
SHA256 | c9db24652c657a54b95e0438e5e03a0e74be42b888a8be7d75e4c6db17d93a52 |
|
MD5 | 733770cdb07cff5f736154b0154639c1 |
|
BLAKE2b-256 | 3c8cdfcb8262aa521566069315dcf46bd0f1d27c0ee896e7a0bcd520164258e4 |
Hashes for PyMatching-0.5.0-cp36-cp36m-manylinux_2_17_i686.manylinux2014_i686.whl
Algorithm | Hash digest | |
---|---|---|
SHA256 | 810470594857778906cd5d88b633a44294df0f56dd9d1b5a687d5ec96b02674f |
|
MD5 | 7c6d7937363c5d805043fb8c149a5ccb |
|
BLAKE2b-256 | a0404582e0146cea7c0634e2b454d56db57902302fed04776a615083cc253b16 |
Hashes for PyMatching-0.5.0-cp36-cp36m-macosx_10_9_x86_64.whl
Algorithm | Hash digest | |
---|---|---|
SHA256 | 960e8ed921233f342232c3f301561b9d5fde5fc85f501d4f80e207e0a0beb5b0 |
|
MD5 | 8c1b5663f97dedc5c9e983537b93c771 |
|
BLAKE2b-256 | d92874f7cacac16b400e4a63cbfd30efeeb71d293cb7303b93a012b304d76c85 |