Skip to content

Commit

Permalink
Add: bits method for register.
Browse files Browse the repository at this point in the history
- Add missing traits on `BitInfo`
  • Loading branch information
raynelfss committed Dec 30, 2024
1 parent 5eda94f commit 71a586b
Show file tree
Hide file tree
Showing 2 changed files with 52 additions and 34 deletions.
5 changes: 3 additions & 2 deletions crates/circuit/src/bit.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ use pyo3::prelude::*;

use crate::register::{RegisterAsKey, RegistryIndex};

#[pyclass(name = "Qubit")]
#[pyclass(name = "Bit")]
pub struct PyBit {
reg_ref: RegisterAsKey, // Register identifier
reg_idx: u32, // Index within Register
Expand All @@ -17,10 +17,11 @@ impl PyBit {
reg_idx: index,
}
}


}

/// Keeps information about where a qubit is located within the circuit.
#[derive(Debug, Clone, Copy, Hash)]
pub struct BitInfo {
register_idx: RegistryIndex,
index: u32,
Expand Down
81 changes: 49 additions & 32 deletions crates/circuit/src/register.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ use crate::{Clbit, Qubit};
/// This represents the hash value of a Register according to the register's
/// name and number of qubits.
#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)]
pub(crate) struct RegisterAsKey(u64);
pub struct RegisterAsKey(u64);

impl RegisterAsKey {
pub fn new(name: Option<&str>, num_qubits: u32) -> Self {
Expand All @@ -30,36 +30,6 @@ impl<'py> FromPyObject<'py> for RegisterAsKey {
))
}
}

#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)]
pub(crate) struct RegistryIndex(u32);

impl From<usize> for RegistryIndex {
fn from(value: usize) -> Self {
Self(value.try_into().expect("Index falls out of range"))
}
}

impl From<u32> for RegistryIndex {
fn from(value: u32) -> Self {
Self(value)
}
}

/// Represents a collection of registers of a certain type within a circuit.
#[derive(Debug, Clone)]
pub(crate) struct CircuitRegistry<T: Register> {
registry: IndexSet<T>,
}

impl<T: Register> Index<RegistryIndex> for CircuitRegistry<T> {
type Output = T;

fn index(&self, index: RegistryIndex) -> &Self::Output {
&self.registry[index.0 as usize]
}
}

/// Described the desired behavior of a Register.
pub trait Register {
/// The type of bit stored by the [Register]
Expand All @@ -71,11 +41,13 @@ pub trait Register {
fn contains(&self, bit: Self::Bit) -> bool;
/// Finds the local index of a certain bit within [Register].
fn find_index(&self, bit: Self::Bit) -> Option<u32>;
/// Return an iterator over all the bits in the register
fn bits(&self) -> impl ExactSizeIterator<Item=Self::Bit>;
}

macro_rules! create_register {
($name:ident, $bit:ty) => {
#[derive(Debug, Clone)]
#[derive(Debug, Clone, Eq)]
pub struct $name {
register: IndexSet<<$name as Register>::Bit>,
name: Option<String>,
Expand Down Expand Up @@ -104,15 +76,60 @@ macro_rules! create_register {
fn find_index(&self, bit: Self::Bit) -> Option<u32> {
self.register.get_index_of(&bit).map(|idx| idx as u32)
}

fn bits(&self) -> impl ExactSizeIterator<Item=Self::Bit> {
self.register.iter().copied()
}
}

impl Hash for $name {
fn hash<H: Hasher>(&self, state: &mut H) {
(self.name.as_ref(), self.len()).hash(state);
}
}

impl PartialEq for $name {
fn eq(&self, other: &Self) -> bool {
self.register.len() == other.register.len() && self.name == other.name
}
}
};
}

create_register!(QuantumRegister, Qubit);
create_register!(ClassicalRegister, Clbit);

#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)]
pub struct RegistryIndex(u32);

impl From<usize> for RegistryIndex {
fn from(value: usize) -> Self {
Self(value.try_into().expect("Index falls out of range"))
}
}

impl From<u32> for RegistryIndex {
fn from(value: u32) -> Self {
Self(value)
}
}
/// Represents a collection of registers of a certain type within a circuit.
#[derive(Debug, Clone)]
pub(crate) struct CircuitRegistry<T: Register> {
registry: IndexSet<T>,
}

impl<T: Register> Index<RegistryIndex> for CircuitRegistry<T> {
type Output = T;

fn index(&self, index: RegistryIndex) -> &Self::Output {
&self.registry[index.0 as usize]
}
}

impl<T: Register + Hash + Eq> CircuitRegistry<T> {
/// Retreives the index of a register if it exists within a registry.
pub fn find_index(&self, register: &T) -> Option<RegistryIndex> {
self.registry.get_index_of(register).map(RegistryIndex::from)
}
}

0 comments on commit 71a586b

Please sign in to comment.