qec-code 0.3.0

Rust primitives for constructing and analyzing quantum error-correcting codes
Documentation
use serde::{Deserialize, Serialize};

use crate::distance::{DistanceResult, LogicalClass};
use crate::distance_bound::DistanceBoundWitness;

#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)]
#[serde(rename_all = "kebab-case")]
pub enum ExactCssDistanceMethod {
    RstimIlpExact,
}

#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)]
#[serde(rename_all = "lowercase")]
pub enum ExactDistanceBoundType {
    Exact,
    Upper,
}

#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)]
#[serde(rename_all = "lowercase")]
pub enum ExactCssDistanceStatus {
    Completed,
    Timeout,
    Incomplete,
}

#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize, Default)]
#[cfg_attr(feature = "cli", derive(clap::ValueEnum))]
#[serde(rename_all = "lowercase")]
pub enum ExactCssDistanceBackend {
    #[default]
    Auto,
    Highs,
    Gurobi,
}

#[derive(Debug, Clone, Copy, PartialEq, Serialize, Deserialize, Default)]
pub struct ExactCssDistanceSolverOptions {
    #[serde(default)]
    pub backend: ExactCssDistanceBackend,
    pub time_limit_seconds: Option<f64>,
    pub mip_gap: Option<f64>,
    pub threads: Option<u32>,
    #[serde(default, skip_serializing_if = "is_false")]
    pub verbose_solver: bool,
}

#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)]
#[serde(rename_all = "snake_case")]
pub enum ExactCssDistanceSolverStatus {
    Optimal,
    TimeLimit,
    SolutionLimit,
    SubOptimal,
}

impl ExactCssDistanceSolverStatus {
    pub fn is_exact(self) -> bool {
        matches!(self, Self::Optimal)
    }
}

#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)]
pub struct ExactCssDistanceSolverReport {
    pub backend: ExactCssDistanceBackend,
    pub status: ExactCssDistanceSolverStatus,
}

#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
#[serde(tag = "input", rename_all = "snake_case")]
pub enum ExactCssDistanceInput {
    CodeId { code_id: String },
    Files { hx: String, hz: String },
    QuantumTannerSpec { quantum_tanner_spec: String },
}

#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
pub struct ExactCssDistanceOptions {
    #[serde(flatten)]
    pub input: ExactCssDistanceInput,
    #[serde(flatten)]
    pub solver: ExactCssDistanceSolverOptions,
}

#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
pub struct ExactCssDistanceProvenance {
    pub tool: String,
    pub tool_version: String,
    pub method_revision: u32,
}

impl ExactCssDistanceProvenance {
    pub fn current() -> Self {
        Self {
            tool: "qec-code".to_owned(),
            tool_version: env!("CARGO_PKG_VERSION").to_owned(),
            method_revision: 1,
        }
    }
}

#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
pub struct ExactCssDistanceResult {
    pub status: ExactCssDistanceStatus,
    pub distance: usize,
    pub method: ExactCssDistanceMethod,
    pub bound_type: ExactDistanceBoundType,
    pub logical_class: LogicalClass,
    pub witness: DistanceBoundWitness,
    #[serde(default)]
    pub requested_backend: ExactCssDistanceBackend,
    #[serde(skip_serializing_if = "Option::is_none")]
    pub backend: Option<ExactCssDistanceBackend>,
    #[serde(skip_serializing_if = "Option::is_none")]
    pub solver_status: Option<ExactCssDistanceSolverStatus>,
    #[serde(skip_serializing_if = "Option::is_none")]
    pub time_limit_seconds: Option<f64>,
    #[serde(skip_serializing_if = "Option::is_none")]
    pub mip_gap: Option<f64>,
    #[serde(skip_serializing_if = "Option::is_none")]
    pub threads: Option<u32>,
    #[serde(default, skip_serializing_if = "is_false")]
    pub verbose_solver: bool,
    pub options: ExactCssDistanceOptions,
    pub provenance: ExactCssDistanceProvenance,
}

impl ExactCssDistanceResult {
    pub fn completed(distance: DistanceResult, options: ExactCssDistanceOptions) -> Self {
        Self::completed_with_solver_report(distance, options, None)
    }

    pub fn completed_with_solver_report(
        distance: DistanceResult,
        options: ExactCssDistanceOptions,
        solver_report: Option<ExactCssDistanceSolverReport>,
    ) -> Self {
        let solver_status = solver_report.map(|report| report.status);
        let backend = solver_report.map(|report| report.backend);
        let solver_certifies_exact = solver_status
            .map(ExactCssDistanceSolverStatus::is_exact)
            .unwrap_or(true);
        let options_allow_exact = !has_positive_mip_gap(&options.solver);
        let is_exact = solver_certifies_exact && options_allow_exact;
        let status = match solver_status {
            Some(ExactCssDistanceSolverStatus::TimeLimit) => ExactCssDistanceStatus::Timeout,
            _ if !is_exact => ExactCssDistanceStatus::Incomplete,
            _ => ExactCssDistanceStatus::Completed,
        };
        let bound_type = if is_exact {
            ExactDistanceBoundType::Exact
        } else {
            ExactDistanceBoundType::Upper
        };

        Self {
            status,
            distance: distance.distance,
            method: ExactCssDistanceMethod::RstimIlpExact,
            bound_type,
            logical_class: distance.logical_class,
            witness: DistanceBoundWitness::from_pauli(&distance.witness),
            requested_backend: options.solver.backend,
            backend,
            solver_status,
            time_limit_seconds: options.solver.time_limit_seconds,
            mip_gap: options.solver.mip_gap,
            threads: options.solver.threads,
            verbose_solver: options.solver.verbose_solver,
            options,
            provenance: ExactCssDistanceProvenance::current(),
        }
    }
}

fn is_false(value: &bool) -> bool {
    !*value
}

fn has_positive_mip_gap(options: &ExactCssDistanceSolverOptions) -> bool {
    options.mip_gap.map(|gap| gap > 0.0).unwrap_or(false)
}