use qoqo_calculator::Calculator;
use std::collections::{HashMap, HashSet};
use super::InvolvedClassical;
use super::SupportedVersion;
use crate::operations::{
InvolveQubits, InvolvedQubits, Operate, OperatePragma, OperateSingleQubit, RoqoqoError,
Substitute,
};
use crate::Circuit;
#[derive(
Debug,
Clone,
PartialEq,
Eq,
roqoqo_derive::SupportedVersion,
roqoqo_derive::Operate,
roqoqo_derive::Substitute,
roqoqo_derive::OperateSingleQubit,
)]
#[cfg_attr(feature = "serialize", derive(serde::Serialize, serde::Deserialize))]
#[cfg_attr(feature = "json_schema", derive(schemars::JsonSchema))]
pub struct MeasureQubit {
qubit: usize,
readout: String,
readout_index: usize,
}
impl InvolveQubits for MeasureQubit {
fn involved_qubits(&self) -> InvolvedQubits {
let mut a: HashSet<usize> = HashSet::new();
a.insert(self.qubit);
InvolvedQubits::Set(a)
}
fn involved_classical(&self) -> super::InvolvedClassical {
let mut a: HashSet<(String, usize)> = HashSet::new();
a.insert((self.readout.clone(), self.readout_index));
InvolvedClassical::Set(a)
}
}
#[allow(non_upper_case_globals)]
const TAGS_MeasureQubit: &[&str; 3] = &["Operation", "Measurement", "MeasureQubit"];
#[derive(
Debug,
Clone,
PartialEq,
roqoqo_derive::SupportedVersion,
roqoqo_derive::Operate,
roqoqo_derive::OperatePragma,
)]
#[cfg_attr(feature = "serialize", derive(serde::Serialize, serde::Deserialize))]
#[cfg_attr(feature = "json_schema", derive(schemars::JsonSchema))]
pub struct PragmaGetStateVector {
readout: String,
circuit: Option<Circuit>,
}
#[allow(non_upper_case_globals)]
const TAGS_PragmaGetStateVector: &[&str; 4] = &[
"Operation",
"Measurement",
"PragmaOperation",
"PragmaGetStateVector",
];
impl Substitute for PragmaGetStateVector {
fn remap_qubits(&self, mapping: &HashMap<usize, usize>) -> Result<Self, RoqoqoError> {
let new_circuit = match self.circuit.as_ref() {
Some(x) => Some(x.remap_qubits(mapping)?),
_ => None,
};
Ok(PragmaGetStateVector::new(self.readout.clone(), new_circuit))
}
fn substitute_parameters(&self, calculator: &Calculator) -> Result<Self, RoqoqoError> {
let new_circuit = match self.circuit.as_ref() {
Some(x) => Some(x.substitute_parameters(calculator)?),
_ => None,
};
Ok(PragmaGetStateVector::new(self.readout.clone(), new_circuit))
}
}
impl InvolveQubits for PragmaGetStateVector {
fn involved_qubits(&self) -> InvolvedQubits {
InvolvedQubits::All
}
fn involved_classical(&self) -> InvolvedClassical {
InvolvedClassical::All(self.readout.clone())
}
}
#[derive(
Debug,
Clone,
PartialEq,
roqoqo_derive::SupportedVersion,
roqoqo_derive::Operate,
roqoqo_derive::OperatePragma,
)]
#[cfg_attr(feature = "serialize", derive(serde::Serialize, serde::Deserialize))]
#[cfg_attr(feature = "json_schema", derive(schemars::JsonSchema))]
pub struct PragmaGetDensityMatrix {
readout: String,
circuit: Option<Circuit>,
}
#[allow(non_upper_case_globals)]
const TAGS_PragmaGetDensityMatrix: &[&str; 4] = &[
"Operation",
"Measurement",
"PragmaOperation",
"PragmaGetDensityMatrix",
];
impl Substitute for PragmaGetDensityMatrix {
fn remap_qubits(&self, mapping: &HashMap<usize, usize>) -> Result<Self, RoqoqoError> {
let new_circuit = match self.circuit.as_ref() {
Some(x) => Some(x.remap_qubits(mapping)?),
_ => None,
};
Ok(PragmaGetDensityMatrix::new(
self.readout.clone(),
new_circuit,
))
}
fn substitute_parameters(&self, calculator: &Calculator) -> Result<Self, RoqoqoError> {
let new_circuit = match self.circuit.as_ref() {
Some(x) => Some(x.substitute_parameters(calculator)?),
_ => None,
};
Ok(PragmaGetDensityMatrix::new(
self.readout.clone(),
new_circuit,
))
}
}
impl InvolveQubits for PragmaGetDensityMatrix {
fn involved_qubits(&self) -> InvolvedQubits {
InvolvedQubits::All
}
fn involved_classical(&self) -> InvolvedClassical {
InvolvedClassical::All(self.readout.clone())
}
}
#[derive(
Debug,
Clone,
PartialEq,
roqoqo_derive::SupportedVersion,
roqoqo_derive::Operate,
roqoqo_derive::OperatePragma,
)]
#[cfg_attr(feature = "serialize", derive(serde::Serialize, serde::Deserialize))]
#[cfg_attr(feature = "json_schema", derive(schemars::JsonSchema))]
pub struct PragmaGetOccupationProbability {
readout: String,
circuit: Option<Circuit>,
}
#[allow(non_upper_case_globals)]
const TAGS_PragmaGetOccupationProbability: &[&str; 4] = &[
"Operation",
"Measurement",
"PragmaOperation",
"PragmaGetOccupationProbability",
];
impl Substitute for PragmaGetOccupationProbability {
fn remap_qubits(&self, mapping: &HashMap<usize, usize>) -> Result<Self, RoqoqoError> {
let new_circuit = match self.circuit.as_ref() {
Some(x) => Some(x.remap_qubits(mapping)?),
_ => None,
};
Ok(PragmaGetOccupationProbability::new(
self.readout.clone(),
new_circuit,
))
}
fn substitute_parameters(&self, calculator: &Calculator) -> Result<Self, RoqoqoError> {
let new_circuit = match self.circuit.as_ref() {
Some(x) => Some(x.substitute_parameters(calculator)?),
_ => None,
};
Ok(PragmaGetOccupationProbability::new(
self.readout.clone(),
new_circuit,
))
}
}
impl InvolveQubits for PragmaGetOccupationProbability {
fn involved_qubits(&self) -> InvolvedQubits {
InvolvedQubits::All
}
fn involved_classical(&self) -> InvolvedClassical {
InvolvedClassical::All(self.readout.clone())
}
}
#[derive(
Debug,
Clone,
PartialEq,
roqoqo_derive::SupportedVersion,
roqoqo_derive::Operate,
roqoqo_derive::OperatePragma,
)]
#[cfg_attr(feature = "serialize", derive(serde::Serialize, serde::Deserialize))]
#[cfg_attr(feature = "json_schema", derive(schemars::JsonSchema))]
pub struct PragmaGetPauliProduct {
qubit_paulis: HashMap<usize, usize>,
readout: String,
circuit: Circuit,
}
#[allow(non_upper_case_globals)]
const TAGS_PragmaGetPauliProduct: &[&str; 4] = &[
"Operation",
"Measurement",
"PragmaOperation",
"PragmaGetPauliProduct",
];
impl Substitute for PragmaGetPauliProduct {
fn remap_qubits(&self, mapping: &HashMap<usize, usize>) -> Result<Self, RoqoqoError> {
crate::operations::check_valid_mapping(mapping)?;
let mut mutable_mapping: HashMap<usize, usize> = HashMap::new();
for (key, val) in self.qubit_paulis.iter() {
let new_key = mapping.get(key).unwrap_or(key);
mutable_mapping.insert(*new_key, *val);
}
let new_circuit = self.circuit.remap_qubits(mapping).unwrap();
Ok(PragmaGetPauliProduct::new(
mutable_mapping,
self.readout.clone(),
new_circuit,
))
}
fn substitute_parameters(&self, calculator: &Calculator) -> Result<Self, RoqoqoError> {
let new_circuit = self.circuit.substitute_parameters(calculator).unwrap();
Ok(PragmaGetPauliProduct::new(
self.qubit_paulis.clone(),
self.readout.clone(),
new_circuit,
))
}
}
impl InvolveQubits for PragmaGetPauliProduct {
fn involved_qubits(&self) -> InvolvedQubits {
let mut new_hash_set: HashSet<usize> = HashSet::new();
for qubit in self.qubit_paulis.keys() {
new_hash_set.insert(*qubit);
}
if let InvolvedQubits::Set(tmp_set) = &self.circuit.involved_qubits() {
for qubit in tmp_set {
new_hash_set.insert(*qubit);
}
}
InvolvedQubits::Set(new_hash_set)
}
fn involved_classical(&self) -> InvolvedClassical {
InvolvedClassical::All(self.readout.clone())
}
}
#[derive(
Debug,
Clone,
PartialEq,
Eq,
roqoqo_derive::SupportedVersion,
roqoqo_derive::Operate,
roqoqo_derive::OperatePragma,
)]
#[cfg_attr(feature = "serialize", derive(serde::Serialize, serde::Deserialize))]
#[cfg_attr(feature = "json_schema", derive(schemars::JsonSchema))]
pub struct PragmaRepeatedMeasurement {
readout: String,
number_measurements: usize,
qubit_mapping: Option<HashMap<usize, usize>>,
}
#[allow(non_upper_case_globals)]
const TAGS_PragmaRepeatedMeasurement: &[&str; 4] = &[
"Operation",
"Measurement",
"PragmaOperation",
"PragmaRepeatedMeasurement",
];
impl Substitute for PragmaRepeatedMeasurement {
fn remap_qubits(&self, mapping: &HashMap<usize, usize>) -> Result<Self, RoqoqoError> {
crate::operations::check_valid_mapping(mapping)?;
let new_mapping = match &self.qubit_mapping {
Some(hm) => {
let mut mutable_mapping: HashMap<usize, usize> = HashMap::new();
for (key, val) in hm {
let new_key = mapping.get(key).unwrap_or(key);
mutable_mapping.insert(*new_key, *val);
}
for (key, val) in mapping.iter() {
if mutable_mapping.get(key).is_none() {
mutable_mapping.insert(*key, *val);
}
}
Some(mutable_mapping)
}
None => Some(mapping.clone()),
};
Ok(PragmaRepeatedMeasurement::new(
self.readout.clone(),
self.number_measurements,
new_mapping,
))
}
fn substitute_parameters(&self, _calculator: &Calculator) -> Result<Self, RoqoqoError> {
Ok(self.clone())
}
}
impl InvolveQubits for PragmaRepeatedMeasurement {
fn involved_qubits(&self) -> InvolvedQubits {
InvolvedQubits::All
}
fn involved_classical(&self) -> InvolvedClassical {
match &self.qubit_mapping {
None => InvolvedClassical::AllQubits(self.readout.clone()),
Some(x) => {
let new_set: HashSet<(String, usize)> =
x.values().map(|v| (self.readout.clone(), *v)).collect();
InvolvedClassical::Set(new_set)
}
}
}
}