use std::collections::HashMap;
use std::f64::consts::PI;
use quantrs2_circuit::prelude::*;
use quantrs2_core::{
gate::{
single::{Hadamard, PauliX, PauliY, PauliZ},
GateOp,
},
qubit::QubitId,
};
use super::config::{DDSequenceType, NoiseType};
use crate::DeviceResult;
use scirs2_core::random::prelude::*;
#[derive(Debug, Clone)]
pub struct DDSequence {
pub sequence_type: DDSequenceType,
pub target_qubits: Vec<QubitId>,
pub duration: f64,
pub circuit: Circuit<32>,
pub pulse_timings: Vec<f64>,
pub pulse_phases: Vec<f64>,
pub properties: DDSequenceProperties,
}
#[derive(Debug, Clone)]
pub struct DDSequenceProperties {
pub pulse_count: usize,
pub sequence_order: usize,
pub periodicity: usize,
pub symmetry: SequenceSymmetry,
pub noise_suppression: HashMap<NoiseType, f64>,
pub resource_requirements: ResourceRequirements,
}
#[derive(Debug, Clone)]
pub struct SequenceSymmetry {
pub time_reversal: bool,
pub phase_symmetry: bool,
pub rotational_symmetry: bool,
pub inversion_symmetry: bool,
}
#[derive(Debug, Clone)]
pub struct ResourceRequirements {
pub gate_count: usize,
pub circuit_depth: usize,
pub required_connectivity: Vec<(QubitId, QubitId)>,
pub execution_time: f64,
pub memory_requirements: usize,
}
pub struct DDSequenceGenerator;
impl DDSequenceGenerator {
pub fn generate_base_sequence(
sequence_type: &DDSequenceType,
target_qubits: &[QubitId],
duration: f64,
) -> DeviceResult<DDSequence> {
if target_qubits.is_empty() {
return Err(crate::DeviceError::InvalidInput(
"Target qubits cannot be empty".to_string(),
));
}
if duration <= 0.0 {
return Err(crate::DeviceError::InvalidInput(
"Duration must be positive".to_string(),
));
}
if !duration.is_finite() {
return Err(crate::DeviceError::InvalidInput(
"Duration must be finite".to_string(),
));
}
match sequence_type {
DDSequenceType::CPMG { n_pulses } => {
Self::generate_cpmg_sequence_with_pulses(target_qubits, duration, *n_pulses)
}
DDSequenceType::XY4 => Self::generate_xy4_sequence(target_qubits, duration),
DDSequenceType::XY8 => Self::generate_xy8_sequence(target_qubits, duration),
DDSequenceType::XY16 => Self::generate_xy16_sequence(target_qubits, duration),
DDSequenceType::UDD { n_pulses } => {
Self::generate_udd_sequence_with_pulses(target_qubits, duration, *n_pulses)
}
DDSequenceType::KDD => Self::generate_kdd_sequence(target_qubits, duration),
DDSequenceType::QDD => Self::generate_qdd_sequence(target_qubits, duration),
DDSequenceType::CDD => Self::generate_cdd_sequence(target_qubits, duration),
DDSequenceType::RDD => Self::generate_rdd_sequence(target_qubits, duration),
DDSequenceType::HahnEcho => Self::generate_hahn_echo_sequence(target_qubits, duration),
DDSequenceType::CarrPurcell => Self::generate_cp_sequence(target_qubits, duration),
DDSequenceType::SciRS2Optimized => {
Self::generate_optimized_sequence(target_qubits, duration)
}
DDSequenceType::Custom(name) => {
Self::generate_custom_sequence(name, target_qubits, duration)
}
DDSequenceType::Composite => {
let base_xy4 = Self::generate_xy4_sequence(target_qubits, duration)?;
let base_cpmg = Self::generate_cpmg_sequence(target_qubits, duration)?;
let base_sequences = vec![base_xy4, base_cpmg];
Self::generate_composite_sequence(&base_sequences, CompositionStrategy::Sequential)
}
DDSequenceType::MultiQubitCoordinated => {
Self::generate_xy4_sequence(target_qubits, duration)
}
DDSequenceType::Adaptive => {
Self::generate_optimized_sequence(target_qubits, duration)
}
}
}
fn generate_hahn_echo_sequence(
target_qubits: &[QubitId],
duration: f64,
) -> DeviceResult<DDSequence> {
let pulse_spacing = duration / 2.0;
let mut circuit = Circuit::<32>::new();
let mut pulse_timings = Vec::new();
let mut pulse_phases = Vec::new();
for qubit in target_qubits {
pulse_timings.push(pulse_spacing);
pulse_phases.push(PI); circuit.add_gate(PauliY { target: *qubit })?;
}
let properties = DDSequenceProperties {
pulse_count: target_qubits.len(),
sequence_order: 1,
periodicity: 1,
symmetry: SequenceSymmetry {
time_reversal: true,
phase_symmetry: true,
rotational_symmetry: false,
inversion_symmetry: true,
},
noise_suppression: {
let mut suppression = HashMap::new();
suppression.insert(NoiseType::PhaseDamping, 0.8);
suppression.insert(NoiseType::AmplitudeDamping, 0.2);
suppression
},
resource_requirements: ResourceRequirements {
gate_count: target_qubits.len(),
circuit_depth: 1,
required_connectivity: Vec::new(),
execution_time: duration,
memory_requirements: target_qubits.len() * 8,
},
};
Ok(DDSequence {
sequence_type: DDSequenceType::HahnEcho,
target_qubits: target_qubits.to_vec(),
duration,
circuit,
pulse_timings,
pulse_phases,
properties,
})
}
fn generate_cpmg_sequence_with_pulses(
target_qubits: &[QubitId],
duration: f64,
n_pulses: usize,
) -> DeviceResult<DDSequence> {
let pulse_spacing = duration / (n_pulses + 1) as f64;
let mut circuit = Circuit::<32>::new();
let mut pulse_timings = Vec::new();
let mut pulse_phases = Vec::new();
for qubit in target_qubits {
for i in 1..=n_pulses {
let timing = i as f64 * pulse_spacing;
pulse_timings.push(timing);
pulse_phases.push(PI);
circuit.add_gate(PauliY { target: *qubit })?;
}
}
let properties = DDSequenceProperties {
pulse_count: n_pulses * target_qubits.len(),
sequence_order: 1,
periodicity: n_pulses,
symmetry: SequenceSymmetry {
time_reversal: true,
phase_symmetry: true,
rotational_symmetry: false,
inversion_symmetry: true,
},
noise_suppression: {
let mut suppression = HashMap::new();
suppression.insert(NoiseType::PhaseDamping, 0.9);
suppression.insert(NoiseType::AmplitudeDamping, 0.3);
suppression
},
resource_requirements: ResourceRequirements {
gate_count: n_pulses * target_qubits.len(),
circuit_depth: n_pulses,
required_connectivity: Vec::new(),
execution_time: duration,
memory_requirements: n_pulses * target_qubits.len() * 8,
},
};
Ok(DDSequence {
sequence_type: DDSequenceType::CPMG { n_pulses },
target_qubits: target_qubits.to_vec(),
duration,
circuit,
pulse_timings,
pulse_phases,
properties,
})
}
fn generate_cpmg_sequence(
target_qubits: &[QubitId],
duration: f64,
) -> DeviceResult<DDSequence> {
Self::generate_cpmg_sequence_with_pulses(target_qubits, duration, 16)
}
fn generate_xy4_sequence(target_qubits: &[QubitId], duration: f64) -> DeviceResult<DDSequence> {
let base_sequence = [PI, PI / 2.0, PI, 3.0 * PI / 2.0]; let n_repetitions = 4;
let pulse_spacing = duration / (base_sequence.len() * n_repetitions) as f64;
let mut circuit = Circuit::<32>::new();
let mut pulse_timings = Vec::new();
let mut pulse_phases = Vec::new();
for qubit in target_qubits {
for rep in 0..n_repetitions {
for (i, &phase) in base_sequence.iter().enumerate() {
let timing = (rep * base_sequence.len() + i + 1) as f64 * pulse_spacing;
pulse_timings.push(timing);
pulse_phases.push(phase);
match phase {
p if (p - PI).abs() < 1e-6 => {
circuit.add_gate(PauliX { target: *qubit })?;
}
p if (p - PI / 2.0).abs() < 1e-6 => {
circuit.add_gate(PauliY { target: *qubit })?;
}
p if (p - 3.0 * PI / 2.0).abs() < 1e-6 => {
circuit.add_gate(PauliY { target: *qubit })?;
circuit.add_gate(PauliZ { target: *qubit })?;
circuit.add_gate(PauliZ { target: *qubit })?;
}
_ => {
circuit.add_gate(PauliX { target: *qubit })?;
}
}
}
}
}
let properties = DDSequenceProperties {
pulse_count: base_sequence.len() * n_repetitions * target_qubits.len(),
sequence_order: 2,
periodicity: base_sequence.len(),
symmetry: SequenceSymmetry {
time_reversal: true,
phase_symmetry: true,
rotational_symmetry: true,
inversion_symmetry: true,
},
noise_suppression: {
let mut suppression = HashMap::new();
suppression.insert(NoiseType::PhaseDamping, 0.95);
suppression.insert(NoiseType::AmplitudeDamping, 0.4);
suppression.insert(NoiseType::Depolarizing, 0.8);
suppression
},
resource_requirements: ResourceRequirements {
gate_count: base_sequence.len() * n_repetitions * target_qubits.len(),
circuit_depth: base_sequence.len() * n_repetitions,
required_connectivity: Vec::new(),
execution_time: duration,
memory_requirements: base_sequence.len() * n_repetitions * target_qubits.len() * 8,
},
};
Ok(DDSequence {
sequence_type: DDSequenceType::XY4,
target_qubits: target_qubits.to_vec(),
duration,
circuit,
pulse_timings,
pulse_phases,
properties,
})
}
fn generate_xy8_sequence(target_qubits: &[QubitId], duration: f64) -> DeviceResult<DDSequence> {
let base_sequence = [
PI,
PI / 2.0,
PI,
3.0 * PI / 2.0, 3.0 * PI / 2.0,
PI,
PI / 2.0,
PI, ];
let n_repetitions = 2;
let pulse_spacing = duration / (base_sequence.len() * n_repetitions) as f64;
let mut circuit = Circuit::<32>::new();
let mut pulse_timings = Vec::new();
let mut pulse_phases = Vec::new();
for qubit in target_qubits {
for rep in 0..n_repetitions {
for (i, &phase) in base_sequence.iter().enumerate() {
let timing = (rep * base_sequence.len() + i + 1) as f64 * pulse_spacing;
pulse_timings.push(timing);
pulse_phases.push(phase);
match phase {
p if (p - PI).abs() < 1e-6 => {
circuit.add_gate(PauliX { target: *qubit })?;
}
p if (p - PI / 2.0).abs() < 1e-6 => {
circuit.add_gate(PauliY { target: *qubit })?;
}
p if (p - 3.0 * PI / 2.0).abs() < 1e-6 => {
circuit.add_gate(PauliY { target: *qubit })?;
circuit.add_gate(PauliZ { target: *qubit })?;
circuit.add_gate(PauliZ { target: *qubit })?;
}
_ => {
circuit.add_gate(PauliX { target: *qubit })?;
}
}
}
}
}
let properties = DDSequenceProperties {
pulse_count: base_sequence.len() * n_repetitions * target_qubits.len(),
sequence_order: 3,
periodicity: base_sequence.len(),
symmetry: SequenceSymmetry {
time_reversal: true,
phase_symmetry: true,
rotational_symmetry: true,
inversion_symmetry: true,
},
noise_suppression: {
let mut suppression = HashMap::new();
suppression.insert(NoiseType::PhaseDamping, 0.98);
suppression.insert(NoiseType::AmplitudeDamping, 0.5);
suppression.insert(NoiseType::Depolarizing, 0.9);
suppression.insert(NoiseType::CoherentErrors, 0.85);
suppression
},
resource_requirements: ResourceRequirements {
gate_count: base_sequence.len() * n_repetitions * target_qubits.len(),
circuit_depth: base_sequence.len() * n_repetitions,
required_connectivity: Vec::new(),
execution_time: duration,
memory_requirements: base_sequence.len() * n_repetitions * target_qubits.len() * 8,
},
};
Ok(DDSequence {
sequence_type: DDSequenceType::XY8,
target_qubits: target_qubits.to_vec(),
duration,
circuit,
pulse_timings,
pulse_phases,
properties,
})
}
fn generate_xy16_sequence(
target_qubits: &[QubitId],
duration: f64,
) -> DeviceResult<DDSequence> {
let mut xy8_sequence = Self::generate_xy8_sequence(target_qubits, duration)?;
xy8_sequence.sequence_type = DDSequenceType::XY16;
xy8_sequence.properties.sequence_order = 4;
xy8_sequence
.properties
.noise_suppression
.insert(NoiseType::OneOverFNoise, 0.7);
Ok(xy8_sequence)
}
fn generate_udd_sequence_with_pulses(
target_qubits: &[QubitId],
duration: f64,
n_pulses: usize,
) -> DeviceResult<DDSequence> {
let mut pulse_timings = Vec::new();
let mut pulse_phases = Vec::new();
for k in 1..=n_pulses {
let timing = duration
* (PI * k as f64 / 2.0f64.mul_add(n_pulses as f64, 2.0))
.sin()
.powi(2);
pulse_timings.push(timing);
pulse_phases.push(PI); }
let mut circuit = Circuit::<32>::new();
for qubit in target_qubits {
for _ in 0..n_pulses {
circuit.add_gate(PauliX { target: *qubit })?;
}
}
let properties = DDSequenceProperties {
pulse_count: n_pulses * target_qubits.len(),
sequence_order: n_pulses,
periodicity: 1,
symmetry: SequenceSymmetry {
time_reversal: false,
phase_symmetry: false,
rotational_symmetry: false,
inversion_symmetry: false,
},
noise_suppression: {
let mut suppression = HashMap::new();
suppression.insert(NoiseType::PhaseDamping, 0.99);
suppression.insert(NoiseType::OneOverFNoise, 0.9);
suppression
},
resource_requirements: ResourceRequirements {
gate_count: n_pulses * target_qubits.len(),
circuit_depth: n_pulses,
required_connectivity: Vec::new(),
execution_time: duration,
memory_requirements: n_pulses * target_qubits.len() * 8,
},
};
Ok(DDSequence {
sequence_type: DDSequenceType::UDD { n_pulses },
target_qubits: target_qubits.to_vec(),
duration,
circuit,
pulse_timings,
pulse_phases,
properties,
})
}
fn generate_kdd_sequence(target_qubits: &[QubitId], duration: f64) -> DeviceResult<DDSequence> {
let mut cpmg_sequence = Self::generate_cpmg_sequence(target_qubits, duration)?;
cpmg_sequence.sequence_type = DDSequenceType::KDD;
cpmg_sequence
.properties
.noise_suppression
.insert(NoiseType::CoherentErrors, 0.95);
Ok(cpmg_sequence)
}
pub fn generate_composite_sequence(
base_sequences: &[DDSequence],
composition_strategy: CompositionStrategy,
) -> DeviceResult<DDSequence> {
if base_sequences.is_empty() {
return Err(crate::DeviceError::InvalidInput(
"No base sequences provided".to_string(),
));
}
match composition_strategy {
CompositionStrategy::Sequential => {
let mut composite_circuit = Circuit::<32>::new();
let mut composite_timings = Vec::new();
let mut composite_phases = Vec::new();
let mut total_duration = 0.0;
let mut total_gate_count = 0;
let target_qubits = base_sequences[0].target_qubits.clone();
for sequence in base_sequences {
for &timing in &sequence.pulse_timings {
composite_timings.push(total_duration + timing);
}
composite_phases.extend(&sequence.pulse_phases);
total_duration += sequence.duration;
total_gate_count += sequence.properties.pulse_count;
for qubit in &target_qubits {
for _ in 0..sequence.properties.pulse_count / target_qubits.len() {
composite_circuit.add_gate(PauliY { target: *qubit })?;
}
}
}
let mut combined_suppression = HashMap::new();
for sequence in base_sequences {
for (noise_type, suppression) in &sequence.properties.noise_suppression {
let current = combined_suppression.get(noise_type).unwrap_or(&0.0);
combined_suppression
.insert(noise_type.clone(), (current * suppression).sqrt());
}
}
let properties = DDSequenceProperties {
pulse_count: composite_timings.len(),
sequence_order: base_sequences
.iter()
.map(|s| s.properties.sequence_order)
.max()
.unwrap_or(1),
periodicity: base_sequences.len(),
symmetry: SequenceSymmetry {
time_reversal: base_sequences
.iter()
.all(|s| s.properties.symmetry.time_reversal),
phase_symmetry: base_sequences
.iter()
.all(|s| s.properties.symmetry.phase_symmetry),
rotational_symmetry: base_sequences
.iter()
.any(|s| s.properties.symmetry.rotational_symmetry),
inversion_symmetry: base_sequences
.iter()
.all(|s| s.properties.symmetry.inversion_symmetry),
},
noise_suppression: combined_suppression,
resource_requirements: ResourceRequirements {
gate_count: total_gate_count,
circuit_depth: base_sequences
.iter()
.map(|s| s.properties.resource_requirements.circuit_depth)
.sum(),
required_connectivity: Vec::new(),
execution_time: total_duration,
memory_requirements: total_gate_count * 8,
},
};
Ok(DDSequence {
sequence_type: DDSequenceType::Composite,
target_qubits,
duration: total_duration,
circuit: composite_circuit,
pulse_timings: composite_timings,
pulse_phases: composite_phases,
properties,
})
}
CompositionStrategy::Interleaved => {
Self::generate_composite_sequence(base_sequences, CompositionStrategy::Sequential)
}
CompositionStrategy::Nested => {
Self::generate_composite_sequence(base_sequences, CompositionStrategy::Sequential)
}
}
}
fn generate_qdd_sequence(target_qubits: &[QubitId], duration: f64) -> DeviceResult<DDSequence> {
let mut base = Self::generate_udd_sequence_with_pulses(target_qubits, duration, 8)?;
base.sequence_type = DDSequenceType::QDD;
Ok(base)
}
fn generate_cdd_sequence(target_qubits: &[QubitId], duration: f64) -> DeviceResult<DDSequence> {
let mut base = Self::generate_xy8_sequence(target_qubits, duration)?;
base.sequence_type = DDSequenceType::CDD;
Ok(base)
}
fn generate_rdd_sequence(target_qubits: &[QubitId], duration: f64) -> DeviceResult<DDSequence> {
let mut base = Self::generate_xy4_sequence(target_qubits, duration)?;
base.sequence_type = DDSequenceType::RDD;
base.properties
.noise_suppression
.insert(NoiseType::RandomTelegraphNoise, 0.8);
Ok(base)
}
fn generate_cp_sequence(target_qubits: &[QubitId], duration: f64) -> DeviceResult<DDSequence> {
let mut base = Self::generate_cpmg_sequence(target_qubits, duration)?;
base.sequence_type = DDSequenceType::CarrPurcell;
base.properties.symmetry.phase_symmetry = false;
Ok(base)
}
fn generate_optimized_sequence(
target_qubits: &[QubitId],
duration: f64,
) -> DeviceResult<DDSequence> {
let mut base = Self::generate_xy8_sequence(target_qubits, duration)?;
base.sequence_type = DDSequenceType::SciRS2Optimized;
base.properties.sequence_order = 5; Ok(base)
}
fn generate_custom_sequence(
name: &str,
target_qubits: &[QubitId],
duration: f64,
) -> DeviceResult<DDSequence> {
let mut base = Self::generate_cpmg_sequence(target_qubits, duration)?;
base.sequence_type = DDSequenceType::Custom(name.to_string());
Ok(base)
}
}
#[derive(Debug, Clone)]
pub struct SequenceCache {
pub cached_sequences: HashMap<String, DDSequence>,
pub cache_hits: usize,
pub cache_misses: usize,
}
impl Default for SequenceCache {
fn default() -> Self {
Self::new()
}
}
impl SequenceCache {
pub fn new() -> Self {
Self {
cached_sequences: HashMap::new(),
cache_hits: 0,
cache_misses: 0,
}
}
pub fn get_sequence(&mut self, key: &str) -> Option<DDSequence> {
if let Some(sequence) = self.cached_sequences.get(key) {
self.cache_hits += 1;
Some(sequence.clone())
} else {
self.cache_misses += 1;
None
}
}
pub fn store_sequence(&mut self, key: String, sequence: DDSequence) {
self.cached_sequences.insert(key, sequence);
}
pub fn get_cache_statistics(&self) -> (usize, usize, f64) {
let total_requests = self.cache_hits + self.cache_misses;
let hit_rate = if total_requests > 0 {
self.cache_hits as f64 / total_requests as f64
} else {
0.0
};
(self.cache_hits, self.cache_misses, hit_rate)
}
}
#[derive(Debug, Clone, PartialEq, Eq)]
pub enum CompositionStrategy {
Sequential,
Interleaved,
Nested,
}
pub struct MultiQubitDDCoordinator {
pub qubit_sequences: HashMap<Vec<QubitId>, DDSequence>,
pub crosstalk_mitigation: CrosstalkMitigationStrategy,
pub synchronization: crate::dynamical_decoupling::hardware::SynchronizationRequirements,
}
#[derive(Debug, Clone, PartialEq, Eq)]
pub enum CrosstalkMitigationStrategy {
None,
TimeShifted,
PhaseRandomized,
Orthogonal,
Adaptive,
HybridApproach,
TemporalSeparation,
SpatialSeparation,
}
#[derive(Debug, Clone)]
pub struct SynchronizationRequirements {
pub global_sync: bool,
pub phase_coherence: bool,
pub timing_tolerance: f64,
pub sync_points: Vec<f64>,
}
impl MultiQubitDDCoordinator {
pub fn new(
crosstalk_mitigation: CrosstalkMitigationStrategy,
synchronization: crate::dynamical_decoupling::hardware::SynchronizationRequirements,
) -> Self {
Self {
qubit_sequences: HashMap::new(),
crosstalk_mitigation,
synchronization,
}
}
pub fn add_sequence(&mut self, qubits: Vec<QubitId>, sequence: DDSequence) {
self.qubit_sequences.insert(qubits, sequence);
}
pub fn generate_coordinated_sequence(&self) -> DeviceResult<DDSequence> {
if self.qubit_sequences.is_empty() {
return Err(crate::DeviceError::InvalidInput(
"No sequences to coordinate".to_string(),
));
}
let sequences: Vec<_> = self.qubit_sequences.values().cloned().collect();
match self.crosstalk_mitigation {
CrosstalkMitigationStrategy::TimeShifted => {
self.generate_time_shifted_sequence(&sequences)
}
CrosstalkMitigationStrategy::PhaseRandomized => {
self.generate_phase_randomized_sequence(&sequences)
}
_ => {
DDSequenceGenerator::generate_composite_sequence(
&sequences,
CompositionStrategy::Sequential,
)
}
}
}
fn generate_time_shifted_sequence(&self, sequences: &[DDSequence]) -> DeviceResult<DDSequence> {
let base_sequence = &sequences[0];
let mut coordinated = base_sequence.clone();
let shift_increment = base_sequence.duration / (sequences.len() as f64 * 10.0);
for (i, sequence) in sequences.iter().enumerate() {
let time_shift = i as f64 * shift_increment;
for timing in &mut coordinated.pulse_timings {
*timing += time_shift;
}
}
coordinated.sequence_type = DDSequenceType::MultiQubitCoordinated;
Ok(coordinated)
}
fn generate_phase_randomized_sequence(
&self,
sequences: &[DDSequence],
) -> DeviceResult<DDSequence> {
let base_sequence = &sequences[0];
let mut coordinated = base_sequence.clone();
use std::f64::consts::PI;
for phase in &mut coordinated.pulse_phases {
let random_phase = thread_rng().random::<f64>() * 2.0 * PI;
*phase += random_phase;
}
coordinated.sequence_type = DDSequenceType::MultiQubitCoordinated;
Ok(coordinated)
}
fn generate_composite_sequence(
target_qubits: &[QubitId],
duration: f64,
) -> DeviceResult<DDSequence> {
let xy4 = DDSequenceGenerator::generate_xy4_sequence(target_qubits, duration / 2.0)?;
let cpmg = DDSequenceGenerator::generate_cpmg_sequence(target_qubits, duration / 2.0)?;
let mut composite = xy4;
composite.pulse_timings.extend(cpmg.pulse_timings);
composite.pulse_phases.extend(cpmg.pulse_phases);
composite.duration = duration;
composite.sequence_type = DDSequenceType::Composite;
Ok(composite)
}
fn generate_multi_qubit_coordinated_sequence(
target_qubits: &[QubitId],
duration: f64,
) -> DeviceResult<DDSequence> {
let mut base = DDSequenceGenerator::generate_xy4_sequence(target_qubits, duration)?;
base.sequence_type = DDSequenceType::MultiQubitCoordinated;
let shift_increment = duration / (target_qubits.len() as f64 * 10.0);
for (i, _) in target_qubits.iter().enumerate() {
let time_shift = i as f64 * shift_increment;
for timing in &mut base.pulse_timings {
*timing += time_shift;
}
}
Ok(base)
}
fn generate_adaptive_sequence(
target_qubits: &[QubitId],
duration: f64,
) -> DeviceResult<DDSequence> {
let mut base = DDSequenceGenerator::generate_xy8_sequence(target_qubits, duration)?;
base.sequence_type = DDSequenceType::Adaptive;
let adaptation_factor = 1.1; for timing in &mut base.pulse_timings {
*timing *= adaptation_factor;
}
Ok(base)
}
}