Skip to content

v0.4.1

Latest

Choose a tag to compare

@perlinm perlinm released this 03 Oct 03:14
· 96 commits to main since this release
d6896d6

qLDPC v0.4.1

This release adds the Tesseract and Frontier decoders, introduces a settings-based way to build decoders, and improves code retrieval and distance tracking.

Important

This release contains small breaking changes to decoder imports and options.
See Migrating from qLDPC 0.4.0 before upgrading.

Highlights

  • Settings-based decoder construction (#636). Every decoder is now configured with a settings helper and then built:
    decoders.bp_osd(...).build(pcm_or_dem) or decoders.mwpm(...).build_observable_decoder(dem).
    Settings helpers for ldpc, PyMatching, and Relay-BP accept other backend options through a backend_options mapping.
  • Tesseract decoder (#635): decoders.tesseract(...), decoders.tesseract_preset(...), and decoders.TesseractDecoder.
    Install it with pip install 'qldpc[tesseract]' (Python ≥ 3.12, platforms with published wheels).
  • Frontier observable decoder (#634): decoders.frontier(...) and decoders.FrontierObservableDecoder, which integrate the separately installed Frontier pruned maximum-likelihood decoder for binary detector error models.
  • Lookup decoder upgrades (#633): a probability_cutoff option that skips unlikely errors when building the table, and support for correlated error channels given as a callable over full errors.

Other improvements

  • qLDPC Challenge codes (#629): QuditCode.from_qldpc_challenge_id(...) and CSSCode.from_qldpc_challenge_id(...) load verified submissions, including non-CSS stabilizer codes, together with their certified distance bounds.
  • QECDB retrieval fixed (#629) to use QECDB's current JSON API.
  • Best known distance bounds (#630): codes remember the best distance upper bound they have found or been given, with separate X and Z bounds for CSS codes.
    get_distance_bound() now defaults to num_trials=None, which returns the exact distance or best known bound if available, and otherwise computes a single bound.
    A call with explicit trials never returns a worse bound than the best known one.
  • Cache refresh (#631): functions decorated with qldpc.cache.use_disk_cache have a .refresh(...) method, with the same signature, that recomputes the result and overwrites its cache entry.
    This release also fixes two caching bugs: calling get_generators without its optional keyword crashed, and calling the group-intersection function with keyword arguments failed.
  • Python 3.14 development installs (#628). The in-process GAP binding (libgap) requires Python 3.13; other versions use an executable GAP.
  • New qldpc[decoders] extra that installs the optional decoder backends available for your platform.

Breaking changes

  • qldpc.decoders.construction, qldpc.decoders.custom, qldpc.decoders.external, and qldpc.decoders.construction.specs no longer re-export decoder builders, settings helpers, or resolution functions.
    Import these from qldpc.decoders instead.
  • Builders that were never exported from qldpc.decoders have been removed, for example get_error_decoder_mwpm, get_observable_decoder_mwpm, get_relay_bp_decoder, get_min_sum_bp_decoder, and get_observable_decoder_lookup.
    Use settings helpers and their build / build_observable_decoder methods.
  • Passing error_channel or error_rate together with a detector error model now raises a ValueError, because the model supplies its own probabilities.
    Previously, the ldpc decoders (BP+OSD, BP+LSD, BF) ignored error_rate here and let error_channel override the model's probabilities.
    To override them, decode the model's detector-flip matrix, which serves as a parity-check matrix, and map predicted errors to observables yourself:
    arrays = decoders.DetectorErrorModelArrays(dem),
    decoder = decoders.bp_osd(error_channel=p).build(arrays.detector_flip_matrix), and
    observables = arrays.observable_flip_matrix @ decoder.decode(syndrome) % 2.
  • get_decoder_mwpm and get_decoder(..., with_MWPM=True) now reject options that PyMatching would silently ignore, and reserve faults_matrix for decoders.mwpm(...).build_observable_decoder(dem).

Deprecations

Each of the following still works, but emits a DeprecationWarning that names its replacement:

Deprecated Replacement
error_rate=p error_channel=p
decoders.get_decoder_<NAME>(pcm_or_dem, ...) decoders.<NAME>(...).build(pcm_or_dem)
decoders.get_decoder_rbp(...) decoders.relay_bp(...) or decoders.min_sum_bp(...), then .build(...)
decoders.get_error_decoder(pcm_or_dem, decoder=settings) settings.build(pcm_or_dem)
decoders.get_observable_decoder(dem, decoder=settings) settings.build_observable_decoder(dem)
decoders.get_observable_decoder(dem, decoder=error_decoder) decoders.ErrorsToObservablesDecoder(error_decoder, dem)
decoders.decode_observables(dem, syndrome, decoder=settings) settings.build_observable_decoder(dem).decode_observables(syndrome)
decoders.lookup_table(...) decoders.lookup(...)
penalty_func= (lookup decoders) a callable error_channel

Internal

  • One-sentence-per-line formatting for documentation sources (#632).
  • Reorganized decoder modules into sections, moving code without changing it (#637).

Full changelog: v0.4.0...v0.4.1