Performing a generic single-qubit Pauli error channel in stim

I have a Pauli channel with disjoint probabilities $$P_I$$, $$P_X$$, $$P_Y$$, $$P_Z$$ (meaning $$P_I + P_X + P_Y + P_Z = 1$$) corresponding to Pauli errors I, X, Y, Z. Is there some way apply this Pauli channel in Stim?

• Note: this is a question I received by email. I put the answer here for posterity. May 11, 2021 at 0:42

Update: Since v1.4, stim supports custom pauli channels PAULI_CHANNEL_1(px, py, pz) and PAULI_CHANNEL_2(pix, piy, ..., pzz).

Before v1.4

If $$P_x = P_y = P_z$$ then DEPOLARIZE1 is what you need. If $$P_y = P_z = 0$$ then X_ERROR is what you need (ditto Y_ERROR, Z_ERROR). Otherwise you can use CORRELATED_ERROR and ELSE_CORRELATED_ERROR.

For example, suppose $$P_x = 0.1$$, $$P_y = 0.2$$, $$P_z = 0.3$$ and your target is qubit $$5$$. You can do this:

CORRELATED_ERROR(0.1) X5
ELSE_CORRELATED_ERROR(0.22222222222) Y5  # note: P(Y|not X) = 20%/(100% - 10%)
ELSE_CORRELATED_ERROR(0.42857142857) Z5  # note: P(Z|not X and not Y) = 30%/(100% - 10% - 20%)


The else-case probabilities are conditioned on the earlier cases not happening, which is why they are larger than the original probabilities.

Here's the general case, implemented as python code:

def append_generic_single_qubit_error_channel_to_circuit(
circuit: stim.Circuit,
target: int,
px: float,
py: float,
pz: float):
"""
Args:
circuit: The circuit to append the error channel to.
target: The qubit to hit with the error channel.
px: The disjoint probability of an X error.
py: The disjoint probability of a Y error.
pz: The disjoint probability of a Z error.

Requires:
0 <= px <= 1
0 <= py <= 1
0 <= pz <= 1
px+py+pz <= 1
"""
circuit.append_operation("CORRELATED_ERROR", [stim.target_x(target)], px)
circuit.append_operation("ELSE_CORRELATED_ERROR", [stim.target_y(target)], py / (1 - px))
circuit.append_operation("ELSE_CORRELATED_ERROR", [stim.target_z(target)], pz / (1 - px - py))


Note that it agrees with the example case:

import stim
c = stim.Circuit()
append_generic_single_qubit_error_channel_to_circuit(
circuit=c, target=5, px=0.1, py=0.2, pz=0.3)
print(c)

E(0.1) X5
ELSE_CORRELATED_ERROR(0.222222) Y5
ELSE_CORRELATED_ERROR(0.428571) Z5


(E is an abbreviation for CORRELATED_ERROR)