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.

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\).

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
  1. Step-by-Step Derivation
  • Ideal state prepared by the circuit
  • Start from |0000⟩.
  • Apply H2 then CNOT21: this prepares a Bell pair on qubits (2,1),
\[ |\Phi^+\rangle_{21}=\frac{|00\rangle_{21}+|11\rangle_{21}}{\sqrt{2}}. \]
  • Apply H0 then CNOT03: this prepares a Bell pair on qubits (0,3),
\[ |\Phi^+\rangle_{03}=\frac{|00\rangle_{03}+|11\rangle_{03}}{\sqrt{2}}. \]
  • Since the two halves of the circuit act on disjoint qubit pairs, the ideal final 4-qubit state is
\[ |\psi_{\text{ideal}}\rangle=|\Phi^+\rangle_{21}\otimes|\Phi^+\rangle_{03}. \]
  • Noise model and independence across pairs
  • After each CNOT, a two-qubit depolarizing channel acts on that CNOT’s qubit pair:
\[ \mathcal{D}_p(\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}$.
  • The two channels act on disjoint pairs (first on qubits 2&1, second on 0&3) and are independent. Because no subsequent gates couple these pairs, the final state factorizes:
\[ \rho_{\text{out}}=\mathcal{D}_p^{(21)}\!\big(|\Phi^+\rangle\langle\Phi^+|_{21}\big)\;\otimes\;\mathcal{D}_p^{(03)}\!\big(|\Phi^+\rangle\langle\Phi^+|_{03}\big). \]
  • Fidelity for one Bell pair under two-qubit depolarizing noise
  • For \(|\Phi^+\rangle\), the (density-matrix) stabilizer up to sign is
\[ \{II,\;XX,\;YY,\;ZZ\}. \]
For these Paulis $P$, one has $P|\Phi^+\rangle=\pm|\Phi^+\rangle$, which leaves the projector $|\Phi^+\rangle\langle\Phi^+|$ unchanged.
  • Under \(\mathcal{D}_p\), the event “no error” occurs with probability \((1-p)\) and yields fidelity 1. If an error occurs, it is uniformly one of the 15 non-identity two-qubit Paulis. Exactly 3 of these (XX, YY, ZZ) preserve \(|\Phi^+\rangle\langle\Phi^+|\).
  • Hence the single-pair fidelity is
\[ F_{\text{pair}}(p)=(1-p)+\frac{3}{15}p=1-\frac{4}{5}p. \]
  • Total 4-qubit fidelity
  • Since the two subsystems are independent and the ideal state is a product, the total fidelity factorizes:
\[ F_{\text{total}}(p)=F_{\text{pair}}(p)\times F_{\text{pair}}(p)=\left(1-\frac{4}{5}p\right)^2. \]
  1. Mathematical Typesetting - Already included above.

  2. Conventions and Units - Two-qubit depolarizing channel after each CNOT with error probability \(p\) as specified.

  3. Final Answer:

\[ F_{\text{phys}}(p)=\left(1-\frac{4}{5}p\right)^2=1-\frac{8}{5}p+\frac{16}{25}p^2. \]
User #3

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 #4
  1. Step-by-Step Derivation
  • Ideal encoded target state
  • The circuit prepares two independent Bell pairs on disjoint qubit pairs:
    • On qubits (2,1): after \((H_2)\) and \((CNOT_{21})\) we have \(|\Phi^+\rangle_{21}=(|00\rangle+|11\rangle)/\sqrt{2}\).
    • On qubits (0,3): after \((H_0)\) and \((CNOT_{03})\) we have \(|\Phi^+\rangle_{03}\).
  • The ideal 4-qubit state is
\[ |\Psi_{\text{ideal}}\rangle=|\Phi^+\rangle_{21}\otimes|\Phi^+\rangle_{03}. \]
  • This state lies in the codespace (stabilized by \(XXXX\) and \(ZZZZ\)) and encodes the logical Bell (GHZ) state \((|00\rangle_{AB}+|11\rangle_{AB})/\sqrt{2}\).

  • Noise model on each CNOT and its effect on one Bell pair

  • After each CNOT, a 2-qubit depolarizing channel acts on that pair:
\[ \mathcal{D}_p(\rho)=(1-p)\rho+\frac{p}{15}\sum_{P\in\mathcal{P}_2\setminus\{II\}}P\rho P. \]
  • For a single Bell pair \(|\Phi^+\rangle\), classify the 15 non-identity two-qubit Paulis by their commutation with the pair stabilizers \(XX\) and \(ZZ\):
    • Commute with both \(XX\) and \(ZZ\) (leave \(|\Phi^+\rangle\) invariant up to phase): exactly 3 elements \(\{XX,YY,ZZ\}\).
    • Anticommute with exactly one of them: 4 elements each, mapping \(|\Phi^+\rangle\) to one of the other three Bell states:
    • Flip \(XX\) only: \(|\Phi^+\rangle\to|\Phi^-\rangle\).
    • Flip \(ZZ\) only: \(|\Phi^+\rangle\to|\Psi^+\rangle\).
    • Flip both: \(|\Phi^+\rangle\to|\Psi^-\rangle\).
  • Thus for one pair, the probabilities for the “Bell-type label” \(c\in\{00,10,01,11\}\) (whether the \(XX\) and \(ZZ\) eigenvalues flip) are
\[ \]
  • Post-selection on the [[4,2,2]] code
  • The code checks are \(M_X=XXXX=(XX)_{21}\otimes(XX)_{03}\) and \(M_Z=ZZZZ=(ZZ)_{21}\otimes(ZZ)_{03}\).
  • A run is accepted iff the products of the pair eigenvalues are \(+1\) for both \(M_X\) and \(M_Z\). Equivalently, the two pairs must have the same Bell-type label:
\[ \text{accept} \iff c_{21}=c_{03}\in\{00,10,01,11\}. \]
  • Therefore the acceptance probability is
\[ \]
  • Logical state after post-selection and its fidelity
  • Conditioned on acceptance, the two pairs end up in the same Bell state:
    • If \(c=00\), both are \(|\Phi^+\rangle\), which is exactly the target logical Bell state.
    • If \(c\in\{10,01,11\}\), both pairs are in the same other Bell state (\(|\Phi^-\rangle\), \(|\Psi^+\rangle\), or \(|\Psi^-\rangle\)), which corresponds to a nontrivial logical Pauli on \(A\) or \(B\) and is orthogonal to the target logical state.
  • Hence the logical fidelity conditioned on acceptance is the conditional probability of \(c=00\):
\[ \]
  • Simplify:
\[ \]
For small $p$: $F_{\text{log}}(p)=1-\frac{16}{75}p^2+O(p^3)$, showing first-order errors are entirely post-selected away.
  1. Mathematical Typesetting - All mathematical expressions are provided in LaTeX.

  2. Conventions and Units - Two-qubit depolarizing channel with error probability \(p\) acts once after each of the two CNOTs. - Post-selection keeps only runs with \(+1\) outcomes for both stabilizers \(XXXX\) and \(ZZZZ\) (perfect stabilizer measurement assumed).

  3. Final Answer:

\[ \]
User #5

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 #6
Tool Call (code to execute)
import itertools
from functools import lru_cache

# Define Pauli multiplication ignoring global phases
paulis = ['I','X','Y','Z']
mult_table = {
    ('I','I'):'I', ('I','X'):'X', ('I','Y'):'Y', ('I','Z'):'Z',
    ('X','I'):'X', ('X','X'):'I', ('X','Y'):'Z', ('X','Z'):'Y',
    ('Y','I'):'Y', ('Y','X'):'Z', ('Y','Y'):'I', ('Y','Z'):'X',
    ('Z','I'):'Z', ('Z','X'):'Y', ('Z','Y'):'X', ('Z','Z'):'I',
}

def pmul(a,b):
    # a,b: single-qubit pauli labels
    return mult_table[(a,b)]

# Multiply two 5-qubit pauli strings (ignoring phase)
def str_mul(P, Q):
    return tuple(pmul(p,q) for p,q in zip(P,Q))

I5 = tuple('I'*5)

def cnot_conj(P, control, target):
    # Conjugate 5-qubit Pauli string P by CNOT_{control->target}
    P = list(P)
    pc, pt = P[control], P[target]
    # Map according to standard rules
    # Control mapping
    if pc == 'X':
        # X_c -> X_c X_t
        if P[target] == 'I':
            P[target] = 'X'
        elif P[target] == 'X':
            P[target] = 'I'
        elif P[target] == 'Y':
            P[target] = 'Z'
        elif P[target] == 'Z':
            P[target] = 'Y'
    elif pc == 'Y':
        # Y_c -> Y_c X_t
        if P[target] == 'I':
            P[target] = 'X'
        elif P[target] == 'X':
            P[target] = 'I'
        elif P[target] == 'Y':
            P[target] = 'Z'
        elif P[target] == 'Z':
            P[target] = 'Y'
        # P[control] remains 'Y'
    # Z_c unchanged

    # Target mapping
    pt = P[target]
    if P[target] == 'Z':
        # Z_t -> Z_c Z_t
        # Multiply Z on control position ignoring phase
        P[control] = pmul(P[control], 'Z')
    elif P[target] == 'Y':
        # Y_t = i X_t Z_t -> Z_c Y_t
        P[control] = pmul(P[control], 'Z')
        # Y_t unaffected otherwise
    # X_t unchanged

    return tuple(P)

# Test cnot conjugation against known cases
# Quick sanity checks
assert cnot_conj( ('X','I','I','I','I'), 0,1 ) == ('X','X','I','I','I')
assert cnot_conj( ('Z','I','I','I','I'), 0,1 ) == ('Z','I','I','I','I')
assert cnot_conj( ('I','X','I','I','I'), 0,1 ) == ('I','X','I','I','I')
assert cnot_conj( ('I','Z','I','I','I'), 0,1 ) == ('Z','Z','I','I','I')

# Build mapping from location 2-qubit pauli to final 5-qubit pauli after conjugating through later gates
locations = [ (1,2), (1,0), (2,3), (3,4), (0,4) ]  # ordered L1..L5
# Subsequent gates for each location
subseq_cnots = {
    0: [(1,0),(2,3),(3,4),(0,4)],  # after L1
    1: [(2,3),(3,4),(0,4)],        # after L2
    2: [(3,4),(0,4)],              # after L3
    3: [(0,4)],                    # after L4
    4: [],                         # after L5
}

# Generate all 2-qubit Paulis including II
pauli2 = [ (a,b) for a in paulis for b in paulis ]

# Embedding function: place a 2-qubit pauli on 5-qubit string

def embed2(p2, qpos):
    P = ['I']*5
    (i,j) = qpos
    P[i] = p2[0]
    P[j] = p2[1]
    return tuple(P)

# Forward-conjugation mapping
maps = []  # list of dicts for each location: (p2)-> 5-qubit pauli after conjugating through later cnots
for li, qpos in enumerate(locations):
    d = {}
    for p2 in pauli2:
        P = embed2(p2, qpos)
        # Conjugate through all subsequent CNots in order
        for (c,t) in subseq_cnots[li]:
            P = cnot_conj(P, c, t)
        d[p2] = P
    maps.append(d)

# Define measured operators on final state: ancilla Z4, data XXXX and ZZZZ
Z4 = tuple(['I','I','I','I','Z'])
XXXX = tuple(['X','X','X','X','I'])
ZZZZ = tuple(['Z','Z','Z','Z','I'])

# Target state stabilizer generators: on data: XXXX, ZZZZ, Z_A=Z0Z1, Z_B=Z0Z2 ; ancilla Z4
ZA = tuple(['Z','Z','I','I','I'])
ZB = tuple(['Z','I','Z','I','I'])

def gen_group(generators):
    # generators: list of 5-qubit pauli strings; return set of all products ignoring phase
    gs = generators
    group = set([I5])
    for g in gs:
        new = set()
        for h in group:
            new.add(str_mul(h, g))
        group |= new
    return group

# Stabilizer group (ignoring phase) of target 5-qubit state |0>_4 \otimes |00>_L
G_target = gen_group([Z4, XXXX, ZZZZ, ZA, ZB])
len_G = len(G_target)
len_G
Tool #7
''
Assistant #8
len(G_target)
Tool #9
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
NameError: name 'G_target' is not defined
Assistant #10
# Rerun the code cell to redefine everything up to G_target
import itertools
from functools import lru_cache

paulis = ['I','X','Y','Z']
mult_table = {
    ('I','I'):'I', ('I','X'):'X', ('I','Y'):'Y', ('I','Z'):'Z',
    ('X','I'):'X', ('X','X'):'I', ('X','Y'):'Z', ('X','Z'):'Y',
    ('Y','I'):'Y', ('Y','X'):'Z', ('Y','Y'):'I', ('Y','Z'):'X',
    ('Z','I'):'Z', ('Z','X'):'Y', ('Z','Y'):'X', ('Z','Z'):'I',
}

def pmul(a,b):
    return mult_table[(a,b)]

def str_mul(P, Q):
    return tuple(pmul(p,q) for p,q in zip(P,Q))

I5 = tuple('I'*5)

def cnot_conj(P, control, target):
    P = list(P)
    # Save original for clarity is not necessary
    # Control part
    if P[control] == 'X':
        # multiply X into target
        P[target] = pmul(P[target], 'X')
    elif P[control] == 'Y':
        P[target] = pmul(P[target], 'X')
    # Z on control unchanged
    # Target part
    if P[target] == 'Z':
        P[control] = pmul(P[control], 'Z')
    elif P[target] == 'Y':
        P[control] = pmul(P[control], 'Z')
    return tuple(P)

locations = [ (1,2), (1,0), (2,3), (3,4), (0,4) ]
subseq_cnots = {
    0: [(1,0),(2,3),(3,4),(0,4)],
    1: [(2,3),(3,4),(0,4)],
    2: [(3,4),(0,4)],
    3: [(0,4)],
    4: [],
}

pauli2 = [ (a,b) for a in paulis for b in paulis ]

def embed2(p2, qpos):
    P = ['I']*5
    i,j = qpos
    P[i] = p2[0]
    P[j] = p2[1]
    return tuple(P)

maps = []
for li, qpos in enumerate(locations):
    d = {}
    for p2 in pauli2:
        P = embed2(p2, qpos)
        for (c,t) in subseq_cnots[li]:
            P = cnot_conj(P, c, t)
        d[p2] = P
    maps.append(d)

Z4 = tuple(['I','I','I','I','Z'])
XXXX = tuple(['X','X','X','X','I'])
ZZZZ = tuple(['Z','Z','Z','Z','I'])
ZA = tuple(['Z','Z','I','I','I'])
ZB = tuple(['Z','I','Z','I','I'])

def gen_group(gens):
    group = set([I5])
    for g in gens:
        group = group | set(str_mul(h,g) for h in group)
    return group

G_target = gen_group([Z4, XXXX, ZZZZ, ZA, ZB])
len(G_target)
Tool #11
''
Assistant #12
print(len(G_target))
Tool #13
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
NameError: name 'G_target' is not defined
Assistant #14
# Something odd: variables didn't persist across exec? Let's do everything in one cell and print.
import itertools

paulis = ['I','X','Y','Z']
mult_table = {
    ('I','I'):'I', ('I','X'):'X', ('I','Y'):'Y', ('I','Z'):'Z',
    ('X','I'):'X', ('X','X'):'I', ('X','Y'):'Z', ('X','Z'):'Y',
    ('Y','I'):'Y', ('Y','X'):'Z', ('Y','Y'):'I', ('Y','Z'):'X',
    ('Z','I'):'Z', ('Z','X'):'Y', ('Z','Y'):'X', ('Z','Z'):'I',
}

def pmul(a,b):
    return mult_table[(a,b)]

def str_mul(P, Q):
    return tuple(pmul(p,q) for p,q in zip(P,Q))

I5 = tuple('I'*5)

def cnot_conj(P, control, target):
    P = list(P)
    if P[control] == 'X':
        P[target] = pmul(P[target], 'X')
    elif P[control] == 'Y':
        P[target] = pmul(P[target], 'X')
    if P[target] == 'Z':
        P[control] = pmul(P[control], 'Z')
    elif P[target] == 'Y':
        P[control] = pmul(P[control], 'Z')
    return tuple(P)

locations = [ (1,2), (1,0), (2,3), (3,4), (0,4) ]
subseq_cnots = {
    0: [(1,0),(2,3),(3,4),(0,4)],
    1: [(2,3),(3,4),(0,4)],
    2: [(3,4),(0,4)],
    3: [(0,4)],
    4: [],
}

pauli2 = [ (a,b) for a in paulis for b in paulis ]

def embed2(p2, qpos):
    P = ['I']*5
    i,j = qpos
    P[i] = p2[0]
    P[j] = p2[1]
    return tuple(P)

maps = []
for li, qpos in enumerate(locations):
    d = {}
    for p2 in pauli2:
        P = embed2(p2, qpos)
        for (c,t) in subseq_cnots[li]:
            P = cnot_conj(P, c, t)
        d[p2] = P
    maps.append(d)

Z4 = tuple(['I','I','I','I','Z'])
XXXX = tuple(['X','X','X','X','I'])
ZZZZ = tuple(['Z','Z','Z','Z','I'])
ZA = tuple(['Z','Z','I','I','I'])
ZB = tuple(['Z','I','Z','I','I'])

def gen_group(gens):
    group = set([I5])
    for g in gens:
        group = group | set(str_mul(h,g) for h in group)
    return group

G_target = gen_group([Z4, XXXX, ZZZZ, ZA, ZB])
print('Size of target stabilizer group (ignore phase):', len(G_target))
# Accept set: centralizer of {Z4, XXXX, ZZZZ}

meas = [Z4, XXXX, ZZZZ]

# A Pauli P commutes with Q iff the number of positions where they anticommute is even (here compute explicitly)
anti_pairs = {('X','Z'),('Z','X'),('X','Y'),('Y','X'),('Y','Z'),('Z','Y')}


def commute(P,Q):
    cnt = 0
    for p,q in zip(P,Q):
        if (p,q) in anti_pairs:
            cnt += 1
    return (cnt % 2) == 0

# Build the full Pauli group (ignore phase) to classify Accept set size
# 5-qubit Paulis ignoring phase = 4^5 = 1024 elements
allP = list(itertools.product(paulis, repeat=5))
Accept = set([P for P in allP if all(commute(P,M) for M in meas)])
print('Accept set size:', len(Accept))

# Good set equals G_target
print('Good set size:', len(G_target))
Tool #15
Size of target stabilizer group (ignore phase): 32
Accept set size: 128
Good set size: 32
Assistant #16
Tool Call (code to execute)
import itertools

# Precompute maps (already computed above in the same cell) but re-creating here if needed

paulis = ['I','X','Y','Z']
mult_table = {
    ('I','I'):'I', ('I','X'):'X', ('I','Y'):'Y', ('I','Z'):'Z',
    ('X','I'):'X', ('X','X'):'I', ('X','Y'):'Z', ('X','Z'):'Y',
    ('Y','I'):'Y', ('Y','X'):'Z', ('Y','Y'):'I', ('Y','Z'):'X',
    ('Z','I'):'Z', ('Z','X'):'Y', ('Z','Y'):'X', ('Z','Z'):'I',
}

def pmul(a,b):
    return mult_table[(a,b)]

def str_mul(P, Q):
    return tuple(pmul(p,q) for p,q in zip(P,Q))

I5 = tuple('I'*5)

# cnot conjugation

def cnot_conj(P, control, target):
    P = list(P)
    if P[control] == 'X':
        P[target] = pmul(P[target], 'X')
    elif P[control] == 'Y':
        P[target] = pmul(P[target], 'X')
    if P[target] == 'Z':
        P[control] = pmul(P[control], 'Z')
    elif P[target] == 'Y':
        P[control] = pmul(P[control], 'Z')
    return tuple(P)

locations = [ (1,2), (1,0), (2,3), (3,4), (0,4) ]
subseq_cnots = {
    0: [(1,0),(2,3),(3,4),(0,4)],
    1: [(2,3),(3,4),(0,4)],
    2: [(3,4),(0,4)],
    3: [(0,4)],
    4: [],
}

pauli2 = [ (a,b) for a in paulis for b in paulis ]


def embed2(p2, qpos):
    P = ['I']*5
    i,j = qpos
    P[i] = p2[0]
    P[j] = p2[1]
    return tuple(P)

maps = []
for li, qpos in enumerate(locations):
    d = {}
    for p2 in pauli2:
        P = embed2(p2, qpos)
        for (c,t) in subseq_cnots[li]:
            P = cnot_conj(P, c, t)
        d[p2] = P
    maps.append(d)

# Define measured ops and good set
Z4 = tuple(['I','I','I','I','Z'])
XXXX = tuple(['X','X','X','X','I'])
ZZZZ = tuple(['Z','Z','Z','Z','I'])
ZA = tuple(['Z','Z','I','I','I'])
ZB = tuple(['Z','I','Z','I','I'])

anti_pairs = {('X','Z'),('Z','X'),('X','Y'),('Y','X'),('Y','Z'),('Z','Y')}

def commute(P,Q):
    cnt = 0
    for p,q in zip(P,Q):
        if (p,q) in anti_pairs:
            cnt += 1
    return (cnt % 2) == 0

# generate target stabilizer group (ignoring phases)

def gen_group(gens):
    group = set([I5])
    for g in gens:
        group = group | set(str_mul(h,g) for h in group)
    return group

G_target = gen_group([Z4, XXXX, ZZZZ, ZA, ZB])
meas = [Z4, XXXX, ZZZZ]

# Accept set is centralizer

def accepted(P):
    return all(commute(P,M) for M in meas)

# Good set membership

def good(P):
    return P in G_target

# Enumerate patterns
counts_good = [0]*6
counts_acc  = [0]*6

total_by_k = [0]*6

# Precompute 2-qubit pauli list with identity detection and map for each location
p2_list = pauli2

from itertools import product

# Iterate in nested loops for performance
cnt = 0
for p1 in p2_list:
    for p2 in p2_list:
        for p3 in p2_list:
            for p4 in p2_list:
                for p5 in p2_list:
                    plist = [p1,p2,p3,p4,p5]
                    k = sum(1 for p in plist if not (p[0]=='I' and p[1]=='I'))
                    total_by_k[k] += 1
                    # Compute final Pauli product
                    P = I5
                    for li, p in enumerate(plist):
                        P = str_mul(P, maps[li][p])
                    if good(P):
                        counts_good[k] += 1
                    if accepted(P):
                        counts_acc[k] += 1
                    cnt += 1

print('Total patterns =', cnt)
print('Total by k:', total_by_k)
print('counts_acc:', counts_acc)
print('counts_good:', counts_good)
Tool #17
Total patterns = 1048576
Total by k: [1, 75, 2250, 33750, 253125, 759375]
counts_acc: [1, 7, 282, 4222, 31637, 94923]
counts_good: [1, 7, 138, 1198, 7397, 24027]
Assistant #18
Tool Call (code to execute)
import sympy as sp

p = sp.symbols('p')
counts_acc = [1, 7, 282, 4222, 31637, 94923]
counts_good = [1, 7, 138, 1198, 7397, 24027]

P_acc = 0
P_good = 0
for k in range(6):
    P_acc += counts_acc[k] * (p/15)**k * (1-p)**(5-k)
    P_good += counts_good[k] * (p/15)**k * (1-p)**(5-k)

F = sp.simplify(sp.together(sp.simplify(P_good / P_acc)))
P_acc_simplified = sp.simplify(sp.together(P_acc))
P_good_simplified = sp.simplify(sp.together(P_good))

P_acc_poly = sp.expand(P_acc_simplified)
P_good_poly = sp.expand(P_good_simplified)

print('P_acc(p) expanded =')
print(P_acc_poly)
print('\nP_good(p) expanded =')
print(P_good_poly)
print('\nF_log(p) simplified =')
print(F)

# series expansion small p
series = sp.series(F, p, 0, 4)
print('\nSeries F_log(p) ~', series)
Tool #19
P_acc(p) expanded =
-262144*p**5/253125 + 253952*p**4/50625 - 32768*p**3/3375 + 704*p**2/75 - 68*p/15 + 1

P_good(p) expanded =
-229376*p**5/253125 + 223232*p**4/50625 - 29312*p**3/3375 + 656*p**2/75 - 68*p/15 + 1

F_log(p) simplified =
(229376*p**5 - 1116160*p**4 + 2198400*p**3 - 2214000*p**2 + 1147500*p - 253125)/(262144*p**5 - 1269760*p**4 + 2457600*p**3 - 2376000*p**2 + 1147500*p - 253125)

Series F_log(p) ~ 1 - 16*p**2/25 - 704*p**3/375 + O(p**4)
Assistant #20
Tool Call (code to execute)
import numpy as np

p = 0.01
# Evaluate F(p) from polynomials
P_acc = (-262144*p**5/253125 + 253952*p**4/50625 - 32768*p**3/3375 + 704*p**2/75 - 68*p/15 + 1)
P_good = (-229376*p**5/253125 + 223232*p**4/50625 - 29312*p**3/3375 + 656*p**2/75 - 68*p/15 + 1)
F_poly = P_good/P_acc
print('F_poly at p=0.01:', F_poly)

# Evaluate F based on counts (exact way)
counts_acc = [1, 7, 282, 4222, 31637, 94923]
counts_good = [1, 7, 138, 1198, 7397, 24027]
P_acc2 = 0
P_good2 = 0
for k in range(6):
    P_acc2 += counts_acc[k] * (p/15)**k * (1-p)**(5-k)
    P_good2 += counts_good[k] * (p/15)**k * (1-p)**(5-k)
print('F_count at p=0.01:', P_good2/P_acc2)

print('Acceptance probability at p=0.01:', P_acc2)
Tool #21
F_poly at p=0.01: 0.9999340913140432
F_count at p=0.01: 0.9999340913140433
Acceptance probability at p=0.01: 0.9555956743560912
Assistant #22
Tool Call (code to execute)
import sympy as sp
p = sp.symbols('p')
F = (229376*p**5 - 1116160*p**4 + 2198400*p**3 - 2214000*p**2 + 1147500*p - 253125)/(262144*p**5 - 1269760*p**4 + 2457600*p**3 - 2376000*p**2 + 1147500*p - 253125)
sp.N(F.subs(p, 1))
Tool #23
''
Assistant #24
float((229376 - 1116160 + 2198400 - 2214000 + 1147500 - 253125)/(262144 - 1269760 + 2457600 - 2376000 + 1147500 - 253125))
Tool #25
''
Assistant #26
  1. Step-by-Step Derivation
  • Ideal target and acceptance conditions
  • Starting from |0000⟩ on data qubits 0–3 and ancilla |0⟩ on qubit 4, the circuit
\[ H_1 \to CNOT_{12}\to CNOT_{10}\to CNOT_{23}\to CNOT_{34}\to CNOT_{04} \]
prepares the 4-qubit cat state on data and leaves the ancilla in |0⟩:
\[ |\psi_{\text{ideal}}\rangle = |0\rangle_4 \otimes \frac{|0000\rangle_{0,1,2,3}+|1111\rangle_{0,1,2,3}}{\sqrt{2}}. \]
This is the logical state |00⟩AB in the [[4,2,2]] code, stabilized by $XXXX$ and $ZZZZ$, and with $Z_A=Z_0Z_1$, $Z_B=Z_0Z_2$ both +1.
  • Post-selection accepts a run iff:

    • The ancilla measurement is |0⟩, i.e. \(Z_4=+1\).
    • The code stabilizers return +1, i.e. \(XXXX=+1\) and \(ZZZZ=+1\).
  • Noise model and Clifford-Pauli propagation

  • After each of the five CNOTs, a two-qubit depolarizing channel acts on that gate’s two qubits:
\[ \mathcal{D}_p(\rho)=(1-p)\rho+\frac{p}{15}\sum_{P\in\mathcal{P}_2\setminus\{II\}} P\rho P. \]
  • Because the circuit is Clifford and the noise is Pauli, each error instance is equivalent to applying a single 5-qubit Pauli \(E_{\text{final}}\) at the end, obtained by propagating each inserted Pauli forward through the remaining CNOTs via the usual conjugation rules for \(CNOT_{c\to t}\):
    • \(X_c\mapsto X_cX_t\), \(Z_t\mapsto Z_cZ_t\),
    • \(Z_c\mapsto Z_c\), \(X_t\mapsto X_t\),
    • and \(Y\) follows from \(Y=iXZ\) (global phases are irrelevant).
  • If \(E_{\text{final}}\) anticommutes with any of \(Z_4\), \(XXXX\), \(ZZZZ\), the corresponding measurement outcome flips to −1 deterministically and the run is rejected. Thus:
    • Accept if and only if \(E_{\text{final}}\) lies in the centralizer of \(\{Z_4,XXXX,ZZZZ\}\).
    • The prepared logical state is correct if and only if \(E_{\text{final}}\) lies in the stabilizer group of the target 5-qubit state
\[ \mathcal{S}_{\text{target}}=\langle Z_4,\;XXXX,\;ZZZZ,\;Z_0Z_1,\;Z_0Z_2\rangle. \]
  • Combinatorics of error patterns
  • There are five two-qubit gates, so an error pattern is a 5-tuple of two-qubit Paulis chosen from \(\{II,\ldots,ZZ\}\) (16 choices per location). The probability of a pattern with exactly \(k\) non-identity errors is \((1-p)^{5-k}(p/15)^k\).
  • For each pattern, compute \(E_{\text{final}}\) by propagating the 2-qubit Paulis forward and multiplying (ignoring global phase).
  • Let:
    • \(A_k\) be the number of \(k\)-fault patterns that are accepted (i.e. \(E_{\text{final}}\) commutes with \(Z_4,XXXX,ZZZZ\)).
    • \(G_k\) be the number of \(k\)-fault patterns that are both accepted and logically correct (i.e. \(E_{\text{final}}\in\mathcal{S}_{\text{target}}\)).
  • Exhaustive stabilizer/Pauli enumeration gives:

    • Total patterns with exactly \(k\) faults: \(\binom{5}{k}15^k\).
    • Counts:
    • \(A_k\): [1, 7, 282, 4222, 31637, 94923] for \(k=0,1,2,3,4,5\),
    • \(G_k\): [1, 7, 138, 1198, 7397, 24027] for \(k=0,1,2,3,4,5\).
    • Notably, \(A_1=G_1=7\), i.e., all accepted single-fault patterns are logically correct (first-order logical errors are fully detected), as required for fault-tolerant state preparation.
  • Constructing the conditional logical fidelity

  • Acceptance probability:
\[ P_{\text{acc}}(p)=\sum_{k=0}^{5} A_k\left(\frac{p}{15}\right)^k(1-p)^{5-k}. \]
  • “Good-and-accepted” probability:
\[ P_{\text{good}}(p)=\sum_{k=0}^{5} G_k\left(\frac{p}{15}\right)^k(1-p)^{5-k}. \]
  • Logical fidelity conditioned on acceptance:
\[ F_{\text{log}}(p)=\frac{P_{\text{good}}(p)}{P_{\text{acc}}(p)}. \]
  • Simplifying,
\[ P_{\text{acc}}(p)&=1-\frac{68}{15}p+\frac{704}{75}p^2-\frac{32768}{3375}p^3+\frac{253952}{50625}p^4-\frac{262144}{253125}p^5,\\ P_{\text{good}}(p)&=1-\frac{68}{15}p+\frac{656}{75}p^2-\frac{29312}{3375}p^3+\frac{223232}{50625}p^4-\frac{229376}{253125}p^5, \]
hence
\[ F_{\text{log}}(p)=\frac{1-\frac{68}{15}p+\frac{656}{75}p^2-\frac{29312}{3375}p^3+\frac{223232}{50625}p^4-\frac{229376}{253125}p^5}{1-\frac{68}{15}p+\frac{704}{75}p^2-\frac{32768}{3375}p^3+\frac{253952}{50625}p^4-\frac{262144}{253125}p^5}. \]
An equivalent integer-coefficient form is
\[ F_{\text{log}}(p)=\frac{229376p^5-1116160p^4+2198400p^3-2214000p^2+1147500p-253125}{262144p^5-1269760p^4+2457600p^3-2376000p^2+1147500p-253125}. \]
  • Small-\(p\) expansion:
\[ F_{\text{log}}(p)=1-\frac{16}{25}p^2-\frac{704}{375}p^3+O(p^4), \]
confirming that all first-order faults are detected or benign, and the leading logical infidelity is $O(p^2)$.
  1. Mathematical Typesetting - All equations are provided in LaTeX above.

  2. Conventions and Units - Two-qubit depolarizing channel with error probability \(p\) is applied after each of the five CNOTs. - Post-selection requires ancilla outcome \(Z_4=+1\) and both stabilizers \(XXXX=+1\), \(ZZZZ=+1\).

  3. Final Answer:

\[ F_{\text{log}}(p)=\frac{1-\frac{68}{15}p+\frac{656}{75}p^2-\frac{29312}{3375}p^3+\frac{223232}{50625}p^4-\frac{229376}{253125}p^5}{1-\frac{68}{15}p+\frac{704}{75}p^2-\frac{32768}{3375}p^3+\frac{253952}{50625}p^4-\frac{262144}{253125}p^5}. \]
User #27

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 #28
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(68, 15)*p
        + sp.Rational(656, 75)*p**2
        - sp.Rational(29312, 3375)*p**3
        + sp.Rational(223232, 50625)*p**4
        - sp.Rational(229376, 253125)*p**5
    ) / (
        1
        - sp.Rational(68, 15)*p
        + sp.Rational(704, 75)*p**2
        - sp.Rational(32768, 3375)*p**3
        + sp.Rational(253952, 50625)*p**4
        - sp.Rational(262144, 253125)*p**5
    )
    # ---------------------------------------------------------------

    return F_logical