In google's repetition code memory experiment, they use the subsampling technique to reduce the experimental burden of acquiring data and enforce the self-consistency in error rates.

When I use stim and pymatching2 to simulate the repetition code, is there a way to emulate the subsampling process efficiently? The problem here is two fold:

  1. Tracking the logical observables of all the sub-code. The way I deal with it is to append all the possible sub-code's logical observables to the stim.Circuit.
  2. Making detector error models for all the sub-code. The dem for the sub-code should be the subsets of all the error items including only the detectors in sub-code. Additionally, the error items across the boundary of the sub-code should be converted to edges connecting a detector to the boundary. I wonder the correctness of this method and how to do it efficiently.

1 Answer 1


It sounds to me like you have the right idea.

The way I would approach this is to edit nothing except the OBSERVABLE_INCLUDE and DETECTOR annotations in the circuit, while leaving all operations exactly the same. Don't mess with the noise model, don't hide measurements, don't lie about what the circuit was doing to make it look like "really truly" a smaller distance rep code circuit, just change the annotations describing the decoding task. This preserves the most information possible about the circuit, while forcing the decoder to subsample. This edit-annotations-approach will also avoid some potential pitfalls, like making an edit that changes how Paulis from spin echo or sweep bits propagate through the circuit, changing the expected signs of measurements, resulting in detection events getting computed wrong from the sampled data.

To actually do the rewrite, I would iterate through the circuit noting QUBIT_COORD data to locate qubits, then for each measurement I'd note whether its target qubit was inside or outside the sample so I could look that information up later from the measurement index. Then, whenever I ran into a DETECTOR, I'd iterate over its record targets and delete any that referred to a measurement outside the subsample, by looking up the is-measurement's-qubit-in-subsample information. Note that it's okay to have empty detectors. For the OBSERVABLE_INCLUDE instruction I'd change the single measurement record target to refer to the most recent measurement that was inside the subsample.

You will need to run this circuit rewriting process once for each subsample region, since you'll get slightly different dems from the slightly different noise across the qubits even for subsamples of the same distance. Assuming you do all offsets of all distances from 3 to 25, that's around 300 times. I think that's a bit expensive but totally reasonable given that you're gong to use each one for a million shots. I expect decoding the shots to take longer than producing the circuit with rewritten annotations. Personally I probably wouldn't even bother making the rewrite code work on loops (often a major speed boost for rewrite code); I'd just start the rewrite method with stim.Circuit.flattened.

Once you have a circuit with rewritten detectors and observables, you can decode it like you would any other circuit. Use stim m2d or stim.Circuit.compile_m2d_converter to convert the measurement data into detection event data and observable flip data. Don't forget to give the sweep data that tells the conversion if the qubits were flipped or not at the start! Use pymatching.Matching.from_stim_circuit to get a pymatching decoder for the rewritten circuit. Then give the detection event data to that decoder and compare its predicted observable flips to the actual observable flips to get a logical error rate.


Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

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