use serde::{Deserialize, Serialize};
use std::collections::HashMap;
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Serialize, Deserialize)]
pub struct WireId(pub usize);
impl WireId {
pub const fn index(self) -> usize {
self.0
}
}
impl std::fmt::Display for WireId {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
write!(f, "{}", self.0)
}
}
#[derive(Debug, Clone, Default)]
pub struct WireMap {
wire_to_qubit: HashMap<usize, u32>,
qubit_to_wire: HashMap<u32, usize>,
}
impl WireMap {
pub fn from_wires(wires: &[usize]) -> Self {
let mut wire_to_qubit = HashMap::with_capacity(wires.len());
let mut qubit_to_wire = HashMap::with_capacity(wires.len());
for (qubit_idx, &wire) in wires.iter().enumerate() {
wire_to_qubit.insert(wire, qubit_idx as u32);
qubit_to_wire.insert(qubit_idx as u32, wire);
}
Self {
wire_to_qubit,
qubit_to_wire,
}
}
pub fn wire_to_qubit(&self, wire: usize) -> Option<quantrs2_core::qubit::QubitId> {
self.wire_to_qubit
.get(&wire)
.copied()
.map(quantrs2_core::qubit::QubitId)
}
pub fn qubit_to_wire(&self, qubit: u32) -> Option<usize> {
self.qubit_to_wire.get(&qubit).copied()
}
pub fn num_wires(&self) -> usize {
self.wire_to_qubit.len()
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_dense_wire_map() {
let map = WireMap::from_wires(&[0, 1, 2]);
assert_eq!(map.num_wires(), 3);
assert_eq!(map.wire_to_qubit(0).map(|q| q.0), Some(0));
assert_eq!(map.wire_to_qubit(2).map(|q| q.0), Some(2));
assert_eq!(map.qubit_to_wire(1), Some(1));
}
#[test]
fn test_sparse_wire_map() {
let map = WireMap::from_wires(&[3, 7, 12]);
assert_eq!(map.wire_to_qubit(3).map(|q| q.0), Some(0));
assert_eq!(map.wire_to_qubit(7).map(|q| q.0), Some(1));
assert_eq!(map.wire_to_qubit(12).map(|q| q.0), Some(2));
assert_eq!(map.qubit_to_wire(0), Some(3));
}
#[test]
fn test_missing_wire() {
let map = WireMap::from_wires(&[0, 1]);
assert!(map.wire_to_qubit(99).is_none());
}
}