# How to calculate destabilizer group of toric and other codes

Some papers use the "destabilizer group" for more efficient simulations; see for example (page 3):

https://www.scottaaronson.com/showcase2/report/ted-yoder.pdf

"In addition to stabilizers, we also make use of destabilizers, introduced by Aaronson and Gottesman [10]. While the stabilizer generators can be thought of as virtual Z operators, the destabilizers can be thought of as their conjugate, virtual X operators."

Given the stabilizers $$S_i$$ of an $$[n,k,d]$$ code I know of algorithms to put them in standard form and calculate the encoded $$\bar X$$'s and $$\bar Z$$'s (also in standard forms). This gives me $$m+k+k$$ operators. The destabilizers are an additional $$m$$ operators on top of these; how are these calculated? Are there standard forms possibly related to the other generators'? Also, the $$[2d^2,2,d]$$ toric code is usually described with $$2d^2$$ stabilizers (2 of them redundant); how is the redundancy handled?

stim.Tableau.from_stabilizers (source code) computes the destabilizers for a set of stabilizers.

from typing import List
import stim

def get_destabilizers(
stabilizer_generators: List[stim.PauliString],
) -> List[stim.PauliString]:
t = stim.Tableau.from_stabilizers(stabilizer_generators)
return [t.x_output(k) for k in range(len(t))]

perfect_code = [
stim.PauliString('_XZZX'),
stim.PauliString('X_XZZ'),
stim.PauliString('ZX_XZ'),
stim.PauliString('ZZX_X'),
stim.PauliString('ZZZZZ'),
]
destabilizers = get_destabilizers(perfect_code)
for s, d in zip(perfect_code, destabilizers):
print(s, d)

+_XZZX +_Z_Z_
+X_XZZ +Z____
+ZX_XZ +___Z_
+ZZX_X +_Z_ZZ
+ZZZZZ +_ZXZ_


At a high level, the approach Stim takes is to build a circuit $$C$$ that iteratively turns the k'th stabilizer $$S_k$$ into the single-qubit term $$Z_k$$. It does that by using single qubit gates to turn a non-identity term of the stabilizer into a $$Z$$ term, and then two qubit gates to reduce the stabilizer to that single term (while not disturbing the already reduced stabilizers). When all terms are of the form $$Z_k$$, a valid destabilizer for $$Z_k$$ is $$X_k$$. Because the circuit was constructed such that $$C^\dagger \cdot Z_k \cdot C = S_k$$ and unitaries preserve commutation and anti-commutation, you get the destabilizer $$D_k$$ for $$S_k$$ by computing $$D_k = C^\dagger \cdot X_k \cdot C$$.

This is essentially just Gaussian elimination, by the way. To decompose a matrix into simple instructions, apply row operations turning it into the identity operation. Running the row operations in reverse applies the matrix, giving you your simple instructions. This then enables you to quickly do things that might have been hard otherwise, like applying the inverse of the matrix. The same trick is being used above, just on a list of stabilizers (a Tableau) instead of on a list of vectors (a matrix).

In the context of a simulation, you almost certainly want to maintain knowledge of the destabilizers as you apply operations instead of computing then anew from the stabilizers at each step. Note that the destabilizers are not unique. if $$D_k$$ is a destabilizer and $$S_j$$ is one of the stabilizers, then replacing $$D_k$$ by $$D_k^\prime = i D_k S_j$$ will work just fine. Flipping the sign of $$D_k$$ also doesn't matter.

• Thanks for the response. I asked this back in 2020 and have since found ways to calculate them. For the toric codes in particular I was hoping to find a "natural" or "geometric" way to describe them in relation to the stabilizers. The stabilizers for example can be defined as the product of edges coincident on a vertix...I never found such a description for the destabilizers and I'm still interested in that if you happen to know. Aug 12, 2023 at 17:56
• @unknown The toric code as normally specified has a redundant X stabilizer because the product of all X stabilizers is +1 (same for Z stabilizers). To find destabilizers you need to remove this redundant X stabilizer (by removing any X stabilizer); otherwise it's impossible because all errors flip an even number of stabilizers so you can never isolate one stabilizer. Removing the stabilizer creates a hole, and the destabilizer of an X stabilizer is a chain of Z errors travelling from the X stabilizer to this hole. Aug 12, 2023 at 21:11
• I checked that these chains have the right commutation relations with the stabilizer. However it doesn't look like they commute with the logicals which is another constraint on the destabilizers. Did you happen to check their commutation with the logicals? Aug 14, 2023 at 17:31
• @unknown take the path that doesn't cross your logicals in the other basis, by travelling in the opposite direction around the donut as needed. Aug 15, 2023 at 0:02
• This ended up being a little trickier than I thought; but in the end there are enough degrees of freedom to move things around so the x and z destabilizers commute with each other and the with logicals. Thanks for your suggestions. Aug 19, 2023 at 2:46

We start with the tableau for a state whose destabilisers and stabiliser we know, for instance $$|0\rangle$$. It’s tableau is the identity matrix because the stabilisers are $$Z_1, Z_2, \dots Z_n$$. We want the corresponding destabilisers to have the property that the commute with each other and all the stabilisers except the one that is in the same position. Based on this we see that the destabilisers must be $$X_1, X_2\dots X_n$$.

From here on, the paper specifies how we need to modify the tableau (so in particular the destabilisers) as we apply the various gates.