
seun
e831e513-b95a-4211-b11a-d686a4b91dfb/agentic-stim
Clone
git clone https://zoo.qernel.sh/e831e513-b95a-4211-b11a-d686a4b91dfb/agentic-stim.git
cd agentic-stim
Unique clones: 0
Files
Comments
- No comments yet.
src/main.py
Download rawimport math
import random
from typing import Dict, Iterable, List, Optional, Sequence, Tuple
import stim
# Type aliases used for clarity.
Coordinate = Tuple[float, float, float]
Stabilizer = Tuple[int, int, int, int]
# The standard X- and Z-type stabilizers for the Steane [[7, 1, 3]] CSS code.
STEANE_STABILIZERS: Tuple[Stabilizer, Stabilizer, Stabilizer] = (
(0, 1, 2, 3),
(0, 1, 4, 5),
(0, 2, 4, 6),
)
def _rec_target(circuit: stim.Circuit, measurement_index: int) -> stim.GateTarget:
"""Return a ``stim`` REC target for a historic measurement index.
``stim`` expects detector targets referencing measurements to be expressed as
negative lookbacks relative to the total number of measurements issued so far.
This helper converts the stored absolute ``measurement_index`` into the
required relative form.
"""
lookback = measurement_index - circuit.num_measurements
if lookback >= 0:
raise ValueError(
"Measurement indices must refer to outcomes emitted before the "
"current detector is appended."
)
return stim.target_rec(lookback)
def _compute_fano_plane_coords(radius: float = 2.0) -> Dict[int, Coordinate]:
"""Return a set of aesthetically spaced coordinates for the seven data qubits.
The coordinates place the data qubits on the vertices of a regular heptagon.
Ancilla coordinates are derived later by averaging the coordinates of the
data qubits that participate in a given stabiliser.
"""
coords: Dict[int, Coordinate] = {}
for index in range(7):
angle = 2.0 * math.pi * index / 7.0
coords[index] = (
radius * math.cos(angle),
radius * math.sin(angle),
0.0,
)
return coords
def _average_coords(points: Iterable[Coordinate]) -> Coordinate:
"""Compute the centroid of the supplied points."""
xs, ys, zs = zip(*points)
inv = 1.0 / len(xs)
return (
sum(xs) * inv,
sum(ys) * inv,
sum(zs) * inv,
)
def generate_713_steane_code_circuit(
num_qubits: int,
depth: int,
seed: Optional[int] = None,
) -> stim.Circuit:
r"""Generate a stabiliser-measurement circuit for the Steane \[[7, 1, 3]] code.
The circuit follows the CSS construction described by Steane in
*“Multiple particle interference and quantum error correction”*
(Proc. R. Soc. A 452, 2551–2577, 1996). The three X-type and three Z-type
stabilisers are measured in every round using dedicated ancilla qubits.
Detectors compare consecutive rounds to flag non-trivial syndrome changes
and the final data-qubit measurements define the logical $Z$ observable.
Args:
num_qubits: Expected number of data qubits. Only ``7`` is supported and
corresponds to the seven physical qubits that store one logical qubit.
depth: Number of repeated syndrome-measurement rounds. Must be positive.
seed: Optional seed retained for API compatibility; the circuit is
deterministic but passing a value allows callers to reproduce any
future stochastic extensions.
Returns:
A ``stim.Circuit`` implementing ``depth`` rounds of Steane code syndrome
extraction followed by data measurement and logical observable tracking.
Raises:
ValueError: If ``num_qubits`` is not ``7`` or if ``depth`` is non-positive.
Notes:
• Qubit indexing:
0–6 : data qubits (logical subspace)
7–9 : X-syndrome ancillae (one per X stabiliser)
10–12: Z-syndrome ancillae (one per Z stabiliser)
• Qubit coordinates are chosen to mirror the Fano plane representation of
the Steane code. Ancilla coordinates are placed at the centroid of the
data qubits that support the associated stabiliser, with the third
coordinate distinguishing the X- and Z-measurement layers.
• Detectors are emitted for rounds ``> 0`` where a comparison with the
previous round is available. Final detectors tie the last Z-syndrome
measurements to the data measurements, yielding boundary checks.
• Logical $Z_L = Z_0 Z_1 Z_2 Z_3 Z_4 Z_5 Z_6$ is published via
``OBSERVABLE_INCLUDE`` with index ``0``.
"""
if num_qubits != 7:
raise ValueError(
"The Steane [[7,1,3]] code requires exactly 7 data qubits; "
f"received num_qubits={num_qubits!r}."
)
if depth <= 0:
raise ValueError("Parameter 'depth' must be a positive integer.")
# Seed retained for API compatibility – no randomness is currently used.
if seed is not None:
random.seed(seed)
data_qubits: Tuple[int, ...] = tuple(range(7))
x_ancilla: Tuple[int, ...] = tuple(range(7, 10))
z_ancilla: Tuple[int, ...] = tuple(range(10, 13))
circuit = stim.Circuit()
# Build coordinate map for data and ancilla qubits.
coords = _compute_fano_plane_coords()
for idx, stabiliser in enumerate(STEANE_STABILIZERS):
data_coords = [coords[q] for q in stabiliser]
centroid = _average_coords(data_coords)
coords[x_ancilla[idx]] = (centroid[0], centroid[1], 1.0)
coords[z_ancilla[idx]] = (centroid[0], centroid[1], -1.0)
for qubit, coord in sorted(coords.items()):
circuit.append("QUBIT_COORDS", [qubit], coord)
# Initialise data qubits to |0>.
for q in data_qubits:
circuit.append("R", [q])
circuit.append("TICK")
# Helper collections tracking measurement indices for detector construction.
x_measurements: List[List[int]] = []
z_measurements: List[List[int]] = []
# Perform repeated stabiliser measurements.
for round_index in range(depth):
# Reset all ancilla qubits to |0⟩ at the start of each round.
for anc in (*x_ancilla, *z_ancilla):
circuit.append("R", [anc])
circuit.append("TICK")
# Prepare X-type ancillae in |+⟩.
for anc in x_ancilla:
circuit.append("H", [anc])
circuit.append("TICK")
# Entangle X-type ancillae with data qubits using control-on-ancilla CNOTs.
for anc_index, stabiliser in enumerate(STEANE_STABILIZERS):
anc = x_ancilla[anc_index]
for data in stabiliser:
circuit.append("CX", [anc, data])
circuit.append("TICK")
# Rotate X-type ancillae back to the Z basis for measurement.
for anc in x_ancilla:
circuit.append("H", [anc])
circuit.append("TICK")
# Measure X-type ancillae and record their indices.
current_x_indices: List[int] = []
for anc in x_ancilla:
meas_index = circuit.num_measurements
circuit.append("M", [anc])
current_x_indices.append(meas_index)
x_measurements.append(current_x_indices)
circuit.append("TICK")
# Entangle Z-type ancillae with data qubits using data-controlled CNOTs.
for anc_index, stabiliser in enumerate(STEANE_STABILIZERS):
anc = z_ancilla[anc_index]
for data in stabiliser:
circuit.append("CX", [data, anc])
circuit.append("TICK")
# Measure Z-type ancillae and capture indices.
current_z_indices: List[int] = []
for anc in z_ancilla:
meas_index = circuit.num_measurements
circuit.append("M", [anc])
current_z_indices.append(meas_index)
z_measurements.append(current_z_indices)
circuit.append("TICK")
# Emit temporal detectors comparing consecutive rounds.
if round_index > 0:
previous_x = x_measurements[round_index - 1]
previous_z = z_measurements[round_index - 1]
for stabiliser_index in range(len(STEANE_STABILIZERS)):
circuit.append(
"DETECTOR",
[
_rec_target(circuit, previous_x[stabiliser_index]),
_rec_target(circuit, current_x_indices[stabiliser_index]),
],
)
for stabiliser_index in range(len(STEANE_STABILIZERS)):
circuit.append(
"DETECTOR",
[
_rec_target(circuit, previous_z[stabiliser_index]),
_rec_target(circuit, current_z_indices[stabiliser_index]),
],
)
circuit.append("TICK")
# Final data-qubit measurements to close the circuit.
data_measurement_indices: Dict[int, int] = {}
for q in data_qubits:
meas_index = circuit.num_measurements
circuit.append("M", [q])
data_measurement_indices[q] = meas_index
circuit.append("TICK")
# Boundary detectors tying the final Z-syndrome outcomes to data measurements.
last_z_round = z_measurements[-1]
for stabiliser_index, stabiliser in enumerate(STEANE_STABILIZERS):
targets = [_rec_target(circuit, last_z_round[stabiliser_index])]
targets.extend(_rec_target(circuit, data_measurement_indices[q]) for q in stabiliser)
circuit.append("DETECTOR", targets)
circuit.append("TICK")
# Publish the logical Z observable Z₀…Z₆.
logical_targets = [_rec_target(circuit, data_measurement_indices[q]) for q in data_qubits]
circuit.append("OBSERVABLE_INCLUDE", logical_targets)
return circuit