0
$\begingroup$

I'm experimenting with some small quantum error correcting codes (QECC). For example $[[5,1,3]]$, $[[8,3,3]]$ or toric codes $[[2d^2,2,d]]$ ($d=2,3,\cdots$). The last one being defined by redundant stabilizers. What packages can take in a set of $m'$ stabilizers and produce the tableau? ($m'$ could be larger than $m=n-k$ in case stabilizers are not independent).

$\endgroup$
2
$\begingroup$

You can use stim for this, although you do have to write the stabilizer projection procedure for yourself.

Write some methods to project a system into the +1 eigenstate of several stabilizers:

from typing import List

import stim

def find_compatible_tableau(stabilizers: List[stim.PauliString]) -> stim.Tableau:
    num_qubits = max(len(e) for e in stabilizers)
    sim = stim.TableauSimulator()
    # Start the target qubits in a state that overlaps all stabilizers.
    for q in range(num_qubits):
        sim.h(q)
        sim.cnot(q, q + num_qubits + 1)
    # Project into each stabilizer's +1 eigenbasis.
    for s in stabilizers:
        project_stabilizer(sim, s, ancilla=num_qubits)
    # Discard ancillary qubits.
    sim.set_num_qubits(num_qubits)

    # Simulator happens to track the inverse tableau.
    # Invert it to get the normal one.
    return sim.current_inverse_tableau()**-1


def project_stabilizer(sim: stim.TableauSimulator, stabilizer: stim.PauliString, ancilla: int):
    assert ancilla >= len(stabilizer)
    sim.reset(ancilla)
    sim.h(ancilla)
    for q, p in enumerate(stabilizer):
        if p == 1:
            sim.cnot(ancilla, q)
        elif p == 2:
            sim.cy(ancilla, q)
        elif p == 3:
            sim.cz(ancilla, q)
    if stabilizer.sign == -1:
        sim.z(ancilla)
    sim.h(ancilla)
    returned_true, kickback = sim.measure_kickback(ancilla)
    if returned_true:
        if kickback is None:
            raise ValueError("Contradictory stabilizers.")
        sim.do(kickback)

Use it on your problem:

solved_tableau = find_compatible_tableau(stabilizers=[
    stim.PauliString("+ZZ_"),
    stim.PauliString("+_ZZ"),
    stim.PauliString("-XXX"),
])

print(repr(solved_tableau))

And voilà:

stim.Tableau.from_conjugated_generators(
    xs=[
        stim.PauliString("-X__"),
        stim.PauliString("+_X_"),
        stim.PauliString("+__Z"),
    ],
    zs=[
        stim.PauliString("+Z_Z"),
        stim.PauliString("+_ZZ"),
        stim.PauliString("-XXX"),
    ],
)

The stabilizers are a bit re-arranged, but the table is consistent with the ones that were asked for.

$\endgroup$
2
  • $\begingroup$ I think this converts the original stabilizers to a standard form first. This doesn't change the codespace, but the tableaux now corresponds to the new stabilizers; so the rows correspond to the new stabilizers/destabilizers. Is there a way to map that to the original generators? (PS. can stim be installed under windows without visual c? I can live with slower speed for now) $\endgroup$
    – unknown
    Jul 1 at 18:10
  • $\begingroup$ @unknown Normally you would install stim via python's pip install stim. If that doesn't work please open an issue on stim's github repository. Having the stabilizers match exactly is tricky because when you measure in a stabilizer simulator, there are many satisfactory output states and you don't have a way of saying which one you want. $\endgroup$ Jul 1 at 20:24

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.