use pyo3::prelude::*;
use qoqo_macros::noise_model_wrapper;
use roqoqo::noise_models::{ImperfectReadoutModel, NoiseModel};
#[cfg(feature = "json_schema")]
use roqoqo::{operations::SupportedVersion, ROQOQO_VERSION};
#[pyclass(frozen, name = "ImperfectReadoutModel")]
#[derive(Debug, Default, Clone, PartialEq)]
pub struct ImperfectReadoutModelWrapper {
pub internal: ImperfectReadoutModel,
}
#[noise_model_wrapper]
impl ImperfectReadoutModelWrapper {
#[new]
pub fn new() -> Self {
ImperfectReadoutModelWrapper {
internal: ImperfectReadoutModel::new(),
}
}
#[staticmethod]
pub fn new_with_uniform_error(
number_qubits: usize,
prob_detect_0_as_1: f64,
prob_detect_1_as_0: f64,
) -> PyResult<Self> {
let internal = ImperfectReadoutModel::new_with_uniform_error(
number_qubits,
prob_detect_0_as_1,
prob_detect_1_as_0,
)
.map_err(|err| pyo3::exceptions::PyValueError::new_err(err.to_string()))?;
Ok(ImperfectReadoutModelWrapper { internal })
}
#[staticmethod]
#[pyo3(text_signature = "(input)")]
pub fn from_bincode(input: &Bound<PyAny>) -> PyResult<ImperfectReadoutModelWrapper> {
let bytes = input.extract::<Vec<u8>>().map_err(|_| {
pyo3::exceptions::PyTypeError::new_err("Input cannot be converted to byte array")
})?;
let noise_model: NoiseModel =
bincode::serde::decode_from_slice(&bytes[..], bincode::config::legacy())
.map_err(|_| {
pyo3::exceptions::PyValueError::new_err(
"Input cannot be deserialized to Noise-Model.",
)
})?
.0;
match noise_model {
NoiseModel::ImperfectReadoutModel(internal) => {
Ok(ImperfectReadoutModelWrapper { internal })
}
_ => Err(pyo3::exceptions::PyValueError::new_err(
"Input cannot be deserialized to selected Noise-Model.",
)),
}
}
#[staticmethod]
#[pyo3(text_signature = "(input)")]
pub fn from_json(input: &str) -> PyResult<ImperfectReadoutModelWrapper> {
let noise_model: NoiseModel = serde_json::from_str(input).map_err(|_| {
pyo3::exceptions::PyValueError::new_err("Input cannot be deserialized to Noise-Model.")
})?;
match noise_model {
NoiseModel::ImperfectReadoutModel(internal) => {
Ok(ImperfectReadoutModelWrapper { internal })
}
_ => Err(pyo3::exceptions::PyValueError::new_err(
"Input cannot be deserialized to selected Noise-Model.",
)),
}
}
#[cfg(feature = "json_schema")]
#[staticmethod]
pub fn json_schema() -> String {
let schema = schemars::schema_for!(ImperfectReadoutModel);
serde_json::to_string_pretty(&schema).expect("Unexpected failure to serialize schema")
}
pub fn set_error_probabilites(
&self,
qubit: usize,
prob_detect_0_as_1: f64,
prob_detect_1_as_0: f64,
) -> PyResult<Self> {
Ok(Self {
internal: self
.internal
.clone()
.set_error_probabilites(qubit, prob_detect_0_as_1, prob_detect_1_as_0)
.map_err(|err| pyo3::exceptions::PyValueError::new_err(err.to_string()))?,
})
}
pub fn prob_detect_0_as_1(&self, qubit: usize) -> f64 {
self.internal.prob_detect_0_as_1(&qubit)
}
pub fn prob_detect_1_as_0(&self, qubit: usize) -> f64 {
self.internal.prob_detect_1_as_0(&qubit)
}
}