4
$\begingroup$

I am working with stim's excellent code generator together with pymatching, using stim's generated error model and the glue code in the tutorial here. I am trying to understand better what the output of the decoder means. Specifically, is it correct to say that the output of the decoder xor the logical observable, sampled using OBSERVABLE_INCLUDE, gives the output of a "stanard" decoder, created using a matching matrix and specifying the number of repetitions as arguments to pymatching's Matching constructor?

To clarify what I mean, I created a simple example of a distance 3 repetition code, which I decode using both the stim error model based decoder and the "conventionally" defined decoder. I am using an example generated by calling

repc = stim.Circuit.generated(
    "repetition_code:memory",
    rounds=1,
    distance=3)

and adapting it to include an error on qubits 0 and 2 with probability 0.5:

repc = stim.Circuit('''
    R 0 1 2 3 4
    TICK
    CX 0 1 2 3
    TICK
    CX 2 1 4 3
    TICK
    MR 1 3
    DETECTOR(1, 0) rec[-2]
    DETECTOR(3, 0) rec[-1]

    X_ERROR(0.5) 0 2

    M 0 2 4
    DETECTOR(1, 1) rec[-2] rec[-3] rec[-5]
    DETECTOR(3, 1) rec[-1] rec[-2] rec[-4]
    OBSERVABLE_INCLUDE(0) rec[-1]
''')

m = detector_error_model_to_pymatching_graph(repc.detector_error_model(decompose_errors=True))
shots = repc.compile_detector_sampler().sample(1, append_observables=True)[0]
observable = shots[-1]
print('observable = ', observable)

# decode using glue code and error model
expanded_det = np.resize(shots[:-1], repc.num_detectors + 1)
expanded_det[-1] = 0
print('error model decode', m.decode(expanded_det))

# decode using matching matrix
detector_events = expanded_det[:-1].reshape(-1, 2)
print(detector_events)
m_matrix = pymatching.Matching([[1, 1, 0], [0, 1, 1]], repetitions=2)
print('matrix decode', m_matrix.decode(detector_events.T))

First of all, would it be possible to clarify why the logical observable was chosen to be qubit 4 (rather than, say 0^2^4)?

Secondly, in a shot where there are errors both on 0 and on 2, the output is:

observable =  0
error model decode [0]
[[0 0]
 [0 1]]
matrix decode [0 0 1]

In this case my naive expectation would be that the error model decoder will want to flip the logical bit (which would result in a logical error), which is what the conventional decoder does. Does that make sense? If not, I'd be really happy to understand better how to interpret the result of the decoder.

$\endgroup$

1 Answer 1

2
$\begingroup$

is it correct to say that the output of the decoder xor the logical observable, sampled using OBSERVABLE_INCLUDE, gives the output of a "stanard" decoder, created using a matching matrix and specifying the number of repetitions as arguments to pymatching's Matching constructor?

The output from pymatching is a need-to-flip bit. It says whether to keep or flip the logical observable's uncorrected measurement result in order to get the corrected logical measurement result.

I'm not sure what a 'standard' decoder outputs. In my experience it's somewhat common for the decoder to output a set of edges, with no understanding of the logical observables at all, instead of a corrected-result bit or a need-to-flip bit.

would it be possible to clarify why the logical observable was chosen to be qubit 4 (rather than, say 0^2^4)?

Picking all data qubits will blow up in your face if you ever use an even code distance.

It doesn't matter which set of data qubits you use to define the observable in the rep code, as long as it's an odd number of the data qubits. Picking just one is simpler than picking more than one.

in a shot where there are errors both on 0 and on 2 [...] my naive expectation would be that the error model decoder will want to flip the logical bit

Why would it? Even if your logical observable was $Z_0 Z_2 Z_4$, because you bit flipped both 0 and 2 you had no overall effect on the observable.

$$(-Z_0) (-Z_2) Z_4 = --Z_0 Z_2 Z_4 = +Z_0 Z_2 Z_4$$

If you had defined the observable to be just $Z_2$, or just $Z_0$, then you would need to flip.

$\endgroup$
4
  • $\begingroup$ Thank you! this is super informative, since this together with your answers to the question about optimality of MWPM really helped me understand the basic idea better. What I meant by "standard" decoder is MWPM. So do you think your decoder is better/worse than MWPM? Also, why would you ever use an even distance code? Doesn't it allow to correct for the same number of maximum errors as the odd distance code with d-1? $\endgroup$
    – Lior
    Feb 9 at 8:51
  • 1
    $\begingroup$ @Lior PyMatching isn't my decoder and it is an MWPM decoder. If you actually plot out sampled logical error rate vs distance you find that even distance codes don't really behave that differently compared to odd distance codes. Honestly don't have a great reason why. Maybe something to do with how real world errors are about confusing the decoder rather than making min weight undetectable paths, and also to do with how weights and correlations play out. $\endgroup$ Feb 9 at 9:04
  • $\begingroup$ sorry, I'll be more precise - your decoder estimates the logical state directly (not entirely sure how) and a "standard" MWPM decoder estimates the Pauli frame and then uses it to estimate the logical state. You mean that even distane d codes sit between the d-1 and d+1 in terms of performance and are not the same as the d-1 ones? That shows that all the textbook explanations are inaccurate at best... $\endgroup$
    – Lior
    Feb 9 at 9:22
  • $\begingroup$ @Lior PyMatching isn't my decoder. And it doesn't estimate the logical state directly it is computing the frame of the observable; the do-you-flip-the-measurement bit. For even code distances at the very least you can use random guessing to break ties, so that distance 2d fails half as often as distance 2d-1. $\endgroup$ Feb 9 at 10:17

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.