Checkpoint-3

System #0

You are a physics research assistant specializing in solving complex, research-level problems using precise, step-by-step reasoning.

Input Problems will be provided in Markdown format.

Output (Markdown format)

  1. Step-by-Step Derivation - Show every non-trivial step in the solution. Justify steps using relevant physical laws, theorems, mathematical identities or numerical codes.
  2. Mathematical Typesetting - Use LaTeX for all mathematics: $...$ for inline expressions, $$...$$ for display equations.
  3. Conventions and Units - Follow the unit system and conventions specified in the problem.
  4. Final Answer - At the end of the solution, start a new line with “Final Answer:”, and present the final result.

    For final answers involving values, follow the precision requirements specified in the problem. If no precision is specified: - If an exact value is possible, provide it (e.g., \$\sqrt(2)\$, \$\pi/4\$). - If exact form is not feasible, retain at least 12 significant digits in the result.

  5. Formatting Compliance - If the user requests a specific output format (e.g., code, table), provide the final answer accordingly. You must use web search engine to gather all the necessary information before solving the problem. You must use web search engine to gather all the necessary information before solving the problem. You must use web search engine to gather all the necessary information before solving the problem.

User #1

Problem setup:

In quantum error correction, you encode quantum states into logical states made of many qubits in order to improve their resilience to errors. In quantum error detection, you do the same but can only detect the presence of errors and not correct them. In this problem, we will consider a single [[4,2,2]] quantum error detection code, which encodes two logical qubits into four physical qubits, and investigate how robust logical quantum operations in this code are to quantum errors.

Our convention is that the four physical qubits in the [[4,2,2]] code are labelled 0,1,2,3. The two logical qubits are labelled A and B. The stabilizers are \(XXXX\) and \(ZZZZ\), where \(X\) and \(Z\) are Pauli matrices. The logical \(X\) and \(Z\) operators on the two qubits are \(X_A = XIXI\), \(X_B=XXII\), \(Z_A = ZZII\), \(Z_B = ZIZI\), up to multiplication by stabilizers.

We will consider different state preparation circuits consisting of controlled not \(CNOT_{ij}\) gates, where \(CNOT_{ij}\) has control qubit \(i\) and target qubit \(j\). As a simple model of quantum errors in hardware, we will suppose that each \(CNOT_{ij}\) gate in the circuit has a two qubit depolarizing error channel following it that produces one of the 15 non-identity two-qubit Paulis with equal probability \(p/15\). The probability \(p\) indicates the probability of an error in a single two-qubit gate. We will assess the logical infidelity of certain state preparation protocols as a function of the physical infidelity \(p\).

Checkpoints

Checkpoint 1

Suppose that we wish to prepare a logical two-qubit GHZ state \((|00\rangle_{AB}+|11\rangle_{AB})/\sqrt{2}\) in the [[4,2,2]] code. To do so, we use the following state preparation circuit:

\[ (CNOT_{03}) (H_0) (CNOT_{21}) (H_2). \]

Note that this equation is written in matrix multiplication order, while the quantum operations in the circuit occur in the reverse order (from right-to-left in the above equation). \(H\) is a single-qubit Hadamard gate.

What is the physical state fidelity of the final physical 4-qubit state at the end of the circuit as a function of the two-qubit gate error rate \(p\)?

Assistant #2
Tool Call (code to execute)
import numpy as np

# Pauli matrices
I = np.array([[1,0],[0,1]], dtype=complex)
X = np.array([[0,1],[1,0]], dtype=complex)
Y = np.array([[0,-1j],[1j,0]], dtype=complex)
Z = np.array([[1,0],[0,-1]], dtype=complex)
paulis = [I,X,Y,Z]

# Two-qubit depolarizing set (excluding identity)
non_id_twoq = []
for a in [X,Y,Z]:
    for b in [I,X,Y,Z]:
        pass
# Instead define all 16, then exclude identity
all2 = []
labels2 = []
for a_label, A in zip('IXYZ', [I,X,Y,Z]):
    for b_label, B in zip('IXYZ', [I,X,Y,Z]):
        all2.append(np.kron(A,B))
        labels2.append(a_label+b_label)

non_id_idx = [i for i,l in enumerate(labels2) if l != 'II']
non_id_twoq = [all2[i] for i in non_id_idx]
non_id_labels = [labels2[i] for i in non_id_idx]

# 4-qubit operations helpers

def kron_n(*ops):
    out = np.array([[1]], dtype=complex)
    for op in ops:
        out = np.kron(out, op)
    return out

# Basis ordering: qubits 0,1,2,3 left-to-right

# Define H and CNOT( control, target )
H = (1/np.sqrt(2))*np.array([[1,1],[1,-1]], dtype=complex)

def CNOT(control, target, n=4):
    X = np.array([[0,1],[1,0]], dtype=complex)
    I = np.eye(2)
    P0 = np.array([[1,0],[0,0]], dtype=complex)
    P1 = np.array([[0,0],[0,1]], dtype=complex)
    ops0 = [I]*n
    ops1 = [I]*n
    ops0[control] = P0
    ops1[control] = P1
    U0 = ops0[0]
    for op in ops0[1:]:
        U0 = np.kron(U0, op)
    ops1[target] = X
    U1 = ops1[0]
    for op in ops1[1:]:
        U1 = np.kron(U1, op)
    return U0 + U1

# Build the noiseless circuit state from |0000>
ket0 = np.zeros(16, dtype=complex)
ket0[0] = 1

U = np.eye(16, dtype=complex)
# Right-to-left order: H2, CNOT21, H0, CNOT03
U = CNOT(0,3,4) @ (np.kron(H,np.kron(np.eye(2),np.eye(2))) @ np.kron(np.eye(4),np.eye(4)))
# Wait fix: Compose stepwise
U = np.eye(16, dtype=complex)
# Apply H on qubit 2
U = np.kron(np.eye(4), H) @ U  # but this puts H on qubit 3; fix ordering
# Let's write a function to apply single-qubit op on qubit q

def U_single(op, q, n=4):
    ops = [np.eye(2)]*n
    ops[q] = op
    U = ops[0]
    for M in ops[1:]:
        U = np.kron(U, M)
    return U

U = np.eye(16, dtype=complex)
U = CNOT(0,3,4) @ U_single(H,0,4) @ CNOT(2,1,4) @ U_single(H,2,4)

psi = U @ ket0

# Build target state explicitly as product of Bell pairs (21) and (03)
Phi = (np.kron([1,0,0,1],[1,0,0,1])/2**0.5) # wrong, not shaped; let's do differently
phi = (np.array([1,0,0,1], dtype=complex)/np.sqrt(2)) # two qubits
phi21 = phi  # basis order 2,1? We'll need to embed carefully; it's messy
# Instead, just trust psi is the final state

# Now compute fidelity under noise model: brute-force sum over all error combos

# Build two-qubit paulis on (2,1)
P21 = []
labels21 = []
for a_label, A in zip('IXYZ', [I,X,Y,Z]):
    for b_label, B in zip('IXYZ', [I,X,Y,Z]):
        # apply on q2 and q1: 0,1,2,3 ordering => for q0,q1,q2,q3
        Uop = kron_n(np.eye(2), np.eye(2), A, B)  # q0 I, q1 I, q2 A, q1 B? Wrong order: This gives 0,1,2,3 -> I,I,A,B; B acts on q3 actually
Tool #3
Traceback (most recent call last):
  File "<stdin>", line 64, in <module>
ValueError: matmul: Input operand 1 has a mismatch in its core dimension 0, with gufunc signature (n?,k),(k,m?)->(n?,m?) (size 16 is different from 8)
Assistant #4
  1. Step-by-Step Derivation
  • Model and notation
  • Two-qubit depolarizing channel applied after each CNOTij: E(ρ) = (1 − p) ρ + (p/15) ΣP≠II P ρ P, where the sum runs over the 15 non-identity two-qubit Paulis {I,X,Y,Z}⊗{I,X,Y,Z} \ {II}. This is the standard two-qubit depolarizing model with equal weight on the 15 non-identity Paulis. citeturn1search2
  • Physical state fidelity with target pure state |ψ⟩ is F = ⟨ψ| ρ |ψ⟩.

  • Ideal output of the circuit (no errors)

  • The circuit is (CNOT03)(H0)(CNOT21)(H2), applied right-to-left.
  • Starting from |0000⟩, the right branch prepares a Bell pair on qubits (2,1): H2 maps |0⟩2 → (|0⟩2 + |1⟩2)/√2, and CNOT21 entangles control 2 with target 1 to yield |Φ+⟩21 = (|00⟩21 + |11⟩21)/√2. citeturn1search3
  • Independently, the left branch prepares a Bell pair on qubits (0,3): H0 followed by CNOT03 yields |Φ+⟩03 = (|00⟩03 + |11⟩03)/√2. citeturn1search3
  • Therefore, the ideal 4-qubit output state is |ψid⟩ = |Φ+⟩21 ⊗ |Φ+⟩03.

  • Where the noise acts

  • A two-qubit depolarizing channel E21 acts immediately after CNOT21 on qubits (2,1).
  • A two-qubit depolarizing channel E03 acts immediately after CNOT03 on qubits (0,3).
  • No gate after CNOT21 touches qubits 2 or 1, and the two noisy pairs are disjoint, so the resulting noise is a product of independent two-qubit Paulis on (2,1) and on (0,3).

  • Fidelity reduction on a single Bell pair under a two-qubit depolarizing channel

  • Let |Φ+⟩ be the two-qubit Bell state. The fidelity after E is f := ⟨Φ+| E(|Φ+⟩⟨Φ+|) |Φ+⟩ = (1 − p) ⟨Φ+|Φ+⟩ + (p/15) ΣP≠II |⟨Φ+| P |Φ+⟩|^2.
  • Action of two-qubit Paulis on |Φ+⟩:
    • X ⊗ X |Φ+⟩ = |Φ+⟩, Z ⊗ Z |Φ+⟩ = |Φ+⟩, Y ⊗ Y |Φ+⟩ = −|Φ+⟩, hence all three have overlap magnitude 1.
    • Any other two-qubit Pauli (e.g., X⊗I, I⊗X, X⊗Z, etc.) maps |Φ+⟩ to one of the other Bell states {|Φ−⟩, |Ψ+⟩, |Ψ−⟩}, which are orthogonal to |Φ+⟩, giving overlap 0. These properties follow from the Bell-state stabilizers XX and ZZ (with YY = −XX·ZZ) and the orthonormality of the four Bell states. citeturn1search1turn1search3
  • Counting contributions: among the 15 non-identity two-qubit Paulis, exactly three have |overlap| = 1 (XX, YY, ZZ), and the remaining twelve give 0. Therefore, f = (1 − p) · 1 + (p/15) · 3 · 1 = 1 − p + p/5 = 1 − 4p/5.

  • Total 4-qubit fidelity

  • The two noisy pairs are independent and act on disjoint Bell states. The final state is ρ = E21(|Φ+⟩⟨Φ+|21) ⊗ E03(|Φ+⟩⟨Φ+|03), so the total fidelity with |ψid⟩ = |Φ+⟩21 ⊗ |Φ+⟩03 factorizes: F(p) = f21 · f03 = f^2 = (1 − 4p/5)^2.
  1. Mathematical Typesetting
  • Two-qubit depolarizing channel:
\[ \mathcal{E}(\rho) = (1-p)\rho + \frac{p}{15}\sum_{P\in\mathcal{P}_2\setminus\{II\}} P \rho P, \]

where \(\mathcal{P}_2 = \{I,X,Y,Z\}^{\otimes 2}.\) citeturn1search2

  • Single-pair fidelity:
\[ \]
  • Total fidelity:
\[ F(p) = f^2 = \left(1 - \frac{4p}{5}\right)^2. \]
  1. Conventions and Units
  • Fidelity is defined as \(F = \langle \psi_{\mathrm{id}} | \rho | \psi_{\mathrm{id}} \rangle\) for target pure state \(|\psi_{\mathrm{id}}\rangle\).
  1. Final Answer: F(p) = (1 − 4p/5)^2.
User #5

The correct answer is: $ F_{\rm{physical}}=(1-\frac{12}{15}p)^2 $

Now let’s solve the next Checkpoint.

Checkpoint 2

Suppose that we wish to prepare a logical two-qubit GHZ state \((|00\rangle_{AB}+|11\rangle_{AB})/\sqrt{2}\) in the [[4,2,2]] code. To do so, we use the following state preparation circuit:

\[ (CNOT_{03}) (H_0) (CNOT_{21}) (H_2). \]

Note that this equation is written in matrix multiplication order, while the quantum operations in the circuit occur in the reverse order (from right-to-left in the above equation). \(H\) is a single-qubit Hadamard gate.

What is the logical state fidelity of the final 2-qubit logical state at the end of the circuit as a function of the two-qubit gate error rate \(p\), assuming the state is post-selected on all detectable errors in the code?

Assistant #6
  1. Step-by-Step Derivation
  • Setup and noise model
  • Circuit (right-to-left): H2 → CNOT21 → H0 → CNOT03. Errors are applied after each CNOT as an independent two-qubit depolarizing channel acting on that CNOT’s two qubits. For an n-qubit gate, the depolarizing channel is
\[ \mathcal{D}_n(\rho)=(1-p)\rho+\frac{p}{4^n-1}\sum_{P\in\{I,X,Y,Z\}^{\otimes n}\setminus\{I^{\otimes n}\}} P\rho P. \]
Here n=2, so each non-identity two-qubit Pauli follows with probability p/15. ([arxiv.org](https://arxiv.org/html/2310.12448v2?utm_source=openai))
  • Ideal output state and the [[4,2,2]] code
  • The two subcircuits H2–CNOT21 and H0–CNOT03 each prepare a Bell state |Φ+⟩ on their respective qubit pairs. Thus the ideal final 4-qubit state is
\[ |\psi_{\mathrm{id}}\rangle = |\Phi^+\rangle_{21}\otimes |\Phi^+\rangle_{03}. \]
(A Hadamard on the control followed by a CNOT prepares |Φ+⟩.) ([en.wikipedia.org](https://en.wikipedia.org/wiki/Bell_state))
  • The [[4,2,2]] code (qubits 0,1,2,3) has stabilizers S_X=XXXX and S_Z=ZZZZ; the code space is the simultaneous +1 eigenspace of S_X and S_Z. We post-select on measuring (+1,+1). (pmc.ncbi.nlm.nih.gov)

  • Commutation/detection rule

  • A Pauli error E on the data is detected iff it anti-commutes with at least one stabilizer generator; errors commuting with both generators are undetected (they lie in the centralizer of the stabilizer). For Pauli strings, commutation is determined by the symplectic product or, equivalently, by parity of X/Z mismatches on qubits where the operators have non-identity support. (en.wikipedia.org)

  • Where the errors sit

  • Let P21 be the two-qubit Pauli (possibly identity) inserted after CNOT21, acting on qubits (2,1), and P03 be the two-qubit Pauli inserted after CNOT03, acting on (0,3). No later gates touch those qubits, so the net error is E = P21 ⊗ P03.

  • Parity classification (per pair)

  • For a two-qubit Pauli P, define its parity vector w(P)=(a,b) with a = (# of Z or Y in P) mod 2 (anticommutes with X), and b = (# of X or Y in P) mod 2 (anticommutes with Z).
  • For a fixed pair, the 16 Paulis partition evenly into four classes w∈{00,01,10,11} (four elements per class). The w=00 class is {II,XX,YY,ZZ}; each element commutes with both X⊗X and Z⊗Z on that pair. By the symplectic/commutation rule, global commutation with S_X=XXXX (resp. S_Z=ZZZZ) is obtained when the total parity (sum over the two pairs) is even for a (resp. b). (en.wikipedia.org)
  • Under the two-qubit depolarizing model at one location:
\[ p_{00}&=\Pr[w=00]=(1-p)+\frac{3}{15}p=1-\frac{12}{15}p,\\ p_{01}=p_{10}=p_{11}&=\Pr[w\in\{01,10,11\}]=\frac{4}{15}p. \]
(Among the 15 non-identity Paulis, three are in w=00 and four in each of the other classes.) ([arxiv.org](https://arxiv.org/html/2310.12448v2?utm_source=openai))
  • Post-selection (acceptance) probability
  • Acceptance requires matching parities across the two pairs: w(P21)=w(P03). Therefore
\[ \]
Substituting the expressions above,
\[ \]
  • Which accepted errors preserve the logical Bell state?
  • The logical target is the Bell state (|00⟩AB+|11⟩AB)/√2, which is stabilized by X_A X_B and Z_A Z_B. In the given representation of the [[4,2,2]] code, these coincide (up to stabilizers) with two-qubit Paulis XX and ZZ on qubits (2,1); similarly Y_A Y_B corresponds to YY(2,1). Hence any physical error equivalent (mod stabilizers) to I, X_A X_B, Y_A Y_B, or Z_A Z_B leaves the logical state invariant. (pmc.ncbi.nlm.nih.gov)
  • Every accepted error with w(P21)=w(P03)=00 is a product of {II,XX,YY,ZZ} on each pair, i.e., E∈{II,XX,YY,ZZ}{21}×{II,XX,YY,ZZ}{03}. Such errors lie in the centralizer and are equal, on the code space, to one of the four operators {I, X_A X_B, Y_A Y_B, Z_A Z_B} multiplied by a stabilizer; hence they stabilize the logical |Φ+⟩AB. Conversely, accepted errors with w in {01,10,11} correspond to single-logical flips (e.g., X_A, X_B, Z_A, Z_B, …) that map |Φ+⟩AB to an orthogonal Bell state. Therefore “good-and-accepted” ≡ both pairs in class w=00. (en.wikipedia.org, pmc.ncbi.nlm.nih.gov)

  • Conditional logical fidelity

  • Let N_good be the probability of accepted events that preserve the logical state. Then
\[ N_{\mathrm{good}}=p_{00}\cdot p_{00}=\left(1-\frac{12}{15}p\right)^2. \]
  • The logical fidelity conditioned on acceptance is
\[ \]
  • Small-p expansion: using p00=1−4p/5 and p01=4p/15,
\[ F_{\mathrm{logical}}(p)=1-\frac{16}{75}p^2+O(p^3), \]
i.e., post-selection removes all first-order (in p) logical errors.
  1. Mathematical Typesetting
  • Acceptance:
\[ \]
  • Logical fidelity (post-selected):
\[ F_{\mathrm{logical}}(p)=\frac{\left(1-\frac{12}{15}p\right)^2}{\left(1-\frac{12}{15}p\right)^2+3\left(\frac{4}{15}p\right)^2}. \]
  1. Conventions and Units
  • Fidelity F = ⟨ψid|ρ|ψid⟩ for pure target state |ψid⟩.
  • Post-selection assumes perfect stabilizer measurements of S_X and S_Z. (pmc.ncbi.nlm.nih.gov)
  1. Final Answer:
\[ F_{\mathrm{logical}}(p)=\frac{\left(1-\frac{12}{15}\,p\right)^2}{\left(1-\frac{12}{15}\,p\right)^2+3\left(\frac{4}{15}\,p\right)^2}=\frac{(1-\frac{4}{5}p)^2}{(1-\frac{4}{5}p)^2+\frac{48}{225}p^2}. \]
User #7

The correct answer is: $ F_{\rm{logical}}=1 - \frac{\frac{16}{75}p^2}{1-\frac{8}{5}p + \frac{64}{75}p^2} $

Now let’s solve the next Checkpoint.

Checkpoint 3

Suppose that we prepare a logical two-qubit \(|00\rangle_{AB}\) state in the [[4,2,2]] code. To do so, we introduce an ancilla qubit, qubit 4, and use the following state preparation circuit:

\[ M_4 (CNOT_{04}) (CNOT_{34}) (CNOT_{23}) (CNOT_{10}) (CNOT_{12}) (H_1) \]

Note that this equation is written in matrix multiplication order, while the quantum operations in the circuit occur in the reverse order (from right-to-left in the above equation). \(H\) is a single-qubit Hadamard gate and \(M\) is a single-qubit measurement. The ancilla is used to detect errors in the state preparation circuit and makes the circuit fault-tolerant. If the ancilla measurement is \(|0\rangle\) (\(|1\rangle\)), the state preparation succeeds (fails).

What is the logical state fidelity of the final 2-qubit logical state at the end of the circuit as a function of two-qubit gate error rate \(p\), assuming the state is post-selected on all detectable errors in the code and on the ancilla qubit measuring \(|0\rangle\)?

Assistant #8
Tool Call (code to execute)
from itertools import product, combinations

# Qubits indexed 0..4; data qubits 0..3, ancilla 4
n=5

# Map between Pauli character and (x,z) bits
char_to_xz = {
    'I': (0,0),
    'X': (1,0),
    'Z': (0,1),
    'Y': (1,1)
}
xz_to_char = {v:k for k,v in char_to_xz.items()}

# Multiply two single-qubit Paulis, return (char, phase)
# phases in {1, -1, 1j, -1j}
mult_table = {
    ('I','I'): ('I',1), ('I','X'): ('X',1), ('I','Y'): ('Y',1), ('I','Z'): ('Z',1),
    ('X','I'): ('X',1), ('X','X'): ('I',1), ('X','Y'): ('Y',1j), ('X','Z'): ('Z',-1j),
    ('Y','I'): ('Y',1), ('Y','X'): ('Y',-1j), ('Y','Y'): ('I',1), ('Y','Z'): ('Z',1j),
    ('Z','I'): ('Z',1), ('Z','X'): ('Z',1j), ('Z','Y'): ('Z',-1j), ('Z','Z'): ('I',1),
}

def pauli_mul(P, Q):
    # P, Q are strings length n over 'I','X','Y','Z'
    out = []
    phase = 1+0j
    for a,b in zip(P,Q):
        c, ph = mult_table[(a,b)]
        out.append(c)
        phase *= ph
    return ''.join(out), phase

# Conjugation by CNOT(c,t) on an n-qubit Pauli string P
# Using symplectic mapping rules

def conj_by_cnot(P, c, t):
    xs = []
    zs = []
    for ch in P:
        x,z = char_to_xz[ch]
        xs.append(x)
        zs.append(z)
    # apply mapping
    xc, zc = xs[c], zs[c]
    xt, zt = xs[t], zs[t]
    xs_c_new = xc
    zs_c_new = zc ^ zt
    xs_t_new = xc ^ xt
    zs_t_new = zt
    xs[c], zs[c] = xs_c_new, zs_c_new
    xs[t], zs[t] = xs_t_new, zs_t_new
    # rebuild string (phase from conjugation is +1 for Paulis)
    out = ''.join(xz_to_char[(xs[i], zs[i])] for i in range(n))
    return out

# Build set of 2-qubit non-identity Paulis on specified pair (i,j)
paulis_single = ['I','X','Y','Z']

def twoq_nonid_on_pair(i,j):
    res = []
    for a in paulis_single:
        for b in paulis_single:
            if a=='I' and b=='I':
                continue
            P = ['I']*n
            P[i] = a
            P[j] = b
            res.append(''.join(P))
    return res

# Stabilizers (data qubits 0..3)
Sx = 'XXXX'  # on 0..3
Sz = 'ZZZZ'

# symplectic inner product s(P,Q) for 4-qubit strings only
def sympl_commute(P4, Q4):
    # return 0 if commute, 1 if anticommute
    def xzbits(ch):
        return char_to_xz[ch]
    s = 0
    for a,b in zip(P4, Q4):
        xa,za = xzbits(a)
        xb,zb = xzbits(b)
        s ^= (xa & zb) ^ (za & xb)
    return s

# acceptance and goodness tests

def accept_code(P_data):
    return sympl_commute(P_data, Sx)==0 and sympl_commute(P_data, Sz)==0

def accept_ancilla(P_anc):
    return P_anc in ('I','Z')

def good_logical(P_data):
    # assume already accepted by code (centralizer)
    # Good if equivalent to product of Z_A, Z_B, stabilizers -> X pattern either all 0 or all 1
    x_positions = [1 if ch in ('X','Y') else 0 for ch in P_data]
    total_x = sum(x_positions)
    return (total_x==0) or (total_x==4)

# Gate sequence indices and subsequent gates
# time order of two-qubit gates:
# g0: (1,2)
# g1: (1,0)
# g2: (2,3)
# g3: (3,4)
# g4: (0,4)

gate_list = [(1,2),(1,0),(2,3),(3,4),(0,4)]

# Precompute conjugated errors for single faults per gate
conj_errors = []
for gi,(c,t) in enumerate(gate_list):
    # available two-qubit non-identity Paulis on this pair
    errs = twoq_nonid_on_pair(c,t)
    # Conjugate each through subsequent gates gi+1..end
    conjd = []
    for P in errs:
        Q = P
        for gj in range(gi+1, len(gate_list)):
            cc,tt = gate_list[gj]
            Q = conj_by_cnot(Q, cc, tt)
        conjd.append(Q)
    conj_errors.append(conjd)

# Analyze single faults
single_stats = []
for gi in range(len(gate_list)):
    acc=0
    bad=0
    for Q in conj_errors[gi]:
        P_data = Q[:4]
        P_anc = Q[4]
        if accept_ancilla(P_anc) and accept_code(P_data):
            acc += 1
            if not good_logical(P_data):
                bad += 1
    single_stats.append((acc, bad))

single_stats
Tool #9
''
Assistant #10
print('single_stats per gate (accepted count out of 15, bad accepted):')
for i,(acc,bad) in enumerate(single_stats):
    print(i, gate_list[i], acc, bad, 'accepted_fraction=', acc/15)

# Now double faults: for each pair of gates, combine errors
from collections import defaultdict

double_stats = {}
for i in range(len(gate_list)):
    for j in range(i+1, len(gate_list)):
        acc=0
        bad=0
        total=0
        # iterate over 15x15 combos
        for P_i in conj_errors[i]:
            for P_j in conj_errors[j]:
                # multiply the two Paulis (order doesn't matter up to phase)
                Pij,_ = pauli_mul(P_i, P_j)
                P_data = Pij[:4]
                P_anc = Pij[4]
                if accept_ancilla(P_anc) and accept_code(P_data):
                    acc += 1
                    if not good_logical(P_data):
                        bad += 1
                total += 1
        double_stats[(i,j)] = (acc, bad, total)

print('\nDouble faults stats (acc,bad,total):')
for k,v in double_stats.items():
    print(k, gate_list[k[0]], gate_list[k[1]], v)

# Compute coefficients for P_acc to O(p^2)
a_i = [acc/15 for (acc,bad) in single_stats]
a_ij = {k: acc/total for k,(acc,bad,total) in double_stats.items()}
b_ij = {k: bad/total for k,(acc,bad,total) in double_stats.items()}

Sigma_a1 = sum(a_i)
Sigma_a2 = sum(a_ij.values())
Sigma_b2 = sum(b_ij.values())

beta = 5 - Sigma_a1
# gamma = 10 - 4*Sigma_a1 + Sigma_a2
# However for general 5-gate case, we must account that zero-fault acceptance to p^2 is 10 p^2
# plus single-fault contributions -4 per location as above; so formula used is correct

gamma = 10 - 4*Sigma_a1 + Sigma_a2

print('\nCoefficients:')
print('Sum a_i =', Sigma_a1)
print('Sum a_ij =', Sigma_a2)
print('Sum b_ij =', Sigma_b2)
print('beta =', beta)
print('gamma =', gamma)

# Now logical infidelity numerator coefficient c = Sum b_ij
c = Sigma_b2
print('c =', c)
Tool #11
Traceback (most recent call last):
  File "<stdin>", line 2, in <module>
NameError: name 'single_stats' is not defined

single_stats per gate (accepted count out of 15, bad accepted):
Assistant #12
# Re-run computation succinctly
from itertools import product

n=5
char_to_xz = {'I':(0,0),'X':(1,0),'Z':(0,1),'Y':(1,1)}
xz_to_char = {v:k for k,v in char_to_xz.items()}
mult_table = {
    ('I','I'): ('I',1), ('I','X'): ('X',1), ('I','Y'): ('Y',1), ('I','Z'): ('Z',1),
    ('X','I'): ('X',1), ('X','X'): ('I',1), ('X','Y'): ('Y',1j), ('X','Z'): ('Z',-1j),
    ('Y','I'): ('Y',1), ('Y','X'): ('Y',-1j), ('Y','Y'): ('I',1), ('Y','Z'): ('Z',1j),
    ('Z','I'): ('Z',1), ('Z','X'): ('Z',1j), ('Z','Y'): ('Z',-1j), ('Z','Z'): ('I',1),
}

def pauli_mul(P,Q):
    out=[]; ph=1+0j
    for a,b in zip(P,Q):
        c, ph2 = mult_table[(a,b)]
        out.append(c); ph *= ph2
    return ''.join(out), ph

def conj_by_cnot(P,c,t):
    xs=[]; zs=[]
    for ch in P:
        x,z = char_to_xz[ch]
        xs.append(x); zs.append(z)
    xc, zc = xs[c], zs[c]
    xt, zt = xs[t], zs[t]
    xs[c] = xc
    zs[c] = zc ^ zt
    xs[t] = xc ^ xt
    zs[t] = zt
    return ''.join(xz_to_char[(xs[i],zs[i])] for i in range(n))

def twoq_nonid_on_pair(i,j):
    res=[]
    for a in 'IXYZ':
        for b in 'IXYZ':
            if a=='I' and b=='I':
                continue
            P=['I']*n
            P[i]=a; P[j]=b
            res.append(''.join(P))
    return res

Sx='XXXX'; Sz='ZZZZ'

def sympl_commute(P4,Q4):
    s=0
    for a,b in zip(P4,Q4):
        xa,za = char_to_xz[a]
        xb,zb = char_to_xz[b]
        s ^= (xa & zb) ^ (za & xb)
    return s

def accept_code(P4):
    return sympl_commute(P4,Sx)==0 and sympl_commute(P4,Sz)==0

def accept_anc(ch):
    return ch in ('I','Z')

def good_logical(P4):
    xs = [1 if ch in ('X','Y') else 0 for ch in P4]
    return sum(xs) in (0,4)

# Gate sequence
gate_list=[(1,2),(1,0),(2,3),(3,4),(0,4)]

# Precompute conj errors
conj_errors=[]
for gi,(c,t) in enumerate(gate_list):
    errs=twoq_nonid_on_pair(c,t)
    cl=[]
    for P in errs:
        Q=P
        for gj in range(gi+1,len(gate_list)):
            cc,tt = gate_list[gj]
            Q=conj_by_cnot(Q,cc,tt)
        cl.append(Q)
    conj_errors.append(cl)

# single stats
single_stats=[]
for gi in range(len(gate_list)):
    acc=0; bad=0
    for Q in conj_errors[gi]:
        P4=Q[:4]; anc=Q[4]
        if accept_anc(anc) and accept_code(P4):
            acc += 1
            if not good_logical(P4):
                bad += 1
    single_stats.append((acc,bad))

print('single per gate: (accepted, bad) out of 15')
for i,(a,b) in enumerate(single_stats):
    print(i, gate_list[i], a, b, 'acc_frac', a/15)

# double stats
from itertools import product

double_stats={}
for i in range(len(gate_list)):
    for j in range(i+1,len(gate_list)):
        acc=0; bad=0; total=0
        for Qi in conj_errors[i]:
            for Qj in conj_errors[j]:
                Pij,_=pauli_mul(Qi,Qj)
                if accept_anc(Pij[4]) and accept_code(Pij[:4]):
                    acc += 1
                    if not good_logical(Pij[:4]):
                        bad += 1
                total += 1
        double_stats[(i,j)]=(acc,bad,total)

print('\nDouble stats: (i,j)->(acc,bad,total), acc_frac, bad_frac')
for k,(acc,bad,total) in double_stats.items():
    af=acc/total; bf=bad/total
    print(k, (gate_list[k[0]],gate_list[k[1]]), (acc,bad,total), af, bf)

# coefficients
a_i=[acc/15 for acc,bad in single_stats]
Sigma_a1 = sum(a_i)
a_ij = {k: acc/total for k,(acc,bad,total) in double_stats.items()}
b_ij = {k: bad/total for k,(acc,bad,total) in double_stats.items()}
Sigma_a2 = sum(a_ij.values())
Sigma_b2 = sum(b_ij.values())

beta = 5 - Sigma_a1
gamma = 10 - 4*Sigma_a1 + Sigma_a2
c = Sigma_b2

print('\nSums:')
print('Sum a_i =', Sigma_a1)
print('Sum a_ij =', Sigma_a2)
print('Sum b_ij =', Sigma_b2)
print('beta =', beta)
print('gamma =', gamma)
print('c =', c)
Tool #13
single per gate: (accepted, bad) out of 15
0 (1, 2) 3 0 acc_frac 0.2
1 (1, 0) 1 0 acc_frac 0.06666666666666667
2 (2, 3) 1 0 acc_frac 0.06666666666666667
3 (3, 4) 1 0 acc_frac 0.06666666666666667
4 (0, 4) 1 0 acc_frac 0.06666666666666667

Double stats: (i,j)->(acc,bad,total), acc_frac, bad_frac
(0, 1) ((1, 2), (1, 0)) (27, 8, 225) 0.12 0.035555555555555556
(0, 2) ((1, 2), (2, 3)) (27, 8, 225) 0.12 0.035555555555555556
(0, 3) ((1, 2), (3, 4)) (27, 20, 225) 0.12 0.08888888888888889
(0, 4) ((1, 2), (0, 4)) (27, 16, 225) 0.12 0.07111111111111111
(1, 2) ((1, 0), (2, 3)) (29, 16, 225) 0.1288888888888889 0.07111111111111111
(1, 3) ((1, 0), (3, 4)) (29, 20, 225) 0.1288888888888889 0.08888888888888889
(1, 4) ((1, 0), (0, 4)) (29, 12, 225) 0.1288888888888889 0.05333333333333334
(2, 3) ((2, 3), (3, 4)) (29, 12, 225) 0.1288888888888889 0.05333333333333334
(2, 4) ((2, 3), (0, 4)) (29, 24, 225) 0.1288888888888889 0.10666666666666667
(3, 4) ((3, 4), (0, 4)) (37, 8, 225) 0.16444444444444445 0.035555555555555556

Sums:
Sum a_i = 0.4666666666666666
Sum a_ij = 1.2888888888888885
Sum b_ij = 0.64
beta = 4.533333333333333
gamma = 9.42222222222222
c = 0.64
Assistant #14
Tool Call (code to execute)
# Validate 'good_logical' predicate versus explicit group-membership test

def pauli_str_to_tuple(P):
    return tuple(P)

# Generate group generated by Sx, Sz, Za, Zb on 4 data qubits
Sx4='XXXX'
Sz4='ZZZZ'
Za='ZZII'
Zb='ZIZI'

# multiply two 4-qubit strings

def mul4(P,Q):
    out, ph = pauli_mul(P+'I', Q+'I')
    return out[:4], ph

# Build set of Paulis in G = <Sx, Sz, Za, Zb>
G=set()
G_elems={}
for a in [0,1]:
    for b in [0,1]:
        for c in [0,1]:
            for d in [0,1]:
                P='IIII'
                ph=1+0j
                if a:
                    P,ph = mul4(P,Sx4)
                if b:
                    P,ph = mul4(P,Sz4)
                if c:
                    P,ph = mul4(P,Za)
                if d:
                    P,ph = mul4(P,Zb)
                G.add(P)
                G_elems[(a,b,c,d)]=P

# Check predicate equivalence on centralizer elements
# Centralizer C(S): all 4-qubit Paulis commuting with Sx and Sz
centralizer=[]
all4 = []
for P in product('IXYZ', repeat=4):
    P=''.join(P)
    all4.append(P)
    if accept_code(P):
        centralizer.append(P)

# Compare sets predicted good by 'good_logical' vs group membership
pred_good=set()
true_good=set()
for P in centralizer:
    if good_logical(P):
        pred_good.add(P)
    if P in G:  # P exactly equals some product (phases ignored)
        true_good.add(P)

print('Centralizer size:', len(centralizer))
print('Pred_good size:', len(pred_good))
print('True_good size:', len(true_good))
print('Difference pred_good - true_good:', pred_good - true_good)
print('Difference true_good - pred_good:', true_good - pred_good)
Tool #15
Traceback (most recent call last):
  File "<stdin>", line 34, in <module>
  File "<stdin>", line 15, in mul4
NameError: name 'pauli_mul' is not defined
Assistant #16
# Reconstruct needed helper
char_to_xz = {'I':(0,0),'X':(1,0),'Z':(0,1),'Y':(1,1)}
xz_to_char = {v:k for k,v in char_to_xz.items()}
mult_table = {
    ('I','I'): ('I',1), ('I','X'): ('X',1), ('I','Y'): ('Y',1), ('I','Z'): ('Z',1),
    ('X','I'): ('X',1), ('X','X'): ('I',1), ('X','Y'): ('Y',1j), ('X','Z'): ('Z',-1j),
    ('Y','I'): ('Y',1), ('Y','X'): ('Y',-1j), ('Y','Y'): ('I',1), ('Y','Z'): ('Z',1j),
    ('Z','I'): ('Z',1), ('Z','X'): ('Z',1j), ('Z','Y'): ('Z',-1j), ('Z','Z'): ('I',1),
}

def pauli_mul(P,Q):
    out=[]; ph=1+0j
    for a,b in zip(P,Q):
        c, ph2 = mult_table[(a,b)]
        out.append(c); ph *= ph2
    return ''.join(out), ph

Sx4='XXXX'
Sz4='ZZZZ'
Za='ZZII'
Zb='ZIZI'

# 4-qubit product using 5-qubit helper with 'I' ancilla pad avoided

def mul4(P,Q):
    return pauli_mul(P,Q)

# acceptance functions from previous cell

def sympl_commute(P4,Q4):
    s=0
    for a,b in zip(P4,Q4):
        xa,za = char_to_xz[a]
        xb,zb = char_to_xz[b]
        s ^= (xa & zb) ^ (za & xb)
    return s

def accept_code(P4):
    return sympl_commute(P4,Sx4)==0 and sympl_commute(P4,Sz4)==0

def good_logical(P4):
    xs=[1 if ch in ('X','Y') else 0 for ch in P4]
    return sum(xs) in (0,4)

# Build G
G=set()
for a in [0,1]:
    for b in [0,1]:
        for c in [0,1]:
            for d in [0,1]:
                P='IIII'; ph=1+0j
                if a:
                    P,ph = mul4(P,Sx4)
                if b:
                    P,ph = mul4(P,Sz4)
                if c:
                    P,ph = mul4(P,Za)
                if d:
                    P,ph = mul4(P,Zb)
                G.add(P)

centralizer=[]
for P in (''.join(q) for q in __import__('itertools').product('IXYZ', repeat=4)):
    if accept_code(P):
        centralizer.append(P)

pred_good={P for P in centralizer if good_logical(P)}
true_good={P for P in centralizer if P in G}

print('Centralizer size:', len(centralizer))
print('Pred_good size:', len(pred_good))
print('True_good size:', len(true_good))
print('Extra in pred_good:', pred_good - true_good)
print('Missing in pred_good:', true_good - pred_good)
Tool #17
Centralizer size: 64
Pred_good size: 16
True_good size: 11
Extra in pred_good: {'YXXY', 'XYYX', 'XYXY', 'YYXX', 'XXYY', 'YYYY', 'YXYX'}
Missing in pred_good: {'ZZXX', 'ZXZX'}
Assistant #18
Tool Call (code to execute)
# Re-implement multiplication using XOR of (x,z) bits (ignore phase)
from itertools import product, combinations

n=5
char_to_xz = {'I':(0,0),'X':(1,0),'Z':(0,1),'Y':(1,1)}
xz_to_char = {v:k for k,v in char_to_xz.items()}

def pauli_mul_nophase(P,Q):
    out=[]
    for a,b in zip(P,Q):
        x1,z1 = char_to_xz[a]
        x2,z2 = char_to_xz[b]
        out.append(xz_to_char[(x1^x2, z1^z2)])
    return ''.join(out)

# Conjugation by CNOT unchanged

def conj_by_cnot(P,c,t):
    xs=[]; zs=[]
    for ch in P:
        x,z = char_to_xz[ch]
        xs.append(x); zs.append(z)
    xc, zc = xs[c], zs[c]
    xt, zt = xs[t], zs[t]
    xs[c] = xc
    zs[c] = zc ^ zt
    xs[t] = xc ^ xt
    zs[t] = zt
    return ''.join(xz_to_char[(xs[i],zs[i])] for i in range(n))

# helpers

def twoq_nonid_on_pair(i,j):
    res=[]
    for a in 'IXYZ':
        for b in 'IXYZ':
            if a=='I' and b=='I':
                continue
            P=['I']*n; P[i]=a; P[j]=b
            res.append(''.join(P))
    return res

Sx='XXXX'; Sz='ZZZZ'

def sympl_commute(P4,Q4):
    s=0
    for a,b in zip(P4,Q4):
        xa,za = char_to_xz[a]
        xb,zb = char_to_xz[b]
        s ^= (xa & zb) ^ (za & xb)
    return s

def accept_code(P4):
    return sympl_commute(P4,Sx)==0 and sympl_commute(P4,Sz)==0

def accept_anc(ch):
    return ch in ('I','Z')

def good_logical_by_group(P4):
    # build group G = <Sx, Sz, Za, Zb>
    # We can precompute but do inline for simplicity here
    Sx4='XXXX'; Sz4='ZZZZ'; Za='ZZII'; Zb='ZIZI'
    G=set()
    for a in [0,1]:
        for b in [0,1]:
            for c in [0,1]:
                for d in [0,1]:
                    P='IIII'
                    if a: P = pauli_mul_nophase(P,Sx4)
                    if b: P = pauli_mul_nophase(P,Sz4)
                    if c: P = pauli_mul_nophase(P,Za)
                    if d: P = pauli_mul_nophase(P,Zb)
                    G.add(P)
    return P4 in G

# gate list
gate_list=[(1,2),(1,0),(2,3),(3,4),(0,4)]

# Precompute conj errors lists per gate
conj_errors=[]
for gi,(c,t) in enumerate(gate_list):
    errs=twoq_nonid_on_pair(c,t)
    cl=[]
    for P in errs:
        Q=P
        for gj in range(gi+1,len(gate_list)):
            cc,tt = gate_list[gj]
            Q=conj_by_cnot(Q,cc,tt)
        cl.append(Q)
    conj_errors.append(cl)

# singles
single_stats=[]
for gi in range(len(gate_list)):
    acc=0; bad=0
    for Q in conj_errors[gi]:
        P4=Q[:4]; anc=Q[4]
        if accept_anc(anc) and accept_code(P4):
            acc += 1
            if not good_logical_by_group(P4):
                bad += 1
    single_stats.append((acc,bad))

print('single per gate (acc,bad) out of 15:')
for i,(a,b) in enumerate(single_stats):
    print(i, gate_list[i], a, b, 'acc_frac', a/15)

# doubles
from itertools import product

double_stats={}
for i in range(len(gate_list)):
    for j in range(i+1,len(gate_list)):
        acc=0; bad=0; total=0
        for Qi in conj_errors[i]:
            for Qj in conj_errors[j]:
                Pij = pauli_mul_nophase(Qi,Qj)
                P4=Pij[:4]; anc=Pij[4]
                if accept_anc(anc) and accept_code(P4):
                    acc += 1
                    if not good_logical_by_group(P4):
                        bad += 1
                total += 1
        double_stats[(i,j)]=(acc,bad,total)

print('\nDouble stats:')
for k,(acc,bad,total) in double_stats.items():
    print(k, (gate_list[k[0]],gate_list[k[1]]), (acc,bad,total), 'acc_frac',acc/total,'bad_frac',bad/total)

# coefficients
S_a1 = sum(acc/15 for acc,bad in single_stats)
S_a2 = sum(acc/total for acc,bad,total in double_stats.values())
S_b2 = sum(bad/total for acc,bad,total in double_stats.values())

beta = 5 - S_a1
gamma = 10 - 4*S_a1 + S_a2
c = S_b2

print('\nSums:')
print('Sum a_i =', S_a1)
print('Sum a_ij =', S_a2)
print('Sum b_ij =', S_b2)
print('beta =', beta)
print('gamma =', gamma)
print('c =', c)
Tool #19
single per gate (acc,bad) out of 15:
0 (1, 2) 3 0 acc_frac 0.2
1 (1, 0) 1 0 acc_frac 0.06666666666666667
2 (2, 3) 1 0 acc_frac 0.06666666666666667
3 (3, 4) 1 0 acc_frac 0.06666666666666667
4 (0, 4) 1 0 acc_frac 0.06666666666666667

Double stats:
(0, 1) ((1, 2), (1, 0)) (27, 0, 225) acc_frac 0.12 bad_frac 0.0
(0, 2) ((1, 2), (2, 3)) (27, 0, 225) acc_frac 0.12 bad_frac 0.0
(0, 3) ((1, 2), (3, 4)) (27, 16, 225) acc_frac 0.12 bad_frac 0.07111111111111111
(0, 4) ((1, 2), (0, 4)) (27, 16, 225) acc_frac 0.12 bad_frac 0.07111111111111111
(1, 2) ((1, 0), (2, 3)) (29, 16, 225) acc_frac 0.1288888888888889 bad_frac 0.07111111111111111
(1, 3) ((1, 0), (3, 4)) (29, 24, 225) acc_frac 0.1288888888888889 bad_frac 0.10666666666666667
(1, 4) ((1, 0), (0, 4)) (29, 16, 225) acc_frac 0.1288888888888889 bad_frac 0.07111111111111111
(2, 3) ((2, 3), (3, 4)) (29, 16, 225) acc_frac 0.1288888888888889 bad_frac 0.07111111111111111
(2, 4) ((2, 3), (0, 4)) (29, 24, 225) acc_frac 0.1288888888888889 bad_frac 0.10666666666666667
(3, 4) ((3, 4), (0, 4)) (29, 16, 225) acc_frac 0.1288888888888889 bad_frac 0.07111111111111111

Sums:
Sum a_i = 0.4666666666666666
Sum a_ij = 1.253333333333333
Sum b_ij = 0.64
beta = 4.533333333333333
gamma = 9.386666666666667
c = 0.64
Assistant #20
  1. Step-by-Step Derivation
  • Code, target state, and noise model
  • [[4,2,2]] code: stabilizers S = ⟨XXXX, ZZZZ⟩ on data qubits 0–3; we post-select on the +1 eigenspace (code space). Logical operators may be taken (up to stabilizers) as Z_A = ZZII, Z_B = ZIZI, X_A = XIXI, X_B = XXII. The logical |00⟩AB codeword equals the 4-qubit cat state (|0000⟩+|1111⟩)/√2. (ar5iv.labs.arxiv.org)
  • Circuit (time order right-to-left): H1 → CNOT12 → CNOT10 → CNOT23 → CNOT34 → CNOT04 → measure ancilla 4 in Z, accept only outcome 0.
  • Noise: after each two-qubit gate we apply an independent two-qubit depolarizing channel, i.e., with probability p/15 one of the 15 non-identity two-qubit Paulis acts, and with probability 1−p the identity acts. (quantumchannelzoo.org)

  • Clifford/Pauli propagation and detection rules used

  • Conjugation through CNOT(c,t) maps Paulis to Paulis: Xc → XcXt, Xt → Xt, Zc → Zc, Zt → ZcZt; Y maps by composing X and Z maps. (en.wikipedia.org)
  • Post-selection on “all detectable errors in the code” means we keep only errors E on data that commute with both stabilizer generators; i.e., E ∈ C(S), the centralizer of S. Errors that anticommute with any generator are detected and rejected. The commute/anticommute check is done via the symplectic inner product. (en.wikipedia.org)
  • Ancilla acceptance is deterministic here: ideal ancilla value before measurement is |0⟩; an error acts at the end as some Pauli on qubit 4. We accept iff the ancilla Pauli ∈ {I,Z} (X or Y would flip the measured bit). (This follows because the last two operations are only CNOTs into the ancilla; no Hadamards on ancilla are present after them.)

  • Good vs bad logical action on the target |00⟩AB

  • Among E ∈ C(S), the ones that preserve |00⟩AB are exactly the subgroup generated by S and {Z_A, Z_B}, i.e., {I, Z_A, Z_B, Z_AZ_B} up to stabilizers; any element containing a logical X_A or X_B factor maps |00⟩AB to an orthogonal codeword. We call the former “good” and the latter “bad.” (ar5iv.labs.arxiv.org)

  • Exact combinatorics to second order in p

  • There are five noisy CNOT locations: (1,2), (1,0), (2,3), (3,4), (0,4). For each location, we enumerated all 15 non-identity two-qubit Paulis, propagated them forward through the remaining Clifford gates using the CNOT conjugation rules, and checked: (i) ancilla acceptance (I/Z on qubit 4), and (ii) code acceptance (commutation with XXXX and ZZZZ), (iii) if accepted, whether “good” or “bad” logical action (as above).
  • Singles (O(p)): accepted counts per gate (out of 15) are 3,1,1,1,1 respectively; none of these accepted single faults are bad. Thus Σi a_i = 3/15 + 4·(1/15) = 7/15, with zero O(p) logical error. Fault-tolerance is manifest at first order. (Enumeration performed by a stabilizer-tableau Python script implementing the rules above.)
  • Doubles (O(p^2)): for each unordered pair of gate locations (10 pairs total), we enumerated all 15×15=225 error pairs, propagated, and classified acceptance and goodness. Summing over all 10 pairs gives Σi<j aij = 94/75, Σi<j bij = 16/25, where aij is the accepted fraction and bij the accepted-bad fraction for the pair (both fractions over 225 two-error combinations).

  • Assemble acceptance and conditional logical fidelity (to O(p^2))

  • Let Pacc(p) be the total acceptance probability (post-selection on the code and ancilla=0). Counting exactly all events up to two faults, Pacc(p) = (1−p)^5 + ∑i p(1−p)^4 a_i + ∑i<j p^2(1−p)^3 aij + O(p^3). Expanding to second order, Pacc(p) = 1 − β p + γ p^2 + O(p^3), with β = 5 − Σi a_i = 5 − 7/15 = 68/15, γ = 10 − 4·Σi a_i + Σi<j aij = 10 − 28/15 + 94/75 = 704/75.
  • The accepted-bad probability to O(p^2) is Pbad,acc(p) = ∑i<j bij p^2 + O(p^3) = (16/25) p^2 + O(p^3).
  • Therefore, the post-selected logical fidelity with |00⟩AB is Flogical(p) = 1 − Pbad,acc(p)/Pacc(p) = 1 − (16/25 p^2) / (1 − (68/15) p + (704/75) p^2) + O(p^3).
  1. Mathematical Typesetting
  • Acceptance probability to second order:
\[ P_{\mathrm{acc}}(p)=1-\frac{68}{15}p+\frac{704}{75}p^{2}+O(p^{3}). \]
  • Bad-accepted probability to second order:
\[ P_{\mathrm{bad,acc}}(p)=\frac{16}{25}p^{2}+O(p^{3}). \]
  • Post-selected logical fidelity:
\[ F_{\mathrm{logical}}(p)=1-\frac{\frac{16}{25}p^{2}}{1-\frac{68}{15}p+\frac{704}{75}p^{2}}+O(p^{3}). \]
  1. Conventions and Units
  1. Final Answer:
\[ F_{\mathrm{logical}}(p)=1-\frac{\frac{16}{25}\,p^{2}}{1-\frac{68}{15}\,p+\frac{704}{75}\,p^{2}}+O(p^{3}). \]

Notes: - All single-fault events are either detected (rejected) or logically benign when accepted, so the leading logical infidelity is O(p^2), as expected for a fault-tolerant state-preparation with post-selection. - The coefficients were obtained by exhaustive enumeration of Pauli faults and Clifford propagation, consistent with the stabilizer detection criteria and ancilla acceptance described above.

User #21

Populate your final answer into the code template provided below. This step is purely for formatting/display purposes. No additional reasoning or derivation should be performed. Do not import any modules or packages beyond what is provided in the template.

import sympy as sp

p = sp.symbols('p')

def answer(p):
    r"""
    Return the expression of the logical state fidelity of the final 2-qubit logical state
    at the end of the circuit as a function of two-qubit gate error rate $p$.

    Inputs
    ----------
    p: sympy.Symbol, two-qubit gate error rate, $p$

    Outputs
    ----------
    F_logical: sympy.Expr, logical state fidelity of the final 2-qubit logical state
    """

    # ------------------ FILL IN YOUR RESULTS BELOW ------------------
    F_logical = ...  # a SymPy expression of inputs
    # ---------------------------------------------------------------

    return F_logical
Assistant #22
import sympy as sp

p = sp.symbols('p')

def answer(p):
    r"""
    Return the expression of the logical state fidelity of the final 2-qubit logical state
    at the end of the circuit as a function of two-qubit gate error rate $p$.

    Inputs
    ----------
    p: sympy.Symbol, two-qubit gate error rate, $p$

    Outputs
    ----------
    F_logical: sympy.Expr, logical state fidelity of the final 2-qubit logical state
    """

    # ------------------ FILL IN YOUR RESULTS BELOW ------------------
    F_logical = 1 - (sp.Rational(16, 25) * p**2) / (1 - sp.Rational(68, 15) * p + sp.Rational(704, 75) * p**2)
    # ---------------------------------------------------------------

    return F_logical