Source code for loom.eka.syndrome_circuit

"""
Copyright (c) Entropica Labs Pte Ltd 2025.

Use, distribution and reproduction of this program in its source or compiled
form is prohibited without the express written consent of Entropica Labs Pte
Ltd.

"""

from __future__ import annotations
from uuid import uuid4
import logging

from pydantic import field_validator, Field, ValidationInfo
from pydantic.dataclasses import dataclass

from .circuit import Circuit, Channel
from .utilities.validation_tools import (
    pauli_error,
    dataclass_params,
    retrieve_field,
    no_name_error,
)

logging.basicConfig(format="%(name)s - %(levelname)s - %(message)s")
log = logging.getLogger(__name__)


[docs] def default_circuit(pauli_str: str) -> Circuit: """ Construct the default circuit corresponding to the input Pauli string. Parameters ---------- pauli_str: str The input Pauli string of the stabilizer Returns ------- Circuit The circuit containing instructions measuring the stabilizer """ weight = len(pauli_str) ancilla_channel = Channel(type="quantum", label="a0") data_channels = [Channel(type="quantum", label=f"d{i}") for i in range(weight)] cbit_channel = Channel(type="classical", label="c0") reset = [Circuit("Reset_0", channels=[ancilla_channel])] hadamard1 = [Circuit("H", channels=[ancilla_channel])] hadamard2 = [Circuit("H", channels=[ancilla_channel])] entangle_ancilla = [ [Circuit(f"C{pauli}", channels=[ancilla_channel, data_channels[i]])] for i, pauli in enumerate(pauli_str) ] measurement = [Circuit("Measurement", channels=[ancilla_channel, cbit_channel])] ops_list = [reset, hadamard1] + entangle_ancilla + [hadamard2, measurement] circuit_name = f"stab_{pauli_str}" return Circuit( circuit_name, channels=data_channels + [ancilla_channel, cbit_channel], circuit=ops_list, )
[docs] @dataclass(**dataclass_params) class SyndromeCircuit: """ A SyndromeCircuit object specifies one way to measure a pauli string. There can be multiple SyndromeCircuit objects for the same pauli string, specifying different circuits for how to measure it. The qubits in the `circuit` field are labeled 0, ..., n. Once the actual syndrome extraction circuit for a stabilizer is generated, qubit i of the SyndromeCircuit object is replaced by stabilizer.data_qubits[i]. Therefore the qubit order inside stabilizer.data_qubits must match the order in which they are used in SyndromeCircuit. Parameter --------- pauli : str The pauli string which this circuit is supposed to measure. Must be a string name: str, optional A name for the SyndromeCircuit object consisting of the characters {X, Y, Z}. circuit: Circuit | None The circuit instructions to measure the syndrome. If `None` is provided, a default circuit for the given pauli string is automatically constructed. uuid: str A uuid associated with the object """ pauli: str = Field(min_length=1) name: str = Field(min_length=1, default_factory=lambda: "SyndromeCircuit") circuit: Circuit | None = Field(default_factory=lambda: None, validate_default=True) uuid: str = Field(default_factory=lambda: str(uuid4()), validate_default=True) # Validation functions _validate_pauli = field_validator("pauli")(pauli_error) _validate_name = field_validator("name")(no_name_error)
[docs] @field_validator("circuit", mode="after") @classmethod def default_syndrome_circuit(cls, value, info: ValidationInfo): """ In case the field circuit is not provided, the default syndrome extraction circuit is automatically assigned """ pauli_str = retrieve_field("pauli", info) value = default_circuit(pauli_str) if value is None else value return value
# Magic methods def __eq__(self, other: SyndromeCircuit) -> bool: """ Ignore the uuid in the equality check. """ if self.pauli != other.pauli: log.info("The two circuits measure different Pauli strings.") log.debug("%s != %s\n", self.pauli, other.pauli) return False if self.name != other.name: log.info("The two circuits have different names.") log.debug("%s != %s\n", self.name, other.name) return False if self.circuit != other.circuit: log.info("The two circuits have different circuit instructions.") return False # log.debug( # f"\n{self.circuit}\n !=\n{other.circuit}" # ) return True def __hash__(self): """ Ignore the uuid in hashing. """ return hash((self.pauli, self.name, self.circuit))