# how to simulate toric and surface codes with stim + PyMatching

According to PyMatching's github page the package can be decode toric and surface codes. Stim's example uses stim + PyMatching combination to get logical error rate vs physical error rate curves for the repetition code. An encoding circuit is needed for this and it looks like stim has one built in for the repetition code. Is there an equivalent circuit for toric and surface codes somewhere already? It would be nice to generate similar curves for these codes and compare to published results.

An encoding circuit is needed [...] for toric and surface codes

The notebook you linked does a surface code experiment at the end. It uses Stim's built-in surface code circuit generation (stim.Circuit.generated). Running:

import stim
circuit = stim.Circuit.generated(
"surface_code:rotated_memory_z",
distance=3,
rounds=10**5,
after_clifford_depolarization=0.001)
print(circuit)


Prints a surface code circuit:

QUBIT_COORDS(1, 1) 1
QUBIT_COORDS(2, 0) 2
QUBIT_COORDS(3, 1) 3
QUBIT_COORDS(5, 1) 5
QUBIT_COORDS(1, 3) 8
QUBIT_COORDS(2, 2) 9
QUBIT_COORDS(3, 3) 10
QUBIT_COORDS(4, 2) 11
QUBIT_COORDS(5, 3) 12
QUBIT_COORDS(6, 2) 13
QUBIT_COORDS(0, 4) 14
QUBIT_COORDS(1, 5) 15
QUBIT_COORDS(2, 4) 16
QUBIT_COORDS(3, 5) 17
QUBIT_COORDS(4, 4) 18
QUBIT_COORDS(5, 5) 19
QUBIT_COORDS(4, 6) 25
R 1 3 5 8 10 12 15 17 19 2 9 11 13 14 16 18 25
TICK
H 2 11 16 25
DEPOLARIZE1(0.001) 2 11 16 25
TICK
CX 2 3 16 17 11 12 15 14 10 9 19 18
DEPOLARIZE2(0.001) 2 3 16 17 11 12 15 14 10 9 19 18
TICK
CX 2 1 16 15 11 10 8 14 3 9 12 18
DEPOLARIZE2(0.001) 2 1 16 15 11 10 8 14 3 9 12 18
TICK
CX 16 10 11 5 25 19 8 9 17 18 12 13
DEPOLARIZE2(0.001) 16 10 11 5 25 19 8 9 17 18 12 13
TICK
CX 16 8 11 3 25 17 1 9 10 18 5 13
DEPOLARIZE2(0.001) 16 8 11 3 25 17 1 9 10 18 5 13
TICK
H 2 11 16 25
DEPOLARIZE1(0.001) 2 11 16 25
TICK
MR 2 9 11 13 14 16 18 25
DETECTOR(0, 4, 0) rec[-4]
DETECTOR(2, 2, 0) rec[-7]
DETECTOR(4, 4, 0) rec[-2]
DETECTOR(6, 2, 0) rec[-5]
REPEAT 99999 {
TICK
H 2 11 16 25
DEPOLARIZE1(0.001) 2 11 16 25
TICK
CX 2 3 16 17 11 12 15 14 10 9 19 18
DEPOLARIZE2(0.001) 2 3 16 17 11 12 15 14 10 9 19 18
TICK
CX 2 1 16 15 11 10 8 14 3 9 12 18
DEPOLARIZE2(0.001) 2 1 16 15 11 10 8 14 3 9 12 18
TICK
CX 16 10 11 5 25 19 8 9 17 18 12 13
DEPOLARIZE2(0.001) 16 10 11 5 25 19 8 9 17 18 12 13
TICK
CX 16 8 11 3 25 17 1 9 10 18 5 13
DEPOLARIZE2(0.001) 16 8 11 3 25 17 1 9 10 18 5 13
TICK
H 2 11 16 25
DEPOLARIZE1(0.001) 2 11 16 25
TICK
MR 2 9 11 13 14 16 18 25
SHIFT_COORDS(0, 0, 1)
DETECTOR(2, 0, 0) rec[-8] rec[-16]
DETECTOR(2, 2, 0) rec[-7] rec[-15]
DETECTOR(4, 2, 0) rec[-6] rec[-14]
DETECTOR(6, 2, 0) rec[-5] rec[-13]
DETECTOR(0, 4, 0) rec[-4] rec[-12]
DETECTOR(2, 4, 0) rec[-3] rec[-11]
DETECTOR(4, 4, 0) rec[-2] rec[-10]
DETECTOR(4, 6, 0) rec[-1] rec[-9]
}
M 1 3 5 8 10 12 15 17 19
DETECTOR(0, 4, 1) rec[-3] rec[-6] rec[-13]
DETECTOR(2, 2, 1) rec[-5] rec[-6] rec[-8] rec[-9] rec[-16]
DETECTOR(4, 4, 1) rec[-1] rec[-2] rec[-4] rec[-5] rec[-11]
DETECTOR(6, 2, 1) rec[-4] rec[-7] rec[-14]
OBSERVABLE_INCLUDE(0) rec[-7] rec[-8] rec[-9]


You should be able to decode errors in this circuit in the same way that it's done with the rep code in the notebook.

Note that the circuit generation is not intended to be flexible enough to do anything and everything someone might want. People want too many different things. It's really just for getting started. If you want something customized, you have to take the leap and write your own.

• I had a feeling it was defined somewhere but I couldn't find the documentation. I'll take the leap in time; for now I still need the training wheels (working examples) Commented Oct 16, 2021 at 22:07