1
$\begingroup$

I'm getting started with STIM but I'm struggling with the interpretation of detectors. For example take the following circuit enter image description here

The "getting started" jupyter notebook says

A slightly subtle point about detectors is that they only assert that the parity of the measurements is always the same under noiseless execution. A detector doesn't say whether the parity should be even or should be odd, only that it should always be the same.

My questions are:

  1. The same as what? For example in the circuit above the parity will be odd, but there's no earlier detection event to compare against
  2. Why does the annotation above the DETECTOR say rec[0]*rec[1] instead of rec[0]+rec[1]?

Thanks

Update:

I've tried to infer the rules for how it determines which parity is "correct". I thought it might be majority vote, or the first result in a run of shots samples, or even the first ever result in a circuit, but all of these are ruled out by this output:

In [288]: stim.Circuit("""
     ...:     H 0
     ...:     CX 0 1
     ...:     X_ERROR(0.5) 0
     ...:     M 0 1
     ...:     DETECTOR rec[-1] rec[-2]
     ...: """).compile_detector_sampler().sample(shots=2)
Out[288]: 
array([[ True],
       [False]])

In [289]: stim.Circuit("""
     ...:     H 0
     ...:     CX 0 1
     ...:     X_ERROR(0.5) 0
     ...:     M 0 1
     ...:     DETECTOR rec[-1] rec[-2]
     ...: """).compile_detector_sampler().sample(shots=2)
Out[289]: 
array([[False],
       [ True]])
```
$\endgroup$

2 Answers 2

1
$\begingroup$

I believe stim could figure out on its own at compilation whether a detector's parity should be even, odd or non-deterministic, without needing any further information.

By backpropagating the observables being tracked by the detector through the (Clifford) circuit, you can predict detector outcomes in the absence of errors thanks to stabilizer formalism.

In your example (without the $X$ error), the two observables are $Z_0$ and $Z_1$, which backpropagates to $X_0$ and $X_0Z_1$. These two Pauli operators commutes together so the measurement outcomes are not fully random but correlated, their product is $Z_1$ which commutes with the stabilizers of the initial state $|00\rangle$ (aka $Z_0,Z_1$), so the detector outcome is deterministic. Since the product is $+Z_1$, the detector parity should be even (i.e. the product should be 1).

If you add an $X$ gate at the beginning on $q_1$, $Z_1$ will backpropagate to $-X_0Z_1$, so the product becomes $-Z_1$ differing in signs from the initial stabilizer $Z_1$. The detector parity is now deterministic and odd (i.e. the product should be -1).

If instead you consider the $X$ error always happen, the product becomes $X_0Z_1\cdot -X_0$ which is still $-Z_1$, The detector parity is still deterministic and odd (i.e. the product should be -1).

If instead you start with $|01\rangle$, the negative sign no longer appear in the product $X_0Z_1\cdot X_0$ but is present in the new initial stabilizer $-Z_1$ (replacing the old $Z_1$). The difference of signs is still there, so the detector parity is still deterministic and odd (i.e. the product should be -1).

If you start with $|0+\rangle$, the initial stabilizer are $Z_0, X_1$. The detector product anticommutes with $X_1$, so the detector outcome is non-deterministic:

import stim

c = stim.Circuit("""
RX 1
H 0
CX 0 1
X_ERROR(0.0) 0
M 0 1
DETECTOR rec[-1] rec[-2]
""")

print(c.detector_error_model())

This code fails as expected because the detector is non-deterministic. stim.Circuit.detector_error_model by default fails on non-deterministic detectors, while c.compile_detector_sampler().sample(shots=2) allows them, but samples 50/50 outcomes for them.

Since the product $X_0Z_1\cdot X_0$ never actually depends on $q_0$, you could start in state $|10\rangle$, $|+0\rangle$ or $|-0\rangle$ while still having a deterministically even detector parity.


In practice, I think stim does not compute whether each deterministic detector should be odd or even but only which ones are deterministic and which ones are not. This means you cannot effectively use stim detectors directly to assert whether two measurements are identical, only to assert that they are deterministic in the absence of errors (there might exist some stim functions to do this, but this is not the purpose of detectors).

It is in the sense that the detector is deterministic that the documentation states it should always be the same.

Compare these 2 circuit samplings:

import stim

stim.Circuit("""
H 0
CX 0 1
X_ERROR(0.0) 0
M 0 1
DETECTOR rec[-1] rec[-2]
""").compile_detector_sampler().sample(shots=200)

and

import stim

stim.Circuit("""
H 0
X 1
CX 0 1
X_ERROR(0.0) 0
M 0 1
DETECTOR rec[-1] rec[-2]
""").compile_detector_sampler().sample(shots=200)

Both always outputs False, despite one having a detector whose parity is even and the other one odd. Since no errors can occur, no detector flips were sampled.

Detectors are primarily used in syndrome extraction for quantum error correction, where you care more about which stabilizer operator was flipped and when than its actual measurement. Stim (and detectors) takes advantage of this to sample more efficiently circuit experiments.

For efficiency, stim never samples the actual errors that occured, but only detector flips. This is possible thanks to the DetectorErrorModel that stim first precomputes before sampling. I recommend reading about it to understand what stim does precisely.

$\endgroup$
2
  • $\begingroup$ > It is in the sense that the detector is deterministic that the documentation states it should always be the same. Thanks. That makes sense. If it is non-deterministic then I guess you get undefined behaviour! $\endgroup$ Commented Oct 30 at 11:57
  • $\begingroup$ In fact, these non-deterministic detectors all behave exactly like fair coin tosses. It is not undefined behaviour, it is working as intended. It is just that physics laws are what they are... $\endgroup$
    – AG47
    Commented Oct 30 at 13:34
1
$\begingroup$

The same as what? For example in the circuit above the parity will be odd, but there's no earlier detection event to compare against

The same each time you run the circuit.

Why does the annotation above the DETECTOR say rec[0]*rec1 instead of rec[0]+rec1?

Multiplying two bits is the same as adding two bits mod 2.

There's a rigorous definition of detectors in Sparse Blossom: correcting a million errors per core second with minimum-weight matching. I've tried to give a pedagogical introduction to detectors in Section 2 of Designing fault-tolerant circuits using detector error models

$\endgroup$
3
  • $\begingroup$ > Multiplying two bits is the same as adding two bits mod 2. Ah, I see. They're thinking of plus ones and minus ones whereas I was thinking of zeros and ones. $\endgroup$ Commented Oct 25 at 13:13
  • $\begingroup$ > The same each time you run the circuit. But if I add a small probability of an X_ERROR just before the measurement and run 10 times (sampler.sample(shots=10)) I find that sometimes the first run produces an error and sometimes it doesn't. How does it decide whether +1 or -1 is the correct parity - it can't be using the first run. $\endgroup$ Commented Oct 25 at 13:14
  • $\begingroup$ I've added an update to the question to make it clearer what the problem is. I needed to post some multiline code, which meant I couldn't just add a comment. Cheers. $\endgroup$ Commented Oct 25 at 13:54

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.