In regular error correction, the procedure involves a classical computer applying the appropriate correction to the quantum computer based on the syndromes that were measured.
In measurement-free error correction, the task of applying the corrections is shifted from the classical computer to the quantum computer. Syndrome qubits can be reused if the quantum computer has a reset operation. Even if no reset operation is available, fresh ancillas can be reloaded and used as the computation proceeds.
Let's take the measurement of a single stabilizer as an example. We'll perform a parity measurement of a Z operator.
import collections
import cirq
qubits = cirq.LineQubit.range(5)
c = cirq.Circuit(
cirq.H(qubits[0]),
cirq.CZ(qubits[0], qubits[1]),
cirq.H(qubits[0]),
cirq.measure(qubits[0]),
)
print(c)
prints
0: ───H───@───H───M───
│
1: ───────@───────────
Now, let's perform error correction the standard way. Let's inject an error to the data qubit 1, which should always be $0$ if the error correction is working correctly
c = cirq.Circuit(
cirq.H(qubits[0]),
cirq.bit_flip(p=0.5).on(qubits[1]),
cirq.CZ(qubits[0], qubits[1]),
cirq.H(qubits[0]),
cirq.measure(qubits[0], key="a"),
cirq.X(qubits[1]).with_classical_controls("a"),
cirq.reset(qubits[0]),
cirq.H(qubits[0]),
cirq.bit_flip(p=0.5).on(qubits[1]),
cirq.CZ(qubits[0], qubits[1]),
cirq.H(qubits[0]),
cirq.measure(qubits[0], key="b"),
cirq.X(qubits[1]).with_classical_controls("b"),
cirq.measure(qubits[1], key="data"),
)
print(c)
# prints
# 0: ───H─────────@───H───M───R───H─────────@───H───M───────────────────
# │ ║ │ ║
# 1: ───BF(0.5)───@───────╫───X───BF(0.5)───@───────╫───X───M('data')───
# ║ ║ ║ ║
# a: ═════════════════════@═══^═════════════════════╬═══╬═══════════════
# ║ ║
# b: ═══════════════════════════════════════════════@═══^═══════════════
sim = cirq.Simulator()
result = sim.run(c, repetitions=10)
assert result.histogram(key="data") == collections.Counter({0: 10})
Notice that the classical control can be removed when an extra qubit is added
c = cirq.Circuit(
cirq.H(qubits[0]),
cirq.bit_flip(p=0.5).on(qubits[1]),
cirq.CZ(qubits[0], qubits[1]),
cirq.H(qubits[0]),
cirq.CX(qubits[0], qubits[2]),
cirq.CX(qubits[2], qubits[1]),
cirq.reset(qubits[0]),
cirq.reset(qubits[2]),
cirq.H(qubits[0]),
cirq.bit_flip(p=0.5).on(qubits[1]),
cirq.CZ(qubits[0], qubits[1]),
cirq.H(qubits[0]),
cirq.CX(qubits[0], qubits[2]),
cirq.CX(qubits[2], qubits[1]),
cirq.measure(qubits[1], key="data"),
)
print(c)
# prints
# 0: ───H─────────@───H───@───R───H─────────@───H───@───────────────────
# │ │ │ │
# 1: ───BF(0.5)───@───────┼───X───BF(0.5)───@───────┼───X───M('data')───
# │ │ │ │
# 2: ─────────────────────X───@───R─────────────────X───@───────────────
result = sim.run(c, repetitions=10)
assert result.histogram(key="data") == collections.Counter({0: 10})
That's how measurement-free error correction is performed with access to a reset operation. How do we manage without a reset operation? We replace the ancillary with a new one after every syndrome measurement
c = cirq.Circuit(
cirq.H(qubits[0]),
cirq.bit_flip(p=0.5).on(qubits[1]),
cirq.CZ(qubits[0], qubits[1]),
cirq.H(qubits[0]),
cirq.CX(qubits[0], qubits[2]),
cirq.CX(qubits[2], qubits[1]),
cirq.H(qubits[3]),
cirq.bit_flip(p=0.5).on(qubits[1]),
cirq.CZ(qubits[3], qubits[1]),
cirq.H(qubits[3]),
cirq.CX(qubits[3], qubits[1]),
cirq.measure(qubits[1], key="data"),
)
print(c)
# prints
# 0: ───H─────────@───H───@─────────────────────────────────────────
# │ │
# 1: ───BF(0.5)───@───────┼───X───BF(0.5)───@───────X───M('data')───
# │ │ │ │
# 2: ─────────────────────X───@─────────────┼───────┼───────────────
# │ │
# 3: ───H───────────────────────────────────@───H───@───────────────
result = sim.run(c, repetitions=10)
assert result.histogram(key="data") == collections.Counter({0: 10})
Measurement-free error correction might outperform regular error correction in scenarios where measurements are slow. Neutral atoms are a good example. In neutral atoms, it takes too much time, relative to the times of single-qubit and two-qubit gates, to make a measurement. If mid-circuit measurements are made after each syndrome extraction, this delay accumulates. Neutral atoms have also been shown to be able to trap many qubits, making it feasible to perform error correction with qubits instead of bits.