# How to find the $+1$ eigenvectors of the stabilizers for the Shor code

I am currently working through chapter $$3$$ of "Stabilizer Codes and Quantum Error Correction" (Daniel Gottesman's thesis).

I would like to know the general method for finding the $$+1$$ eigenvectors of the stabilizers.

He states that the codewords $$| \overline{0} \rangle, | \overline{1} \rangle$$ are $$+1$$ eigenvectors of the operators that measure the bit/phase flips.

I (think) I understand that these operators are

$$g_{1}= Z_{1}Z_{2}$$

$$g_{2}=Z_{1}Z_{3}$$

$$g_{3}=Z_{4}Z_{5}$$

$$g_{4}=Z_{4}Z_{6}$$

$$g_{5}=Z_{7}Z_{8}$$

$$g_{6}=Z_{7}Z_{9}$$

$$g_{7}=X_{1}X_{2}X_{3}X_{4}X_{5}X_{6}$$

$$g_{8}= X_{1}X_{2}X_{3}X_{7}X_{8}X_{9}$$

These operators are clearly the stabilizer generators for the code.

However, I don't understand how to find the codewords from these stabilizers. How does one find the eigenvalues of these stabilizers without writing out a $$2^{9} \times 2^{9}$$ matrix? And then how do you find the eigenvectors?

I have seen some things about projective measurements, for example the $$\pm 1$$ measurement outcomes for $$g_{1}$$ is $$P_{\pm } = \frac{1}{2} (I \pm Z_{1}Z_{2})$$ but I don't know how to use it in this context? I am assuming that the measurement outcome being $$+1$$ has something to do with the eigenvector, but I don't quite get it.

• The eigenvalues will always be +1 and -1. Your generators are unitary, so their eigenvalues must have modulus 1. They are also Pauli operators hence Hermitian matrices, so their eigenvalues must be real. Excluding $\pm I$ as possible generators, they will have both +1 and -1 as eigenvalues. Both eigenspaces should have the same dimension for some other linear algebra reason, hence +1 and -1 should appear the same number of times in the specter of the generator's matrix.
– AG47
Commented May 23 at 15:03

For CSS stabilizers it's easy. Every X stabilizer will project the computational basis state $$|k\rangle$$ into $$|k\rangle + |k \oplus x\rangle$$ where $$x$$ is the bits flipped by the X gates of the stabilizer. So you just end up with a superposition containing $$|0...0\rangle$$ (chosen to satisfy the Z stabilizers) plus all states you can reach by choosing to apply any subset of the given X generators.

In the more general cases, the fastest method I know for producing the simultaneous +1 eigenstate is to generate a random state vector, multiply it by $$G+I$$ for each generator $$G$$, then normalize it to be a unit vector. This is what stim.Tableau.to_state_vector does.

import stim
t = stim.Tableau.from_stabilizers([
stim.PauliString("Z0*Z1"),  # Indices 0-based instead of 1-based
stim.PauliString("Z0*Z2"),
stim.PauliString("Z3*Z4"),
stim.PauliString("Z3*Z5"),
stim.PauliString("Z6*Z7"),
stim.PauliString("Z6*Z8"),
stim.PauliString("XXXXXX___"),
stim.PauliString("___XXXXXX"),
stim.PauliString("ZZZZZZZZZ"),  # Specify logical qubit also
])

s = t.to_state_vector()
for index, amp in enumerate(s):
if amp:
bits = bin(index)[2:].rjust(len(t), "0")
print(f'{amp}*|{bits}⟩')

# prints:
# (0.5+0j)*|000000000⟩
# (0.5+0j)*|000111111⟩
# (0.5+0j)*|111000111⟩
# (0.5+0j)*|111111000⟩

• Thank you very much for the detailed response. I am a little confuse because by that description, I would expect that the zero codeword would be $\frac{1}{N}(| 000000000 \rangle + |111111000 \rangle + |111000111 \rangle + |000111111 \rangle)$ (where $N$ is the normalising factor. However, from the literature, it appears that the zero codeword is $\frac{1}{N}(|000\rangle + |111\rangle)^{\otimes 3}$ which expands out into $\frac{1}{N}(|000000000\rangle + |000111000\rangle + |111000000\rangle + |111111000\rangle + |000000111\rangle + |000111111\rangle + |111000111\rangle + |111111111\rangle)$ Commented May 24 at 11:53
• (ran out of space) but the zero codeword appearing in the literature seems to contain more states than is possible to reach by applying a subset of the $X$ stabilizers? Commented May 24 at 11:54
• @am567 The discrepancy comes from the fact that logical operators are not defined consistently in the literure. If you go with the definition $Z_L = Z_1 Z_2 Z_3 Z_4 Z_5 Z_6 Z_7 Z_8 Z_9$ (as Craig Gidney did) you get the corresponding version of $|0\rangle_L$. However, if you use $Z_L = X_1 X_2 X_3 X_4 X_5 X_6 X_7 X_8 X_9$ (like here: quantumcomputing.stackexchange.com/questions/16789/…), you get $|0\rangle_L = \frac {1}{N}(|000\rangle + |111\rangle)^{\otimes 3}$. It is really a matter of choice. Commented May 24 at 12:13
• Then do they define different codes? How do you have different codewords defined for the same code? Also, then is it not just the X operators of the stabilizers that define the codewords, but also the X operators of the logical operators? Commented May 24 at 12:17
• @am567 If you change the observable stabilizer from +ZZZZZZZZZ to -ZZZZZZZZZ you will see the other states. If you change it to +-XXXXXXXXX you will see them superposed. Overall I would advise not worrying too much about what the state vector looks like. Basically all quantum error correction is done by working directly with the stabilizers, because state vectors don't highlight the important parts of the problem and are exponentially less efficient as a representation. Commented May 24 at 18:59