The circuit which measures a Z-type stabilisers in the surface code is:

enter image description here

whereas for X-type stabilisers it's:

enter image description here

Both types of stabilisers are measured in a memory experiment in the inbuilt surface code circuits of Stim, which I am using by following the linux command line instructions for Sinter. Even though both types of stabilisers are measured for each memory experiment, the two extra hadamards for X-type stabiliser measurements (which detect Z errors) means they have higher depth. This causes a higher logical error rate in a memory experiment for memory X (preserving $|+\rangle_L$ which is more affected by $Z$ errors) than for memory Z (preserving $|0\rangle_L$ which is more affected by $X$ errors). That is ${p_L}_X > {p_L}_Z$.

The circuits I am using are stim's inbuilt surface code circuits. These measure both types of stabilisers for both types of memory experiment. See a distance 2, unrotated surface code with 1 round of stabiliser measurements below as an example (though for my simulations I am doing odd distances and $d$ rounds of stabiliser measurements).

Memory Z prepares the data qubits in $|0\rangle ^{\otimes n}$ and measures them in the Z basis at the end (preserving $|0\rangle_L$):

enter image description here

Whereas Memory X prepares the data qubits in $|+\rangle ^{\otimes n}$ and measures them in the X basis at the end (preserving $|+\rangle_L$):

enter image description here

Note that these diagrams are without noise but for my simulations I am using a circuit noise model (setting all of Stim's inbuilt errors to $p$).

When making threshold curves for the rotated surface code using Stim's inbuilt circuits I see, as expected, that ${p_L}_X > {p_L}_Z$. For example for distance 7 and 9 below ${p_L}_X > {p_L}_Z$ for each distance: enter image description here

On the other hand for the unrotated surface code I am seeing the opposite. Instead of ${p_L}_X > {p_L}_Z$ I am seeing ${p_L}_X < {p_L}_Z$ I have triple checked that I am running and plotting the correct memory experiment type and can not figure out what is causing it. I have simulated every odd distance up to 15 and keep seeing ${p_L}_X < {p_L}_Z$, as per the plots below:

enter image description here

enter image description here

I am running the memory experiments from a linux command line following the instructions for Sinter here which are:

mkdir -p circuits
python -c "

import stim

for p in [0.001, 0.005, 0.01]:
    for d in [3, 5]:
        with open(f'circuits/d={d},p={p},b=X,type=rotated_surface_memory.stim', 'w') as f:
            c = stim.Circuit.generated(
            print(c, file=f)
sinter collect \
    --processes 4 \
    --circuits circuits/*.stim \
    --metadata_func "sinter.comma_separated_key_values(path)" \
    --decoders pymatching \
    --max_shots 1_000_000 \
    --max_errors 1000 \
    --save_resume_filepath stats.csv
sinter plot \
    --in stats.csv \
    --group_func "'Rotated Surface Code d=' + str(metadata['d'])" \
    --x_func "metadata['p']" \
    --fig_size 1024 1024 \
    --xaxis "[log]Physical Error Rate" \
    --out surface_code_figure.png \

1 Answer 1


I don't know what's causing that inversion but...

The two extra hadamards for X-type stabilisers mean a higher depth circuit with more chance for an error, causing a higher logical error rate in a memory experiment for memory X

This is a very concerning sentence! It sounds like you're making a major error in your circuit. In order to protect unknown or entangled logical states, the memory circuit must be independent of the value of the logical qubit. Otherwise you haven't shown your memory circuit can preserve unknown states or entangled logical states. The only circuit detail that should differ, when changing the basis, is the initialization of the logical state at the very beginning and the measurement of the logical state at the very end. The bulk should be literally gate-for-gate detector-for-detector identical, for all logical bases. So the circuit depth should be identical for both memory experiment bases.

Don't skip the X stabilizer measurements, even when performing a Z basis experiment. The X stabilizer measurements introduce noise, and spread the noise around, in ways that relevantly affect the overall logical error rate. To omit them is tantamount to p-hacking. Even if they "don't matter" for the state you happened to test.

If you actually aren't skipping the X stabilizer measurements, then my best guess for what's happening in your circuit is that there are hook errors creating the asymmetry. If you are measuring the X stabilizers in one step and Z stabilizers in another, and not doing a lot of rounds, the issue could be whether the step next to a time boundary is in the same basis or not. Look for anything in the circuit that would be different under exchange of X/Z and reflection around the appropriate diagonal line of symmetry. It's hard to say more without the actual circuits.

  • $\begingroup$ Hi Craig, thanks for your answer - I am using Stim's inbuilt surface code circuits so both types of stabilisers are being measured. I have updated my question to clarify this $\endgroup$
    – drumadoir
    Jun 8, 2023 at 2:21

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.