Skip to content

Commit dcc5fb7

Browse files
committed
Basic prototype. I think there's a major issue, I have not tested yet.
1 parent 55994b8 commit dcc5fb7

File tree

2 files changed

+52
-4
lines changed

2 files changed

+52
-4
lines changed

crates/pecos-engines/src/noise/general.rs

Lines changed: 50 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -92,7 +92,7 @@ use pecos_core::QubitId;
9292
use pecos_core::errors::PecosError;
9393
use rand_chacha::ChaCha8Rng;
9494
use std::any::Any;
95-
use std::collections::HashSet;
95+
use std::collections::{HashSet, BTreeSet};
9696

9797
/// General noise model implementation that includes parameterized error channels for various quantum operations
9898
///
@@ -326,6 +326,17 @@ pub struct GeneralNoiseModel {
326326
/// Random number generator for stochastic noise processes
327327
rng: NoiseRng<ChaCha8Rng>,
328328

329+
/// Set of qubits that have been initialized at any point in the program.
330+
///
331+
/// This is so that we know which qubits exists and we can apply crosstalk
332+
/// to them. Qubits that are measured / discarded are not removed from here, since
333+
/// PECOS does not assume measurements are destructive. This should not cause a
334+
/// problem, since inactive qubits suffering error have no effect on the state,
335+
/// and active qubits should always suffer errors under this naive crosstalk model.
336+
///
337+
/// Using a BTreeSet because we will iterate over the qubits and we want determinism.
338+
initialized_qubits: BTreeSet<usize>,
339+
329340
/// Track which qubits are being measured in the current batch and their gate types
330341
/// This is needed to properly handle leakage during measurements
331342
/// Each entry is (`qubit_id`, `is_measure_leaked`)
@@ -503,9 +514,11 @@ impl GeneralNoiseModel {
503514
);
504515
}
505516
GateType::Prep => {
517+
for &q in &gate.qubits {
518+
self.initialized_qubits.insert(usize::from(q));
519+
}
506520
self.apply_prep_faults(&gate, &mut builder);
507-
508-
// TODO: Implement prep crosstalk when needed
521+
self.apply_crosstalk_faults(&gate, self.p_prep_crosstalk, &mut builder);
509522
}
510523
GateType::Measure | GateType::MeasureLeaked => {
511524
// Track which qubits are being measured for leakage handling
@@ -518,6 +531,7 @@ impl GeneralNoiseModel {
518531
// Measurement noise is handled in apply_noise_on_continue_processing
519532
// We still need to add the original gate here
520533
builder.add_gate_command(&gate);
534+
self.apply_crosstalk_faults(&gate, self.p_meas_crosstalk, &mut builder);
521535
}
522536
GateType::I => {
523537
let err_msg = format!(
@@ -783,6 +797,39 @@ impl GeneralNoiseModel {
783797
}
784798
}
785799

800+
/// Apply crosstalk noise
801+
///
802+
/// Naive crosstalk noise model:
803+
/// 1. All qubits in the trap but the ones in the `gate` are subject to crosstalk
804+
// error. The `gate` should be either qubit measurement or initialization.
805+
// 2. *Each* qubit not in `gate` has the given `probability` to suffer an error.
806+
/// 3. Affected qubits are collapsed into the computational basis (Z measurement).
807+
///
808+
/// In ion trap systems, this could represent scattered light during optical pumping
809+
/// affecting neighboring ions.
810+
pub fn apply_crosstalk_faults(
811+
&mut self,
812+
gate: &Gate,
813+
probability: f64,
814+
builder: &mut ByteMessageBuilder
815+
) {
816+
let mut affected_qubits = Vec::new();
817+
let gate_qubits: Vec<usize> = gate.qubits.iter().map(|q| usize::from(*q)).collect();
818+
819+
for q in self.initialized_qubits.clone() {
820+
if !gate_qubits.contains(&q) {
821+
if self.rng.occurs(probability) {
822+
affected_qubits.push(q);
823+
}
824+
}
825+
}
826+
// TODO potentially major issue: I expect these will be adding measurement
827+
// outcomes to the OutputEngine, which should be ignored. How do we do this?
828+
// Perhaps there should be another add_collapse() method that applies a
829+
// measurement and discards the outcome.
830+
builder.add_measurements(&affected_qubits);
831+
}
832+
786833
/// Apply single-qubit gate noise faults
787834
///
788835
/// Models errors that occur during single-qubit gate operations:

crates/pecos-engines/src/noise/general/default.rs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
use crate::noise::{
22
GeneralNoiseModel, NoiseRng, SingleQubitWeightedSampler, TwoQubitWeightedSampler,
33
};
4-
use std::collections::{BTreeMap, HashSet};
4+
use std::collections::{BTreeMap, HashSet, BTreeSet};
55

66
impl Default for GeneralNoiseModel {
77
/// Create a new noise model with default error parameters
@@ -100,6 +100,7 @@ impl Default for GeneralNoiseModel {
100100
p2_idle: 0.0,
101101
leaked_qubits: HashSet::new(),
102102
rng: NoiseRng::default(),
103+
initialized_qubits: BTreeSet::new(),
103104
measured_qubits: Vec::new(),
104105
p_meas_crosstalk: 0.0,
105106
p_prep_crosstalk: 0.0,

0 commit comments

Comments
 (0)