Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion zixy/src/container/word_iters/_word_iters.rs
Original file line number Diff line number Diff line change
Expand Up @@ -567,7 +567,7 @@ pub mod test_defs {
}

#[cfg(test)]
pub mod tests {
mod tests {
use crate::container::quicksort::QuickSortNoCoeffs;
use rand::rngs::StdRng;
use rand::{Rng, SeedableRng};
Expand Down
2 changes: 1 addition & 1 deletion zixy/src/container/word_iters/term_set.rs
Original file line number Diff line number Diff line change
Expand Up @@ -761,7 +761,7 @@ pub mod test_defs {
}

#[cfg(test)]
pub mod tests {
mod tests {
use super::test_defs::StringCmpnts;
use crate::container::{
traits::EmptyFrom,
Expand Down
249 changes: 244 additions & 5 deletions zixy/src/qubit/traits.rs
Original file line number Diff line number Diff line change
Expand Up @@ -190,11 +190,7 @@ pub trait PauliWordRef: QubitsBased + Display {
fn get_pauli_unchecked(&self, i_mode: usize) -> PauliMatrix;
/// Return the Pauli matrix at `i_mode`, or `OutOfBounds` if `i_mode` is invalid.
fn get_pauli(&self, i_mode: usize) -> Result<PauliMatrix, OutOfBounds> {
OutOfBounds::check(
i_mode,
self.get_container().qubits().len(),
Dimension::Cmpnt,
)?;
OutOfBounds::check(i_mode, self.get_container().qubits().len(), Dimension::Mode)?;
Ok(self.get_pauli_unchecked(i_mode))
}

Expand Down Expand Up @@ -508,3 +504,246 @@ pub trait PauliWordMutRef: QubitsBased {
}
}
}

#[cfg(test)]
mod tests {
use core::fmt;

use super::*;

#[derive(Clone)]
struct TestContainer {
qubits: Qubits,
calls: Vec<&'static str>,
}

impl TestContainer {
fn new(qubits: Qubits) -> Self {
Self {
qubits,
calls: vec![],
}
}

fn new_from_count(n: usize) -> Self {
Self::new(Qubits::from_count(n))
}

fn new_from_offset(i: usize, n: usize) -> Self {
Self::new(Qubits::from_offset(i, n))
}
}

impl QubitsBased for TestContainer {
fn qubits(&self) -> &Qubits {
&self.qubits
}
}

impl proj::ToOwned for TestContainer {
type OwnedType = Self;
fn to_owned(&self) -> Self {
self.clone()
}
}

impl QubitsStandardized for TestContainer {}

impl QubitsStandardize for TestContainer {
fn general_standardize(&mut self, n_qubit: usize) {
self.calls.push("general");
self.qubits = Qubits::from_count(n_qubit);
}

fn resize_standardize(&mut self, n_qubit: usize) {
self.calls.push("resize");
self.qubits = Qubits::from_count(n_qubit);
}
}

impl QubitsRelabel for TestContainer {
fn qubits_mut(&mut self) -> &mut Qubits {
&mut self.qubits
}
}

struct TestPauliWord {
qubits: Qubits,
paulis: Vec<PauliMatrix>,
}

impl TestPauliWord {
fn new(paulis: Vec<PauliMatrix>) -> Self {
Self {
qubits: Qubits::from_count(paulis.len()),
paulis,
}
}
}

impl QubitsBased for TestPauliWord {
fn qubits(&self) -> &Qubits {
&self.qubits
}
}

impl PauliWordMutRef for TestPauliWord {
fn set_pauli_unchecked(&mut self, i_mode: usize, pauli: PauliMatrix) {
self.paulis[i_mode] = pauli;
}

fn get_pauli_unchecked(&self, i_mode: usize) -> PauliMatrix {
self.paulis[i_mode]
}
}

impl fmt::Display for TestPauliWord {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
write!(
f,
"TestPauliWord with qubits {:?} and paulis {:?}",
self.qubits, self.paulis
)
}
}

impl PauliWordRef for TestPauliWord {
type T = Self;
fn get_container(&self) -> &Self::T {
self
}

fn get_pauli_unchecked(&self, i_mode: usize) -> PauliMatrix {
self.paulis[i_mode]
}

fn count(&self, pauli: PauliMatrix) -> usize {
self.paulis.iter().filter(|&&p| p == pauli).count()
}
}

#[test]
fn test_standardize_calls() {
let mut test = TestContainer::new_from_count(2);

test.standardize(5);
assert_eq!(test.calls, vec!["resize"]);
assert_eq!(test.qubits, Qubits::from_count(5));
}

#[test]
fn test_standardize_uses_general() {
let mut test = TestContainer::new_from_offset(2, 3);

test.standardize(3);
assert_eq!(test.calls, vec!["general"]);
assert_eq!(test.qubits, Qubits::from_count(3));
}

#[test]
fn test_standardize_no_op() {
let mut test = TestContainer::new_from_count(3);

test.standardize(3);
assert!(test.calls.is_empty());
assert_eq!(test.qubits, Qubits::from_count(3));
}

#[test]
fn test_general_standardized() {
let test = TestContainer::new_from_count(3);

let standardized = test.general_standardized(4);
assert!(test.calls.is_empty());
assert_eq!(standardized.calls, vec!["general"]);
assert_eq!(standardized.qubits, Qubits::from_count(4));
}

#[test]
fn test_resize_standardized() {
let test = TestContainer::new_from_count(3);
let standardized = test.resize_standardized(2);
assert!(test.calls.is_empty());
assert_eq!(standardized.calls, vec!["resize"]);
assert_eq!(standardized.qubits, Qubits::from_count(2));
assert_eq!(test.qubits, Qubits::from_count(3));
}

#[test]
fn test_push_standardized() {
let test = TestContainer::new_from_count(3);
let standardized = test.push_standardized();
assert!(test.calls.is_empty());
assert_eq!(standardized.calls, vec!["resize"]);
assert_eq!(standardized.qubits, Qubits::from_count(4));
assert_eq!(test.qubits, Qubits::from_count(3));
}

#[test]
fn test_relabelled() -> Result<(), BasisError> {
let mut test = TestContainer::new_from_count(3);
test.relabel(Qubits::from_offset(4, 3))?;
assert_eq!(test.qubits, Qubits::from_offset(4, 3));
Ok(())
}

#[test]
fn test_relabel_invalid() {
let mut test = TestContainer::new_from_count(3);
let result = test.relabel(Qubits::from_count(4));
assert!(matches!(result, Err(BasisError::Counts(_))));
assert_eq!(test.qubits, Qubits::from_count(3));
}

#[test]
fn test_pauliword_clear() {
let mut test = TestPauliWord::new(vec![
PauliMatrix::X,
PauliMatrix::Y,
PauliMatrix::Z,
PauliMatrix::I,
]);
test.clear();
assert_eq!(test.paulis, vec![PauliMatrix::I; 4]);
}

#[test]
fn test_pauliword_map() {
let test = TestPauliWord::new(vec![
PauliMatrix::X,
PauliMatrix::Y,
PauliMatrix::I,
PauliMatrix::X,
PauliMatrix::I,
]);
let map = test.get_pauli_map();
assert_eq!(map.len(), 3);
assert_eq!(map[&0], PauliMatrix::X);
assert_eq!(map[&3], PauliMatrix::X);
assert_eq!(map[&1], PauliMatrix::Y);
}

#[test]
fn test_setpaulimap() -> Result<(), OutOfBounds> {
let mut test = TestPauliWord::new(vec![PauliMatrix::I; 3]);
let mut map = HashMap::new();
map.insert(1, PauliMatrix::X);
map.insert(2, PauliMatrix::Y);
test.set_pauli_map(map)?;
assert_eq!(
test.paulis,
vec![PauliMatrix::I, PauliMatrix::X, PauliMatrix::Y]
);
Ok(())
}

#[test]
fn test_setpaulimap_invalid() {
let mut test = TestPauliWord::new(vec![PauliMatrix::I; 3]);
let mut map = HashMap::new();
map.insert(100, PauliMatrix::Y); // invalid for word of length 3
let result = test.set_pauli_map(map);
assert!(result.is_err());
assert_eq!(test.paulis, vec![PauliMatrix::I; 3]);
}
}
Loading