Skip to main content

relay_bp/
dem.rs

1// (C) Copyright IBM 2025
2//
3// This code is licensed under the Apache License, Version 2.0. You may
4// obtain a copy of this license in the LICENSE.txt file in the root directory
5// of this source tree or at http://www.apache.org/licenses/LICENSE-2.0.
6//
7// Any modifications or derivative works of this code must retain this
8// copyright notice, and modified files need to carry a notice indicating
9// that they have been altered from the originals.
10
11use crate::decoder::SparseBitMatrix;
12use crate::utilities::sparse::load_sparse_npz;
13use ndarray_npy::{read_npy, ReadNpzError};
14use std::path::PathBuf;
15
16use ndarray::Array1;
17
18pub struct DetectorErrorModel {
19    /// Decoding matrix stored in csc format for performance.
20    pub detector_error_matrix: SparseBitMatrix,
21    /// Decoding matrix stored in csc format for performance.
22    pub observable_error_matrix: SparseBitMatrix,
23    pub error_priors: Array1<f64>,
24}
25
26impl DetectorErrorModel {
27    pub fn new(
28        detector_error_matrix: SparseBitMatrix,
29        observable_error_matrix: SparseBitMatrix,
30        error_priors: Array1<f64>,
31    ) -> Self {
32        DetectorErrorModel {
33            detector_error_matrix: detector_error_matrix.into_csc(),
34            observable_error_matrix: observable_error_matrix.into_csc(),
35            error_priors,
36        }
37    }
38
39    // Load from disk given a path and a prefix name.
40    pub fn load(p: PathBuf) -> Result<Self, ReadNpzError> {
41        let mut path_components = p.components();
42        // Remove empty
43        let code_name = path_components.next_back().unwrap();
44        let path_no_file = path_components.as_path();
45
46        let detector_error_matrix_name_name =
47            format!("{}_Hdec.npz", code_name.as_os_str().to_str().unwrap());
48        let detector_error_matrix =
49            load_sparse_npz(path_no_file.join(detector_error_matrix_name_name))?.into_csc();
50
51        let observable_error_matrix_name_name =
52            format!("{}_Adec.npz", code_name.as_os_str().to_str().unwrap());
53        let observable_error_matrix =
54            load_sparse_npz(path_no_file.join(observable_error_matrix_name_name))?.into_csc();
55
56        let prior_name = format!(
57            "{}_error_priors.npy",
58            code_name.as_os_str().to_str().unwrap()
59        );
60        let error_priors: Array1<f32> = read_npy(path_no_file.join(prior_name))?;
61
62        Ok(DetectorErrorModel {
63            detector_error_matrix,
64            observable_error_matrix,
65            error_priors: error_priors.mapv(|elem| elem as f64),
66        })
67    }
68}