burn_quantum 0.4.0

Differentiable qubit and qudit simulation with Burn's native tensor and module APIs
Documentation
//! Detector-driven recovery of a completed noisy surgery trajectory.
use super::*;
use crate::photonic::qec::threshold::{DecoderBudget, GraphDecode, GraphStatus};
use crate::photonic::stabilizer::{Pauli, PauliProduct, Tableau};
use crate::{Error, Result};
/// Decoder proposal for records generated by the declared phenomenological
/// protocol with deferred split feedback. A returned correction is not a
/// guarantee of logical success: residual logical errors are measured in studies.
#[derive(Clone, Debug)]
pub struct SurgeryRecovery {
    /// Complete decoder status, selected fault coordinates and ambiguity/work data.
    pub decode: GraphDecode,
    /// Inferred logical parity after correcting detector/readout faults.
    pub parity: Option<bool>,
    /// Corrected ideal-branch record proposal, including ideal final checks.
    pub corrected_records: Option<Vec<bool>>,
    /// Relative physical correction: predicted data faults plus split gauge frame.
    pub correction: Option<PauliProduct>,
    patch_qubits: usize,
}
impl SurgeryRecovery {
    /// Apply the proposed physical frame to the completed, uncorrected trajectory.
    /// Ambiguous/inconsistent/work-limited decoding supplies no applicable frame.
    /// The two patches may be embedded in a larger entangled tableau.
    pub fn apply(&self, state: &mut Tableau, offsets: [usize; 2]) -> Result<()> {
        let Some(frame) = &self.correction else {
            return Err(Error::Unsupported(
                "surgery decoder has no applicable frame".into(),
            ));
        };
        if self.decode.status != GraphStatus::Corrected {
            return Err(Error::Unsupported(
                "surgery decoder status is not corrected".into(),
            ));
        }
        let n = self.patch_qubits;
        if offsets[0].abs_diff(offsets[1]) < n
            || offsets
                .iter()
                .any(|o| o.checked_add(n).is_none_or(|end| end > state.qubits()))
        {
            return Err(Error::Wires(
                "invalid surgery recovery patch offsets".into(),
            ));
        }
        if frame.terms().iter().any(|(q, _)| *q >= 2 * n) {
            return Err(Error::Wires(
                "surgery recovery frame outside patches".into(),
            ));
        }
        let actual = PauliProduct::new(
            frame
                .terms()
                .iter()
                .map(|&(q, p)| (offsets[q / n] + q % n, p))
                .collect(),
        )?;
        super::execution::apply_pauli(state, &actual)
    }
}
impl SurgeryDetectorModel {
    /// Decode the complete merge/split/ideal-closing transcript and recover a
    /// physical frame, using only observed records and declared erasure flags.
    /// Erasure flags are in fault-coordinate order, not raw-record order.
    pub fn recover(
        &self,
        records: &[bool],
        erased_faults: &[bool],
        budget: DecoderBudget,
    ) -> Result<SurgeryRecovery> {
        let syndrome = self.detector_values(records)?;
        let decode = self
            .graph()
            .decode_union_find(&syndrome, erased_faults, budget)?;
        let mut result = SurgeryRecovery {
            decode,
            parity: None,
            corrected_records: None,
            correction: None,
            patch_qubits: self.plan().code().qubits(),
        };
        if result.decode.status != GraphStatus::Corrected {
            return Ok(result);
        }
        let mut corrected = records.to_vec();
        let n = 2 * result.patch_qubits;
        let mut x = vec![false; n];
        let mut z = x.clone();
        let mut by_round = vec![vec![]; 2 * self.plan().code().distance()];
        for (index, &active) in result.decode.correction.iter().enumerate() {
            if !active {
                continue;
            }
            match self.faults()[index] {
                SurgeryFault::Data { round, site, pauli } => by_round[round].push((site, pauli)),
                SurgeryFault::Readout { record } => corrected[record] ^= true,
            }
        }
        // Sparse frame sweep: O(fault locations + record count * check weight),
        // not one complete record mask allocation per selected decoder edge.
        let mut previous = None;
        for (index, record) in self.records().iter().enumerate() {
            if previous != Some(record.round) {
                if let Some(events) = by_round.get(record.round) {
                    for &(site, pauli) in events {
                        match pauli {
                            Pauli::X => x[site] ^= true,
                            Pauli::Z => z[site] ^= true,
                            Pauli::Y => {
                                return Err(Error::Unsupported(
                                    "unexpected non-CSS surgery fault".into(),
                                ));
                            }
                        }
                    }
                }
                previous = Some(record.round);
            }
            for &(site, pauli) in record.observable.terms() {
                corrected[index] ^= match pauli {
                    Pauli::X => z[site],
                    Pauli::Z => x[site],
                    Pauli::Y => x[site] ^ z[site],
                };
            }
        }
        if self.detector_values(&corrected)?.iter().any(|&v| v) {
            return Err(Error::InvalidValue(
                "surgery decoder failed to close observed syndrome".into(),
            ));
        }
        let d = self.plan().code().distance();
        let start = d * self.plan().merged_checks().len();
        let end = start + self.plan().split_checks().len();
        for &(site, pauli) in self
            .plan()
            .split_correction(&corrected[start..end])?
            .terms()
        {
            match pauli {
                Pauli::X => x[site] ^= true,
                Pauli::Z => z[site] ^= true,
                Pauli::Y => {
                    x[site] ^= true;
                    z[site] ^= true;
                }
            }
        }
        result.parity = Some(corrected[..d].iter().fold(false, |v, &b| v ^ b));
        result.corrected_records = Some(corrected);
        result.correction = Some(PauliProduct::new(
            (0..n)
                .filter_map(|q| match (x[q], z[q]) {
                    (true, true) => Some((q, Pauli::Y)),
                    (true, false) => Some((q, Pauli::X)),
                    (false, true) => Some((q, Pauli::Z)),
                    _ => None,
                })
                .collect(),
        )?);
        Ok(result)
    }
}