# Simulating stabilizer groups

Can any existing software be used (either directly or with a bit of persuading) to work with general stabilizer groups? From what I can see, tableau-based options like Stim and Qiskit can be used to work with stabilizer groups over $$n$$ qubits with minimal generating sets of size $$n$$ (i.e. stabilizer states), but not with stabilizer groups of the form $$S = \langle s_1, \ldots, s_m \rangle$$, where $$m < n$$. Is this right? Are there other packages out there?

EDIT: As an example, the kind of things I want to be able to do are:

• Initialise a stabilizer group, by specifying generators and number of qubits they operate on.
• Ask whether a Pauli $$p$$ is a member of a stabilizer group.
• Determine the effect on the group of measuring a Pauli $$p$$.
• Determine the effect on the group of conjugating by a Clifford $$c$$.

What I've tried: with Stim, I can initialise a TableauSimulator and perform Pauli measurements and Clifford conjugations, but if I try and think of this tableau as a stabilizer group on $$n$$ qubits, it always assumes the group is initially generated by $$Z_1, \ldots, Z_n$$. e.g. If I do the following:

# Initialise a tableau on n=2 qubits, and measure X_1
tableau = TableauSimulator()
tableau.measure_observable(PauliString("XI"))


I'd like to get a group generated by just $$\pm X_1$$. But instead I get a group generated by $$\pm X_1$$ and $$Z_2$$, as shown by:

print(tableau.canonical_stabilizers())
# Output:
[stim.PauliString("-X_"), stim.PauliString("+_Z")]


With Qiskit, I'm not even sure where to start!

• they both work with $k<n$...(side note : using $m$ for the number of stabilizer generators is more standard; $k$ is normally used for the dimension of the code space = number of logicals $m+k=n$) Commented Apr 4, 2023 at 16:49
• Fair comment about $m$! I'll edit my question. As for those packages working with $m < n$, can you give an example? Actually, maybe I should be the one giving an example of the kind of code I want to be able to write - I'll add this to my question too. Commented Apr 5, 2023 at 8:45
• I asked a few similar questions here in the past. This might be a good example to start with : quantumcomputing.stackexchange.com/questions/27396/… Commented Apr 5, 2023 at 15:52

Stim doesn't have native functionality for tracking partial knowledge of the state.

Stim does have generic tools for working with stabilizers, that you could use to make it easier to build this functionality for yourself. You could use stim.PauliString to help implement the logic you want. It can handle the brunt of things like propagating through gates (via stim.PauliString.after) and switching which generators you are using (via stim.PauliString *= stim.PauliString), but you'd have to implement the restricted Gaussian elimination logic of a measurement-with-partial-knowledge for yourself.

Another trick you might consider is to use entanglement with ancilla qubits to represent "don't know". For example, if you have a 3 qubit system to analyze, you would create a system of 6 qubits made up of three Bell pairs. Three of the qubits are the ones you care about, and three are just ancilla qubits they will be entangled with when you don't know them. If you then measure XXX and IZZ, you will find that e.g. the expectation of IYY is still 0 (instead of the +1 or -1 it would necessarily be for a straight 3 qubit system).

• Ahhh this is an interesting suggestion, thanks - so basically use process-state duality to make sure I'm always working with a stabilizer state, which Stim is much happier with? I'll try this out and see how convenient it is. Commented Apr 6, 2023 at 12:42

PyClifford

is a python based clifford circuit simulation package which not only offers the fast simulation but also supports analytical level manipulation of pauli operators and stabilizer states. And we are working on quantum circuit (strong/weak) simulations that include a few T-gates.

esabo/CodingTheory

The goal of this package is to develop a classical and quantum error-correcting codes package in as much native Julia as possible.

QuaEC

QuaEC is a library for working with quantum error correction and fault-tolerance. In particular, QuaEC provides support for maniuplating Pauli and Clifford operators, as well as binary symplectic representations of each.

QuaEC is a very old library. I tried to install it on Python 3.11 and it failed. You might get it to install on older versions. Anaconda is your friend here, for dealing with older versions of Python.

• Thanks for the suggestion! I've had a look through the docs - can this package do the sorts of operations I've described in an edit to my original question? It doesn't seem clear to me that it can. Commented Apr 5, 2023 at 9:15
• @Yossarian I have added two more options. QuaEC seems like what you want. Good luck installing it. The other two options are more limited for your purposes. Commented Apr 5, 2023 at 16:49

The QuantumClifford.jl has pretty great support for mixed stabilizer states and a lot of the algebra related to them (various decompositions, canonicalizations, entropy calculations, partial traces). And the library is similarly optimized to stim, so you are not losing any performance.

Any stabilizer tableau for which the rows ($$m$$) are fewer than the columns ($$n$$) corresponds to mixed stabilizer state. For convenience of modeling one usually tracks the $$m$$ stabilizer operators, the $$m$$ destabilizer operators, and the $$2\times(n-m)$$ "logical operators" (they are called logical because they have a special meaning when we work with ECC).

The MixedDestabilizer datastructure provides that functionality:

julia> using QuantumClifford

julia> ψ = MixedDestabilizer(ghz(3)) # make a 3-qubit pure ghz state
Destab       ⟵ this is the destabilizer part of the tableau
+ Z__
+ _X_
+ __X
Stab━
+ XXX        ⟵ this is the stabilizer part of the tableau
+ ZZ_
+ Z_Z

julia> traceout!(ψ, 3) # partial trace the 3rd qubit, leading to impure state
Destab
+ _X_
𝒳ₗ━━━
+ __X
+ Z__
Stab━
+ ZZ_         ⟵ only one row left in the stabilizer tableau
𝒵ₗ━━━
+ Z_Z         ⟵ the rows that are not part of the stab tableau anymore
+ XXX

julia> apply!(ψ, sMZ(3)) # make a projective measurement trying to recover a purer state
𝒟ℯ𝓈𝓉𝒶𝒷
+ _X_
+ __X
𝒳ₗ━━━
+ Z__
𝒮𝓉𝒶𝒷━
+ ZZ_
- __Z
𝒵ₗ━━━
+ XX_


More circuit-oriented notation is available too (with typical gate and measurement notation), but I wanted to showcase the lower-level algebraic capabilities.

Moreover, besides Monte Carlo simulations over noisy circuits the library also provides symbolic perturbative expansions over them, so you can use it to deduce symbolic expressions for various fidelities and code performance figures of merit.

Lastly, the library provides for simulating non-stabilizer mixtures of stabilizer states and general Pauli channels (e.g. T gates). Of course, these simulations are less efficient than pure and mixed stabilizer states, but they are still highly optimized (and faster than state vector simulators as long as the number of non-Clifford gates is small). This is provided by the StabMixture type.