use crate::operations::Operation;
use crate::operations::{
InvolveQubits, InvolvedQubits, Operate, OperateMultiQubit, OperatePragma, OperatePragmaNoise,
OperatePragmaNoiseProba, OperateSingleQubit, RoqoqoError, Substitute, SupportedVersion,
};
use crate::Circuit;
#[cfg(feature = "json_schema")]
use crate::{Array1C64Def, Array2C64Def, Array2f64Def};
#[cfg(feature = "serialize")]
use bincode::serialize;
use nalgebra::{matrix, Matrix4};
use ndarray::{array, Array, Array1, Array2};
use num_complex::Complex64;
use qoqo_calculator::{Calculator, CalculatorFloat};
#[cfg(feature = "serialize")]
use serde::{Deserialize, Serialize};
use std::collections::{HashMap, HashSet};
use std::convert::TryFrom;
use super::InvolvedClassical;
#[derive(
Debug,
Clone,
PartialEq,
Eq,
roqoqo_derive::SupportedVersion,
roqoqo_derive::Operate,
roqoqo_derive::Substitute,
roqoqo_derive::OperatePragma,
)]
#[cfg_attr(feature = "serialize", derive(Serialize, Deserialize))]
#[cfg_attr(feature = "json_schema", derive(schemars::JsonSchema))]
pub struct PragmaSetNumberOfMeasurements {
number_measurements: usize,
readout: String,
}
#[allow(non_upper_case_globals)]
const TAGS_PragmaSetNumberOfMeasurements: &[&str; 3] = &[
"Operation",
"PragmaOperation",
"PragmaSetNumberOfMeasurements",
];
impl InvolveQubits for PragmaSetNumberOfMeasurements {
fn involved_qubits(&self) -> InvolvedQubits {
InvolvedQubits::None
}
}
#[derive(
Debug,
Clone,
PartialEq,
roqoqo_derive::SupportedVersion,
roqoqo_derive::Operate,
roqoqo_derive::Substitute,
roqoqo_derive::OperatePragma,
)]
#[cfg_attr(feature = "serialize", derive(serde::Serialize, serde::Deserialize))]
pub struct PragmaSetStateVector {
statevector: Array1<Complex64>,
}
#[cfg(feature = "json_schema")]
impl schemars::JsonSchema for PragmaSetStateVector {
fn schema_name() -> String {
"PragmaSetStateVector".to_string()
}
fn json_schema(gen: &mut schemars::gen::SchemaGenerator) -> schemars::schema::Schema {
<SchemaHelperPragmaSetStateVector>::json_schema(gen)
}
}
#[cfg(feature = "json_schema")]
#[derive(schemars::JsonSchema)]
#[allow(dead_code)]
struct SchemaHelperPragmaSetStateVector {
#[serde(with = "Array1C64Def")]
statevector: Array1<Complex64>,
}
#[allow(non_upper_case_globals)]
const TAGS_PragmaSetStateVector: &[&str; 3] =
&["Operation", "PragmaOperation", "PragmaSetStateVector"];
impl InvolveQubits for PragmaSetStateVector {
fn involved_qubits(&self) -> InvolvedQubits {
InvolvedQubits::All
}
}
#[derive(
Debug,
Clone,
PartialEq,
roqoqo_derive::SupportedVersion,
roqoqo_derive::Operate,
roqoqo_derive::Substitute,
roqoqo_derive::OperatePragma,
)]
#[cfg_attr(feature = "serialize", derive(serde::Serialize, serde::Deserialize))]
pub struct PragmaSetDensityMatrix {
density_matrix: Array2<Complex64>,
}
#[cfg(feature = "json_schema")]
impl schemars::JsonSchema for PragmaSetDensityMatrix {
fn schema_name() -> String {
"PragmaSetDensityMatrix".to_string()
}
fn json_schema(gen: &mut schemars::gen::SchemaGenerator) -> schemars::schema::Schema {
<SchemaHelperPragmaSetDensityMatrix>::json_schema(gen)
}
}
#[cfg(feature = "json_schema")]
#[derive(schemars::JsonSchema)]
#[allow(dead_code)]
struct SchemaHelperPragmaSetDensityMatrix {
#[serde(with = "Array2C64Def")]
density_matrix: Array2<Complex64>,
}
#[allow(non_upper_case_globals)]
const TAGS_PragmaSetDensityMatrix: &[&str; 3] =
&["Operation", "PragmaOperation", "PragmaSetDensityMatrix"];
impl InvolveQubits for PragmaSetDensityMatrix {
fn involved_qubits(&self) -> InvolvedQubits {
InvolvedQubits::All
}
}
#[derive(
Debug,
Clone,
PartialEq,
Eq,
roqoqo_derive::SupportedVersion,
roqoqo_derive::Operate,
roqoqo_derive::Substitute,
roqoqo_derive::OperatePragma,
)]
#[cfg_attr(feature = "serialize", derive(serde::Serialize, serde::Deserialize))]
#[cfg_attr(feature = "json_schema", derive(schemars::JsonSchema))]
pub struct PragmaRepeatGate {
repetition_coefficient: usize,
}
#[allow(non_upper_case_globals)]
const TAGS_PragmaRepeatGate: &[&str; 3] = &["Operation", "PragmaOperation", "PragmaRepeatGate"];
impl InvolveQubits for PragmaRepeatGate {
fn involved_qubits(&self) -> InvolvedQubits {
InvolvedQubits::All
}
}
#[derive(
Debug,
Clone,
PartialEq,
roqoqo_derive::SupportedVersion,
roqoqo_derive::Operate,
roqoqo_derive::Substitute,
roqoqo_derive::InvolveQubits,
roqoqo_derive::OperatePragma,
roqoqo_derive::OperateMultiQubit,
)]
#[cfg_attr(feature = "serialize", derive(serde::Serialize, serde::Deserialize))]
#[cfg_attr(feature = "json_schema", derive(schemars::JsonSchema))]
pub struct PragmaOverrotation {
gate_hqslang: String,
qubits: Vec<usize>,
amplitude: f64,
variance: f64,
}
#[allow(non_upper_case_globals)]
const TAGS_PragmaOverrotation: &[&str; 4] = &[
"Operation",
"MultiQubitOperation",
"PragmaOperation",
"PragmaOverrotation",
];
#[derive(
Debug,
Clone,
PartialEq,
roqoqo_derive::SupportedVersion,
roqoqo_derive::Operate,
roqoqo_derive::Substitute,
roqoqo_derive::OperatePragma,
)]
#[cfg_attr(feature = "serialize", derive(serde::Serialize, serde::Deserialize))]
#[cfg_attr(feature = "json_schema", derive(schemars::JsonSchema))]
pub struct PragmaBoostNoise {
noise_coefficient: CalculatorFloat,
}
#[allow(non_upper_case_globals)]
const TAGS_PragmaBoostNoise: &[&str; 3] = &["Operation", "PragmaOperation", "PragmaBoostNoise"];
impl InvolveQubits for PragmaBoostNoise {
fn involved_qubits(&self) -> InvolvedQubits {
InvolvedQubits::None
}
}
#[derive(
Debug,
Clone,
PartialEq,
roqoqo_derive::InvolveQubits,
roqoqo_derive::SupportedVersion,
roqoqo_derive::Operate,
roqoqo_derive::Substitute,
roqoqo_derive::OperateMultiQubit,
roqoqo_derive::OperatePragma,
)]
#[cfg_attr(feature = "serialize", derive(serde::Serialize, serde::Deserialize))]
#[cfg_attr(feature = "json_schema", derive(schemars::JsonSchema))]
pub struct PragmaStopParallelBlock {
qubits: Vec<usize>,
execution_time: CalculatorFloat,
}
#[allow(non_upper_case_globals)]
const TAGS_PragmaStopParallelBlock: &[&str; 4] = &[
"Operation",
"MultiQubitOperation",
"PragmaOperation",
"PragmaStopParallelBlock",
];
#[derive(
Debug,
Clone,
PartialEq,
roqoqo_derive::SupportedVersion,
roqoqo_derive::Operate,
roqoqo_derive::Substitute,
roqoqo_derive::OperatePragma,
)]
#[cfg_attr(feature = "serialize", derive(serde::Serialize, serde::Deserialize))]
#[cfg_attr(feature = "json_schema", derive(schemars::JsonSchema))]
pub struct PragmaGlobalPhase {
phase: CalculatorFloat,
}
#[allow(non_upper_case_globals)]
const TAGS_PragmaGlobalPhase: &[&str; 3] = &["Operation", "PragmaOperation", "PragmaGlobalPhase"];
impl InvolveQubits for PragmaGlobalPhase {
fn involved_qubits(&self) -> InvolvedQubits {
InvolvedQubits::None
}
}
#[derive(
Debug,
Clone,
PartialEq,
roqoqo_derive::InvolveQubits,
roqoqo_derive::SupportedVersion,
roqoqo_derive::Operate,
roqoqo_derive::Substitute,
roqoqo_derive::OperateMultiQubit,
roqoqo_derive::OperatePragma,
)]
#[cfg_attr(feature = "serialize", derive(serde::Serialize, serde::Deserialize))]
#[cfg_attr(feature = "json_schema", derive(schemars::JsonSchema))]
pub struct PragmaSleep {
qubits: Vec<usize>,
sleep_time: CalculatorFloat,
}
#[allow(non_upper_case_globals)]
const TAGS_PragmaSleep: &[&str; 4] = &[
"Operation",
"MultiQubitOperation",
"PragmaOperation",
"PragmaSleep",
];
#[derive(
Debug,
Clone,
PartialEq,
Eq,
roqoqo_derive::InvolveQubits,
roqoqo_derive::SupportedVersion,
roqoqo_derive::Operate,
roqoqo_derive::Substitute,
roqoqo_derive::OperateSingleQubit,
roqoqo_derive::OperatePragma,
)]
#[cfg_attr(feature = "serialize", derive(serde::Serialize, serde::Deserialize))]
#[cfg_attr(feature = "json_schema", derive(schemars::JsonSchema))]
pub struct PragmaActiveReset {
qubit: usize,
}
#[allow(non_upper_case_globals)]
const TAGS_PragmaActiveReset: &[&str; 4] = &[
"Operation",
"SingleQubitOperation",
"PragmaOperation",
"PragmaActiveReset",
];
#[derive(
Debug,
Clone,
PartialEq,
Eq,
roqoqo_derive::InvolveQubits,
roqoqo_derive::SupportedVersion,
roqoqo_derive::Operate,
roqoqo_derive::OperateMultiQubit,
roqoqo_derive::OperatePragma,
)]
#[cfg_attr(feature = "serialize", derive(serde::Serialize, serde::Deserialize))]
#[cfg_attr(feature = "json_schema", derive(schemars::JsonSchema))]
pub struct PragmaStartDecompositionBlock {
qubits: Vec<usize>,
reordering_dictionary: HashMap<usize, usize>,
}
#[allow(non_upper_case_globals)]
const TAGS_PragmaStartDecompositionBlock: &[&str; 4] = &[
"Operation",
"MultiQubitOperation",
"PragmaOperation",
"PragmaStartDecompositionBlock",
];
impl Substitute for PragmaStartDecompositionBlock {
fn remap_qubits(&self, mapping: &HashMap<usize, usize>) -> Result<Self, RoqoqoError> {
crate::operations::check_valid_mapping(mapping)?;
let mut new_qubits: Vec<usize> = Vec::new();
for q in &self.qubits {
new_qubits.push(*mapping.get(q).ok_or(Err("")).map_err(
|_x: std::result::Result<&usize, &str>| RoqoqoError::QubitMappingError {
qubit: *q,
},
)?)
}
let mut mutable_reordering: HashMap<usize, usize> = HashMap::new();
for (old_qubit, new_qubit) in self.reordering_dictionary.clone() {
let old_remapped = *mapping.get(&old_qubit).unwrap_or(&old_qubit);
let new_remapped = *mapping.get(&new_qubit).unwrap_or(&new_qubit);
mutable_reordering.insert(old_remapped, new_remapped);
}
Ok(PragmaStartDecompositionBlock::new(
new_qubits,
mutable_reordering,
))
}
fn substitute_parameters(&self, _calculator: &Calculator) -> Result<Self, RoqoqoError> {
Ok(self.clone())
}
}
#[derive(
Debug,
Clone,
PartialEq,
Eq,
roqoqo_derive::InvolveQubits,
roqoqo_derive::SupportedVersion,
roqoqo_derive::Operate,
roqoqo_derive::Substitute,
roqoqo_derive::OperateMultiQubit,
roqoqo_derive::OperatePragma,
)]
#[cfg_attr(feature = "serialize", derive(serde::Serialize, serde::Deserialize))]
#[cfg_attr(feature = "json_schema", derive(schemars::JsonSchema))]
pub struct PragmaStopDecompositionBlock {
qubits: Vec<usize>,
}
#[allow(non_upper_case_globals)]
const TAGS_PragmaStopDecompositionBlock: &[&str; 4] = &[
"Operation",
"MultiQubitOperation",
"PragmaOperation",
"PragmaStopDecompositionBlock",
];
#[derive(
Debug,
Clone,
PartialEq,
roqoqo_derive::InvolveQubits,
roqoqo_derive::SupportedVersion,
roqoqo_derive::Operate,
roqoqo_derive::Substitute,
roqoqo_derive::OperateSingleQubit,
roqoqo_derive::OperatePragma,
)]
#[cfg_attr(feature = "serialize", derive(serde::Serialize, serde::Deserialize))]
#[cfg_attr(feature = "json_schema", derive(schemars::JsonSchema))]
pub struct PragmaDamping {
qubit: usize,
gate_time: CalculatorFloat,
rate: CalculatorFloat,
}
#[allow(non_upper_case_globals)]
const TAGS_PragmaDamping: &[&str; 6] = &[
"Operation",
"SingleQubitOperation",
"PragmaOperation",
"PragmaNoiseOperation",
"PragmaNoiseProbaOperation",
"PragmaDamping",
];
impl OperatePragmaNoise for PragmaDamping {
fn superoperator(&self) -> Result<Array2<f64>, RoqoqoError> {
let t1_decay: f64 = f64::try_from(-self.gate_time.clone() * self.rate.clone())?.exp();
let t2_decay: f64 = f64::try_from(-self.gate_time.clone() * self.rate.clone() * 0.5)?.exp();
Ok(array![
[1.0, 0.0, 0.0, 1.0 - t1_decay],
[0.0, t2_decay, 0.0, 0.0],
[0.0, 0.0, t2_decay, 0.0],
[0.0, 0.0, 0.0, t1_decay],
])
}
fn powercf(&self, power: CalculatorFloat) -> Self {
let mut new = self.clone();
new.gate_time = power * self.gate_time.clone();
new
}
}
impl OperatePragmaNoiseProba for PragmaDamping {
fn probability(&self) -> CalculatorFloat {
let prob: CalculatorFloat =
(self.gate_time.clone() * self.rate.clone() * (-1.0)).exp() * (-1.0) + 1.0;
prob
}
}
#[derive(
Debug,
Clone,
PartialEq,
roqoqo_derive::InvolveQubits,
roqoqo_derive::SupportedVersion,
roqoqo_derive::Operate,
roqoqo_derive::Substitute,
roqoqo_derive::OperateSingleQubit,
roqoqo_derive::OperatePragma,
)]
#[cfg_attr(feature = "serialize", derive(serde::Serialize, serde::Deserialize))]
#[cfg_attr(feature = "json_schema", derive(schemars::JsonSchema))]
pub struct PragmaDepolarising {
qubit: usize,
gate_time: CalculatorFloat,
rate: CalculatorFloat,
}
#[allow(non_upper_case_globals)]
const TAGS_PragmaDepolarising: &[&str; 6] = &[
"Operation",
"SingleQubitOperation",
"PragmaOperation",
"PragmaNoiseOperation",
"PragmaNoiseProbaOperation",
"PragmaDepolarising",
];
impl OperatePragmaNoise for PragmaDepolarising {
fn superoperator(&self) -> Result<Array2<f64>, RoqoqoError> {
let t1_decay: f64 = f64::try_from(-self.gate_time.clone() * self.rate.clone() * 1.0)?.exp();
let t2_decay: f64 = f64::try_from(-self.gate_time.clone() * self.rate.clone() * 1.0)?.exp();
Ok(array![
[0.5 + 0.5 * t1_decay, 0.0, 0.0, 0.5 - 0.5 * t1_decay],
[0.0, t2_decay, 0.0, 0.0],
[0.0, 0.0, t2_decay, 0.0],
[0.5 - 0.5 * t1_decay, 0.0, 0.0, 0.5 + 0.5 * t1_decay],
])
}
fn powercf(&self, power: CalculatorFloat) -> Self {
let mut new = self.clone();
new.gate_time = power * self.gate_time.clone();
new
}
}
impl OperatePragmaNoiseProba for PragmaDepolarising {
fn probability(&self) -> CalculatorFloat {
let prob: CalculatorFloat =
((self.gate_time.clone() * self.rate.clone() * (-1.0)).exp() * (-1.0) + 1.0) * 0.75;
prob
}
}
#[derive(
Debug,
Clone,
PartialEq,
roqoqo_derive::InvolveQubits,
roqoqo_derive::SupportedVersion,
roqoqo_derive::Operate,
roqoqo_derive::Substitute,
roqoqo_derive::OperateSingleQubit,
roqoqo_derive::OperatePragma,
)]
#[cfg_attr(feature = "serialize", derive(serde::Serialize, serde::Deserialize))]
#[cfg_attr(feature = "json_schema", derive(schemars::JsonSchema))]
pub struct PragmaDephasing {
qubit: usize,
gate_time: CalculatorFloat,
rate: CalculatorFloat,
}
#[allow(non_upper_case_globals)]
const TAGS_PragmaDephasing: &[&str; 6] = &[
"Operation",
"SingleQubitOperation",
"PragmaOperation",
"PragmaNoiseOperation",
"PragmaNoiseProbaOperation",
"PragmaDephasing",
];
impl OperatePragmaNoise for PragmaDephasing {
fn superoperator(&self) -> Result<Array2<f64>, RoqoqoError> {
let gate_time: f64 = f64::try_from(self.gate_time.clone())?;
let rate: f64 = f64::try_from(self.rate.clone())?;
let pre_exp: f64 = -2.0 * gate_time * rate;
let prob: f64 = (1.0 / 2.0) * (1.0 - pre_exp.exp());
Ok(array![
[1.0, 0.0, 0.0, 0.0],
[0.0, 1.0 - 2.0 * prob, 0.0, 0.0],
[0.0, 0.0, 1.0 - 2.0 * prob, 0.0],
[0.0, 0.0, 0.0, 1.0],
])
}
fn powercf(&self, power: CalculatorFloat) -> Self {
let mut new = self.clone();
new.gate_time = power * self.gate_time.clone();
new
}
}
impl OperatePragmaNoiseProba for PragmaDephasing {
fn probability(&self) -> CalculatorFloat {
let prob: CalculatorFloat =
((self.gate_time.clone() * self.rate.clone() * (-2.0)).exp() * (-1.0) + 1.0) * 0.5;
prob
}
}
#[derive(
Debug,
Clone,
PartialEq,
roqoqo_derive::InvolveQubits,
roqoqo_derive::SupportedVersion,
roqoqo_derive::Operate,
roqoqo_derive::Substitute,
roqoqo_derive::OperateSingleQubit,
roqoqo_derive::OperatePragma,
)]
#[cfg_attr(feature = "serialize", derive(serde::Serialize, serde::Deserialize))]
#[cfg_attr(feature = "json_schema", derive(schemars::JsonSchema))]
pub struct PragmaRandomNoise {
qubit: usize,
gate_time: CalculatorFloat,
depolarising_rate: CalculatorFloat,
dephasing_rate: CalculatorFloat,
}
#[allow(non_upper_case_globals)]
const TAGS_PragmaRandomNoise: &[&str; 6] = &[
"Operation",
"SingleQubitOperation",
"PragmaOperation",
"PragmaNoiseOperation",
"PragmaNoiseProbaOperation",
"PragmaRandomNoise",
];
impl OperatePragmaNoise for PragmaRandomNoise {
fn superoperator(&self) -> Result<Array2<f64>, RoqoqoError> {
let gate_time: f64 = f64::try_from(self.gate_time.clone())?;
let rate: f64 = f64::try_from(self.dephasing_rate.clone())?;
let pre_exp: f64 = -2.0 * gate_time * rate;
let prob: f64 = (1.0 / 2.0) * (1.0 - pre_exp.exp());
Ok(array![
[1.0, 0.0, 0.0, 0.0],
[0.0, 1.0 - 2.0 * prob, 0.0, 0.0],
[0.0, 0.0, 1.0 - 2.0 * prob, 0.0],
[0.0, 0.0, 0.0, 1.0],
])
}
fn powercf(&self, power: CalculatorFloat) -> Self {
let mut new = self.clone();
new.gate_time = power * self.gate_time.clone();
new
}
}
impl OperatePragmaNoiseProba for PragmaRandomNoise {
fn probability(&self) -> CalculatorFloat {
let rates = [
self.depolarising_rate.clone() / 4.0,
self.depolarising_rate.clone() / 4.0,
(self.depolarising_rate.clone() / 4.0) + self.dephasing_rate.clone(),
];
(rates[0].clone() + &rates[1] + &rates[2]) * &self.gate_time
}
}
#[derive(
Debug,
Clone,
PartialEq,
roqoqo_derive::InvolveQubits,
roqoqo_derive::SupportedVersion,
roqoqo_derive::Operate,
roqoqo_derive::Substitute,
roqoqo_derive::OperateSingleQubit,
roqoqo_derive::OperatePragma,
)]
#[cfg_attr(feature = "serialize", derive(serde::Serialize, serde::Deserialize))]
pub struct PragmaGeneralNoise {
qubit: usize,
gate_time: CalculatorFloat,
rates: Array2<f64>,
}
#[cfg(feature = "json_schema")]
impl schemars::JsonSchema for PragmaGeneralNoise {
fn schema_name() -> String {
"PragmaGeneralNoise".to_string()
}
fn json_schema(gen: &mut schemars::gen::SchemaGenerator) -> schemars::schema::Schema {
<SchemaHelperPragmaGeneralNoise>::json_schema(gen)
}
}
#[cfg(feature = "json_schema")]
#[derive(schemars::JsonSchema)]
#[allow(dead_code)]
struct SchemaHelperPragmaGeneralNoise {
qubit: usize,
gate_time: CalculatorFloat,
#[serde(with = "Array2f64Def")]
rates: Array2<f64>,
}
#[allow(non_upper_case_globals)]
const TAGS_PragmaGeneralNoise: &[&str; 5] = &[
"Operation",
"SingleQubitOperation",
"PragmaOperation",
"PragmaNoiseOperation",
"PragmaGeneralNoise",
];
const PGN_SUPEROP: [[Matrix4<f64>; 3]; 3] = [
[
matrix![
0., 0., 0., 1.;
0., -0.5, 0., 0.;
0., 0., -0.5, 0.;
0., 0., 0., -1.;
],
matrix![
0., 0., 0., 0.;
0., 0., 1., 0.;
0., 0., 0., 0.;
0., 0., 0., 0.;
],
matrix![
0., 0., 0.5, 0.;
-0.5, 0., 0., -1.5;
0., 0., 0., 0.;
0., 0., -0.5, 0.;
],
],
[
matrix![
0., 0., 0., 0.;
0., 0., 0., 0.;
0., 1., 0., 0.;
0., 0., 0., 0.;
],
matrix![
-1., 0., 0., 0.;
0., -0.5, 0., 0.;
0., 0., -0.5, 0.;
1., 0., 0., 0.;
],
matrix![
0., 0.5, 0., 0.;
0., 0., 0., 0.;
1.5, 0., 0., 0.5;
0., -0.5, 0., 0.;
],
],
[
matrix![
0., 0.5, 0., 0.;
0., 0., 0., 0.;
-0.5, 0., 0., -1.5;
0., -0.5, 0., 0.;
],
matrix![
0., 0., 0.5, 0.;
1.5, 0., 0., 0.5;
0., 0., 0., 0.;
0., 0., -0.5, 0.;
],
matrix![
0., 0., 0., 0.;
0., -2., 0., 0.;
0., 0., -2., 0.;
0., 0., 0., 0.;
],
],
];
impl OperatePragmaNoise for PragmaGeneralNoise {
fn superoperator(&self) -> Result<Array2<f64>, RoqoqoError> {
let gate_time: f64 = f64::try_from(self.gate_time.clone())?;
let mut superop = Matrix4::<f64>::default();
for (i, row) in PGN_SUPEROP.iter().enumerate() {
for (j, op) in row.iter().clone().enumerate() {
let tmp_superop: Matrix4<f64> = *op;
superop += gate_time * self.rates[(i, j)] * tmp_superop;
}
}
let mut exp_superop: Matrix4<f64> = superop.exp();
exp_superop.transpose_mut();
let mut tmp_iter = exp_superop.iter();
let array: Array2<f64> = Array::from_shape_simple_fn((4, 4), || *tmp_iter.next().unwrap());
Ok(array)
}
fn powercf(&self, power: CalculatorFloat) -> Self {
let mut new = self.clone();
new.gate_time = power * self.gate_time.clone();
new
}
}
#[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 PragmaConditional {
condition_register: String,
condition_index: usize,
circuit: Circuit,
}
#[allow(non_upper_case_globals)]
const TAGS_PragmaConditional: &[&str; 3] = &["Operation", "PragmaOperation", "PragmaConditional"];
impl InvolveQubits for PragmaConditional {
fn involved_qubits(&self) -> InvolvedQubits {
self.circuit.involved_qubits()
}
fn involved_classical(&self) -> super::InvolvedClassical {
let mut new_set: HashSet<(String, usize)> = HashSet::new();
new_set.insert((self.condition_register.clone(), self.condition_index));
super::InvolvedClassical::Set(new_set)
}
}
impl Substitute for PragmaConditional {
fn remap_qubits(&self, mapping: &HashMap<usize, usize>) -> Result<Self, RoqoqoError> {
let new_circuit = self.circuit.remap_qubits(mapping).unwrap();
Ok(PragmaConditional::new(
self.condition_register.clone(),
self.condition_index,
new_circuit,
))
}
fn substitute_parameters(&self, calculator: &Calculator) -> Result<Self, RoqoqoError> {
let new_circuit = self.circuit.substitute_parameters(calculator).unwrap();
Ok(PragmaConditional::new(
self.condition_register.clone(),
self.condition_index,
new_circuit,
))
}
}
#[derive(Debug, Clone, PartialEq, 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 PragmaControlledCircuit {
controlling_qubit: usize,
circuit: Circuit,
}
impl SupportedVersion for PragmaControlledCircuit {
fn minimum_supported_roqoqo_version(&self) -> (u32, u32, u32) {
if self.circuit.minimum_supported_roqoqo_version() > (1, 5, 0) {
return self.circuit.minimum_supported_roqoqo_version();
}
(1, 5, 0)
}
}
impl super::ImplementedIn1point5 for PragmaControlledCircuit {}
#[allow(non_upper_case_globals)]
const TAGS_PragmaControlledCircuit: &[&str; 3] =
&["Operation", "PragmaOperation", "PragmaControlledCircuit"];
impl InvolveQubits for PragmaControlledCircuit {
fn involved_qubits(&self) -> InvolvedQubits {
match self.circuit.involved_qubits() {
InvolvedQubits::All => InvolvedQubits::All,
InvolvedQubits::None => {
let set: HashSet<usize> = [self.controlling_qubit].into_iter().collect();
InvolvedQubits::Set(set)
}
InvolvedQubits::Set(s) => {
let mut set = s;
set.insert(self.controlling_qubit);
InvolvedQubits::Set(set)
}
}
}
fn involved_classical(&self) -> super::InvolvedClassical {
super::InvolvedClassical::None
}
}
impl Substitute for PragmaControlledCircuit {
fn remap_qubits(&self, mapping: &HashMap<usize, usize>) -> Result<Self, RoqoqoError> {
let new_circuit = self.circuit.remap_qubits(mapping).unwrap();
crate::operations::check_valid_mapping(mapping)?;
let new_controlling_qubit = mapping
.get(&self.controlling_qubit)
.unwrap_or(&self.controlling_qubit);
Ok(PragmaControlledCircuit::new(
*new_controlling_qubit,
new_circuit,
))
}
fn substitute_parameters(&self, calculator: &Calculator) -> Result<Self, RoqoqoError> {
let new_circuit = self.circuit.substitute_parameters(calculator).unwrap();
Ok(PragmaControlledCircuit::new(
self.controlling_qubit,
new_circuit,
))
}
}
#[derive(
Debug, Clone, PartialEq, Eq, roqoqo_derive::SupportedVersion, roqoqo_derive::OperatePragma,
)]
#[cfg_attr(feature = "serialize", derive(serde::Serialize, serde::Deserialize))]
#[cfg_attr(feature = "json_schema", derive(schemars::JsonSchema))]
pub struct PragmaChangeDevice {
pub wrapped_tags: Vec<String>,
pub wrapped_hqslang: String,
pub wrapped_operation: Vec<u8>,
}
#[cfg_attr(feature = "dynamic", typetag::serde)]
impl Operate for PragmaChangeDevice {
fn tags(&self) -> &'static [&'static str] {
TAGS_PragmaChangeDevice
}
fn hqslang(&self) -> &'static str {
"PragmaChangeDevice"
}
fn is_parametrized(&self) -> bool {
false
}
}
impl PragmaChangeDevice {
#[cfg(feature = "serialize")]
pub fn new<T>(wrapped_pragma: &T) -> Result<Self, RoqoqoError>
where
T: Operate,
T: Serialize,
{
Ok(Self {
wrapped_tags: wrapped_pragma
.tags()
.iter()
.map(|x| x.to_string())
.collect(),
wrapped_hqslang: wrapped_pragma.hqslang().to_string(),
wrapped_operation: serialize(wrapped_pragma).map_err(|err| {
RoqoqoError::SerializationError {
msg: format!("{:?}", err),
}
})?,
})
}
}
#[allow(non_upper_case_globals)]
const TAGS_PragmaChangeDevice: &[&str; 3] = &["Operation", "PragmaOperation", "PragmaChangeDevice"];
impl InvolveQubits for PragmaChangeDevice {
fn involved_qubits(&self) -> InvolvedQubits {
InvolvedQubits::All
}
}
impl Substitute for PragmaChangeDevice {
fn remap_qubits(&self, mapping: &HashMap<usize, usize>) -> Result<Self, RoqoqoError> {
crate::operations::check_valid_mapping(mapping)?;
match mapping.iter().find(|(x, y)| x != y) {
Some((x, _)) => Err(RoqoqoError::QubitMappingError { qubit: *x }),
None => Ok(self.clone()),
}
}
#[allow(unused_variables)]
fn substitute_parameters(&self, calculator: &Calculator) -> Result<Self, RoqoqoError> {
Ok(self.clone())
}
}
#[derive(Debug, Clone, PartialEq, 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 PragmaLoop {
repetitions: CalculatorFloat,
circuit: Circuit,
}
impl super::ImplementedIn1point1 for PragmaLoop {}
impl SupportedVersion for PragmaLoop {
fn minimum_supported_roqoqo_version(&self) -> (u32, u32, u32) {
(1, 1, 0)
}
}
#[allow(non_upper_case_globals)]
const TAGS_PragmaLoop: &[&str; 3] = &["Operation", "PragmaOperation", "PragmaLoop"];
impl Substitute for PragmaLoop {
fn remap_qubits(&self, mapping: &HashMap<usize, usize>) -> Result<Self, RoqoqoError> {
let new_circuit = self.circuit.remap_qubits(mapping)?;
Ok(PragmaLoop::new(self.repetitions.clone(), new_circuit))
}
fn substitute_parameters(&self, calculator: &Calculator) -> Result<Self, RoqoqoError> {
let new_repetitions = calculator.parse_get(self.repetitions.clone())?;
let new_circuit = self.circuit.substitute_parameters(calculator)?;
Ok(PragmaLoop::new(new_repetitions.into(), new_circuit))
}
}
impl InvolveQubits for PragmaLoop {
fn involved_qubits(&self) -> InvolvedQubits {
self.circuit.involved_qubits()
}
fn involved_classical(&self) -> InvolvedClassical {
let mut involved = InvolvedClassical::None;
for op in self.circuit.iter() {
let tmp_involved = op.involved_classical();
match &tmp_involved {
InvolvedClassical::All(x) => {
return InvolvedClassical::All(x.clone());
}
InvolvedClassical::AllQubits(x) => {
return InvolvedClassical::AllQubits(x.clone());
}
InvolvedClassical::None => (),
InvolvedClassical::Set(x) => match involved {
InvolvedClassical::All(y) => {
return InvolvedClassical::All(y);
}
InvolvedClassical::AllQubits(y) => {
return InvolvedClassical::AllQubits(y);
}
InvolvedClassical::None => involved = tmp_involved,
InvolvedClassical::Set(y) => {
let mut combined = x.clone();
combined.extend(y);
involved = InvolvedClassical::Set(combined)
}
},
}
}
involved
}
}
#[derive(Debug, Clone, PartialEq, roqoqo_derive::OperatePragma)]
#[cfg_attr(feature = "serialize", derive(serde::Serialize, serde::Deserialize))]
#[cfg_attr(feature = "json_schema", derive(schemars::JsonSchema))]
pub struct PragmaAnnotatedOp {
pub operation: Box<Operation>,
pub annotation: String,
}
#[cfg_attr(feature = "dynamic", typetag::serde)]
impl Operate for PragmaAnnotatedOp {
fn tags(&self) -> &'static [&'static str] {
TAGS_PragmaAnnotatedOp
}
fn hqslang(&self) -> &'static str {
"PragmaAnnotatedOp"
}
fn is_parametrized(&self) -> bool {
self.operation.is_parametrized()
}
}
impl PragmaAnnotatedOp {
pub fn new(operation: Operation, annotation: String) -> Self {
Self {
operation: Box::new(operation),
annotation,
}
}
}
impl super::ImplementedIn1point8 for PragmaAnnotatedOp {}
impl SupportedVersion for PragmaAnnotatedOp {
fn minimum_supported_roqoqo_version(&self) -> (u32, u32, u32) {
(1, 8, 0)
}
}
#[allow(non_upper_case_globals)]
const TAGS_PragmaAnnotatedOp: &[&str; 3] = &["Operation", "PragmaOperation", "PragmaAnnotatedOp"];
impl Substitute for PragmaAnnotatedOp {
fn remap_qubits(&self, mapping: &HashMap<usize, usize>) -> Result<Self, RoqoqoError> {
let new_op = self.operation.remap_qubits(mapping)?;
Ok(PragmaAnnotatedOp::new(new_op, self.annotation.clone()))
}
fn substitute_parameters(&self, calculator: &Calculator) -> Result<Self, RoqoqoError> {
let new_op = self.operation.substitute_parameters(calculator)?;
Ok(PragmaAnnotatedOp::new(new_op, self.annotation.clone()))
}
}
impl InvolveQubits for PragmaAnnotatedOp {
fn involved_qubits(&self) -> InvolvedQubits {
self.operation.involved_qubits()
}
}