use crate::operations::{
ImplementedIn1point11, InvolveQubits, InvolvedQubits, Operate, OperateSpinsAnalog, Substitute,
SupportedVersion,
};
use crate::RoqoqoError;
use qoqo_calculator::{Calculator, CalculatorFloat};
use std::collections::{HashMap, HashSet};
use struqture::spins::PauliHamiltonian;
use struqture::OperateOnDensityMatrix;
use struqture::SpinIndex;
#[derive(Debug, Clone, PartialEq, roqoqo_derive::Operate)]
#[cfg_attr(feature = "serialize", derive(serde::Serialize, serde::Deserialize))]
#[cfg_attr(feature = "json_schema", derive(schemars::JsonSchema))]
pub struct ApplyConstantPauliHamiltonian {
pub hamiltonian: PauliHamiltonian,
pub time: CalculatorFloat,
}
#[allow(non_upper_case_globals)]
const TAGS_ApplyConstantPauliHamiltonian: &[&str; 3] = &[
"Operation",
"SpinsAnalogOperation",
"ApplyConstantPauliHamiltonian",
];
impl ImplementedIn1point11 for ApplyConstantPauliHamiltonian {}
impl OperateSpinsAnalog for ApplyConstantPauliHamiltonian {
fn spin(&self) -> Result<Vec<usize>, RoqoqoError> {
let mut qubit_set = HashSet::new();
for pps in self.hamiltonian.keys() {
for (index, _) in pps.iter() {
qubit_set.insert(*index);
}
}
let mut qubits = Vec::from_iter(qubit_set);
qubits.sort();
Ok(qubits)
}
}
impl SupportedVersion for ApplyConstantPauliHamiltonian {
fn minimum_supported_roqoqo_version(&self) -> (u32, u32, u32) {
(1, 11, 0)
}
}
impl InvolveQubits for ApplyConstantPauliHamiltonian {
fn involved_qubits(&self) -> InvolvedQubits {
InvolvedQubits::All
}
}
impl Substitute for ApplyConstantPauliHamiltonian {
fn remap_qubits(&self, mapping: &HashMap<usize, usize>) -> Result<Self, RoqoqoError> {
crate::operations::check_valid_mapping(mapping)?;
let mut new_hamiltonian = PauliHamiltonian::new();
for (pp, value) in &self.hamiltonian {
let new_pp = pp.remap_qubits(mapping);
new_hamiltonian.add_operator_product(new_pp, value.clone())?;
}
Ok(ApplyConstantPauliHamiltonian::new(
new_hamiltonian,
self.time.clone(),
))
}
fn substitute_parameters(&self, calculator: &Calculator) -> Result<Self, RoqoqoError> {
let mut new_hamiltonian = self.hamiltonian.clone();
for (key, value) in &self.hamiltonian {
let new_value = calculator.parse_get(value.clone())?;
new_hamiltonian.set(key.clone(), new_value.into())?;
}
let new_time = calculator.parse_get(self.time.clone())?;
Ok(ApplyConstantPauliHamiltonian::new(
new_hamiltonian,
new_time.into(),
))
}
}
#[derive(Debug, Clone, PartialEq, roqoqo_derive::Operate)]
#[cfg_attr(feature = "serialize", derive(serde::Serialize, serde::Deserialize))]
#[cfg_attr(feature = "json_schema", derive(schemars::JsonSchema))]
pub struct ApplyTimeDependentPauliHamiltonian {
hamiltonian: PauliHamiltonian,
time: Vec<f64>,
values: HashMap<String, Vec<f64>>,
}
#[allow(non_upper_case_globals)]
const TAGS_ApplyTimeDependentPauliHamiltonian: &[&str; 3] = &[
"Operation",
"SpinsAnalogOperation",
"ApplyTimeDependentPauliHamiltonian",
];
impl ImplementedIn1point11 for ApplyTimeDependentPauliHamiltonian {}
impl OperateSpinsAnalog for ApplyTimeDependentPauliHamiltonian {
fn spin(&self) -> Result<Vec<usize>, RoqoqoError> {
let mut qubit_set = HashSet::new();
for pps in self.hamiltonian.keys() {
for (index, _) in pps.iter() {
qubit_set.insert(*index);
}
}
let mut qubits = Vec::from_iter(qubit_set);
qubits.sort();
Ok(qubits)
}
}
impl SupportedVersion for ApplyTimeDependentPauliHamiltonian {
fn minimum_supported_roqoqo_version(&self) -> (u32, u32, u32) {
(1, 11, 0)
}
}
impl InvolveQubits for ApplyTimeDependentPauliHamiltonian {
fn involved_qubits(&self) -> InvolvedQubits {
InvolvedQubits::All
}
}
impl Substitute for ApplyTimeDependentPauliHamiltonian {
fn remap_qubits(&self, mapping: &HashMap<usize, usize>) -> Result<Self, RoqoqoError> {
crate::operations::check_valid_mapping(mapping)?;
let mut new_hamiltonian = PauliHamiltonian::new();
for (pp, value) in &self.hamiltonian {
let new_pp = pp.remap_qubits(mapping);
new_hamiltonian.add_operator_product(new_pp, value.clone())?;
}
Ok(ApplyTimeDependentPauliHamiltonian::new(
new_hamiltonian,
self.time.clone(),
self.values.clone(),
))
}
fn substitute_parameters(&self, calculator: &Calculator) -> Result<Self, RoqoqoError> {
let mut new_hamiltonian = self.hamiltonian.clone();
for (key, value) in &self.hamiltonian {
let new_value = calculator.parse_get(value.clone())?;
new_hamiltonian.set(key.clone(), new_value.into())?;
}
Ok(ApplyTimeDependentPauliHamiltonian::new(
new_hamiltonian,
self.time.clone(),
self.values.clone(),
))
}
}