the Question

Is there a standard way to use deterministic errors (so, for instance, X_ERROR(1)) in Stim with PyMatching? Currently, sometimes if I use X_ERROR(1) in my circuit, my pymatching decoder fails with ValueError: maximum absolute edge weight of 16777215 exceeded.

I apologize if there is an obvious solution in the docs. I wasn't able to find one.

I think this failure makes sense because...

So using X_ERROR(1) sets 𝑝 = 1.

Reading what Craig explains here, "Ultimately the ... error probability 𝑝 becomes a weight 𝑀=lg(𝑝/(1βˆ’π‘))", it makes sense X_ERROR(1) would cause problems given that lg(1/(1-1)) is a weird divide-by-zero edge case*.

And it looks like this is what is happening because, indeed, my matching graphs end up with an edge of weight: -inf. Example: [(0, None, {'fault_ids': set(), 'weight': -inf, 'error_probability': 1.0})] error.

And I think this is why I get the ValueError: maximum absolute edge weight of 16777215 exceeded

(In fact, I'm now confused why there are some circuits I can write with X_ERROR(1) that don't fail in pymatching.)

*Technically, in that post, he's talking about how pymatching combines edges. I'm making the assumption that even a single edge probability will be converted into weight: 𝑀=lg(𝑝/(1βˆ’π‘))

Hack-arounds ...

  • Running X_ERROR(0.99) does stop the error message but it makes doing fault enumeration a little weirder so I was hoping there would be another solution I just wasn't aware of.

  • I can't use a normal X gate because I'm using DETECTORs (per documentation DETECTORs will treat X differently from X_ERROR(1))

A minimum failing example:

###### imports 
import stim 
import pymatching 
import numpy as np

###### Boilerplate decompose, run, and decode circuit function 
def run_decode(circuit, num_shots):
    model = circuit.detector_error_model(decompose_errors=True)
    matching = pymatching.Matching.from_detector_error_model(model)
    sampler = circuit.compile_detector_sampler()
    syndrome, actual_observables = sampler.sample(
        shots=num_shots, separate_observables=True)
    predicted_observables = matching.decode_batch(syndrome)
    error_rate = np.sum(np.any(predicted_observables !=
                        actual_observables, axis=1))/num_shots

    return error_rate

circ = stim.Circuit("""R 0
X 0
X_ERROR(1) 0
M 0 
DETECTOR rec[-1]""")

run_decode(circ, 10_000)

The edges of the matching graph here look like: [(0, None, {'fault_ids': set(), 'weight': -inf, 'error_probability': 1.0})] and the code fails with: ValueError: maximum absolute edge weight of 16777215 exceeded.

Please let me know if you need anymore information. I'll be happy to respond.

1 Answer 1


If you're trying to enumerate how errors are corrected, you shouldn't be telling pymatching which errors you are inserting. It will just end up correcting them perfectly (once this probability 1 crashing bug is fixed), because you've told it exactly which errors have happened by giving it a model that contains exactly those errors with probability 1.

What you should do is make one version of the circuit that has a normal noise model. Derive the detector error model given to pymatching from that variant of the circuit. Then have a second variant of the circuit with only your forced errors. Use that to generate the detection event samples given to pymatching.

  • $\begingroup$ Okay, that makes a lot of sense. Thank you! $\endgroup$
    – bumble13
    Commented May 12, 2023 at 19:53

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.