Skip to content

Add option to load TesseractDecoder from check matrices #153

@oscarhiggott

Description

@oscarhiggott

What is your feature request?

A useful representation of the QEC decoding problem is in terms of a detector check matrix H, a logical observable matrix L and a vector of priors p. For a reference on how these related to a detector error model, see section 2 of this paper. Sometimes it can be useful to decode straight from the detector check matrix and logicals matrix, rather than needing to convert to a circuit or DEM first.

In this tutorial we provided a method to convert a stabilizer code into a code-capacity circuit to be decoded by Tesseract, but this served a more specific purpose of generating code-capacity circuits from the stabilizers alone. Decoding from the (H, L, p) representation is a bit more generic, as it captures the structure of any detector error model (ignoring annotations and decompositions, which Tesseract mostly doesn't use anyway). The purpose of allowing this for configuring a TesseractDecoder is to allow researchers to options for configuring tesseract, and a common representation of decoding problems is of this form, using scipy sparse matrices.

For example, the way I currently would get around this is to use this python glue code to convert H, L and p to a DEM first:

def check_matrices_to_detector_error_model(
    check_matrix: scipy.sparse.spmatrix,
    observables_matrix: scipy.sparse.spmatrix,
    priors: np.ndarray
) -> stim.DetectorErrorModel:
    """Converts check matrices to a detector error model.

    Parameters
    ----------
    check_matrix : scipy.sparse.spmatrix
        A detector check matrix H. H[i,j] is 1 if detector i is flipped by
        error j, and is 0 otherwise.
    observables_matrix: scipy.sparse.spmatrix
        A logical observables matrix. L[i,j] is 1 if logical observable i is flipped
        by error j, and is 0 otherwise.
    priors: np.ndarray[float]
        A numpy array
        
    Returns
    -------
    stim.DetectorErrorModel
        A detector error model described by the sparse matrices.
    """
    # Ensure matrices are csc for fast iteration over columns
    H = csc_matrix(check_matrix)
    H.eliminate_zeros()
    L = csc_matrix(observables_matrix)
    L.eliminate_zeros()

    num_errors = H.shape[1]

    dem = stim.DetectorErrorModel()

    for i in range(num_errors):
        dets = H.indices[H.indptr[i] : H.indptr[i + 1]]
        obs = L.indices[L.indptr[i] : L.indptr[i + 1]]
        prob = priors[i]
        targets = []
        for d in dets:
            targets.append(stim.target_relative_detector_id(d))
        for o in obs:
            targets.append(stim.target_logical_observable_id(o))

        dem.append(stim.DemInstruction(type="error", args=[prob], targets=targets))

    return dem

but this is clearly not optimized for speed (python code, unnecessarily creating a DEM). It would be better if this was an option available for loading a TesseractConfig and/or TesseractDecoder directly, for ease of use and efficiency.

For an example of how I added similar functionality to pymatching, see these lines of code, although note that here only graphlike errors (flipping one or two detectors) were being considered and special-cased of course due to the constraints of pymatching.

What solution or approach do you envision?

No response

How urgent is this for you?

None

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions