use pyo3::{exceptions::PyValueError, prelude::*};
use qoqo_macros::noise_model_wrapper;
use roqoqo::noise_models::{DecoherenceOnGateModel, NoiseModel};
#[cfg(feature = "json_schema")]
use roqoqo::{operations::SupportedVersion, ROQOQO_VERSION};
use struqture_py;
#[pyclass(frozen, name = "DecoherenceOnGateModel")]
#[derive(Debug, Default, Clone, PartialEq)]
pub struct DecoherenceOnGateModelWrapper {
internal: DecoherenceOnGateModel,
}
#[noise_model_wrapper]
impl DecoherenceOnGateModelWrapper {
#[new]
pub fn new() -> DecoherenceOnGateModelWrapper {
DecoherenceOnGateModelWrapper {
internal: DecoherenceOnGateModel::new(),
}
}
pub fn set_single_qubit_gate_error(
&self,
gate: &str,
qubit: usize,
noise_operator: &Bound<PyAny>,
) -> PyResult<Self> {
let noise_operator: struqture::spins::PlusMinusLindbladNoiseOperator =
match struqture_py::spins::PlusMinusLindbladNoiseOperatorWrapper::from_pyany(
noise_operator,
) {
Ok(x) => x,
Err(_) => match struqture_py::spins::PlusMinusLindbladNoiseOperatorWrapper::from_struqture_2(noise_operator) {
Ok(x) => x.internal,
Err(err) => return Err(PyValueError::new_err(format!("Could not convert input noise_operator from either struqture 1.x or struqture 2.x: {:?}", err))),
}
};
Ok(Self {
internal: self.internal.clone().set_single_qubit_gate_error(
gate,
qubit,
noise_operator,
),
})
}
pub fn get_single_qubit_gate_error(
&self,
gate: &str,
qubit: usize,
) -> Option<struqture_py::spins::PlusMinusLindbladNoiseOperatorWrapper> {
self.internal
.get_single_qubit_gate_error(gate, qubit)
.map(
|noise_operator| struqture_py::spins::PlusMinusLindbladNoiseOperatorWrapper {
internal: noise_operator.clone(),
},
)
}
pub fn set_two_qubit_gate_error(
&self,
gate: &str,
control: usize,
target: usize,
noise_operator: &Bound<PyAny>,
) -> PyResult<Self> {
let noise_operator: struqture::spins::PlusMinusLindbladNoiseOperator =
match struqture_py::spins::PlusMinusLindbladNoiseOperatorWrapper::from_pyany(
noise_operator,
) {
Ok(x) => x,
Err(_) => match struqture_py::spins::PlusMinusLindbladNoiseOperatorWrapper::from_struqture_2(noise_operator) {
Ok(x) => x.internal,
Err(err) => return Err(PyValueError::new_err(format!("Could not convert input noise_operator from either struqture 1.x or struqture 2.x: {:?}", err))),
}
};
Ok(Self {
internal: self.internal.clone().set_two_qubit_gate_error(
gate,
control,
target,
noise_operator,
),
})
}
pub fn get_two_qubit_gate_error(
&self,
gate: &str,
control: usize,
target: usize,
) -> Option<struqture_py::spins::PlusMinusLindbladNoiseOperatorWrapper> {
self.internal
.get_two_qubit_gate_error(gate, control, target)
.map(
|noise_operator| struqture_py::spins::PlusMinusLindbladNoiseOperatorWrapper {
internal: noise_operator.clone(),
},
)
}
pub fn set_three_qubit_gate_error(
&self,
gate: &str,
control0: usize,
control1: usize,
target: usize,
noise_operator: &Bound<PyAny>,
) -> PyResult<Self> {
let noise_operator: struqture::spins::PlusMinusLindbladNoiseOperator =
match struqture_py::spins::PlusMinusLindbladNoiseOperatorWrapper::from_pyany(
noise_operator,
) {
Ok(x) => x,
Err(_) => match struqture_py::spins::PlusMinusLindbladNoiseOperatorWrapper::from_struqture_2(noise_operator) {
Ok(x) => x.internal,
Err(err) => return Err(PyValueError::new_err(format!("Could not convert input noise_operator from either struqture 1.x or struqture 2.x: {:?}", err))),
}
};
Ok(Self {
internal: self.internal.clone().set_three_qubit_gate_error(
gate,
control0,
control1,
target,
noise_operator,
),
})
}
pub fn get_three_qubit_gate_error(
&self,
gate: &str,
control0: usize,
control1: usize,
target: usize,
) -> Option<struqture_py::spins::PlusMinusLindbladNoiseOperatorWrapper> {
self.internal
.get_three_qubit_gate_error(gate, control0, control1, target)
.map(
|noise_operator| struqture_py::spins::PlusMinusLindbladNoiseOperatorWrapper {
internal: noise_operator.clone(),
},
)
}
pub fn set_multi_qubit_gate_error(
&self,
gate: &str,
qubits: Vec<usize>,
noise_operator: &Bound<PyAny>,
) -> PyResult<Self> {
let noise_operator: struqture::spins::PlusMinusLindbladNoiseOperator =
match struqture_py::spins::PlusMinusLindbladNoiseOperatorWrapper::from_pyany(
noise_operator,
) {
Ok(x) => x,
Err(_) => match struqture_py::spins::PlusMinusLindbladNoiseOperatorWrapper::from_struqture_2(noise_operator) {
Ok(x) => x.internal,
Err(err) => return Err(PyValueError::new_err(format!("Could not convert input noise_operator from either struqture 1.x or struqture 2.x: {:?}", err))),
}
};
Ok(Self {
internal: self.internal.clone().set_multi_qubit_gate_error(
gate,
qubits,
noise_operator,
),
})
}
pub fn get_multi_qubit_gate_error(
&self,
gate: &str,
qubits: Vec<usize>,
) -> Option<struqture_py::spins::PlusMinusLindbladNoiseOperatorWrapper> {
self.internal
.get_multi_qubit_gate_error(gate, qubits)
.map(
|noise_operator| struqture_py::spins::PlusMinusLindbladNoiseOperatorWrapper {
internal: noise_operator.clone(),
},
)
}
#[staticmethod]
#[pyo3(text_signature = "(input)")]
pub fn from_bincode(input: &Bound<PyAny>) -> PyResult<DecoherenceOnGateModelWrapper> {
let bytes = input.as_ref().extract::<Vec<u8>>().map_err(|_| {
pyo3::exceptions::PyTypeError::new_err("Input cannot be converted to byte array")
})?;
let noise_model: NoiseModel = bincode::deserialize(&bytes[..]).map_err(|_| {
pyo3::exceptions::PyValueError::new_err("Input cannot be deserialized to Noise-Model.")
})?;
match noise_model {
NoiseModel::DecoherenceOnGateModel(internal) => {
Ok(DecoherenceOnGateModelWrapper { 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<DecoherenceOnGateModelWrapper> {
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::DecoherenceOnGateModel(internal) => {
Ok(DecoherenceOnGateModelWrapper { 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!(DecoherenceOnGateModel);
serde_json::to_string_pretty(&schema).expect("Unexpected failure to serialize schema")
}
}