rqism 0.3.4

A multi-backend quantum circuit simulator
Documentation
use crate::sparse_mat::SMat;
use num::Complex;

/// A sparse quantum state that stores only non-zero components of the state.
/// Now, it is a thin wrapper around sparse_mat::SMat.
#[derive(Debug, Clone)]
pub struct SQS {
    pub mat: SMat,
    pub n: u32,
}

impl SQS {
    pub fn new(n: u32) -> Self {
        let mat = SMat::zeros((1, n));

        Self { mat, n }
    }

    pub fn set(&self, i: u32, v: Complex<f32>) {
        if i > self.n {
            panic!(
                "attempting to set value at index {} but length is {}",
                i, self.n
            );
        }

        self.mat.set_unchecked(1, i, v);
    }

    pub fn get(&self, i: u32) -> Complex<f32> {
        if i > self.n {
            panic!(
                "attempting to get value at index {} but length is {}",
                i, self.n
            );
        }

        self.mat.get_unchecked(1, i)
    }

    pub fn dot(&self, rhs: &SMat) -> Self {
        Self {
            mat: self.mat.dot(rhs),
            n: self.n,
        }
    }

    pub fn to_vec(&self) -> Vec<Complex<f32>> {
        (0..self.n).map(|x| self.get(x)).collect()
    }

    pub fn fill_zero(&mut self) {
        *self = Self::new(self.n);
    }

    pub fn iter(&self) -> SQSIterator {
        SQSIterator { sqs: self, n: 0 }
    }
}

/// iterator over a sparse quantum state
pub struct SQSIterator<'a> {
    sqs: &'a SQS,
    n: u32,
}

impl Iterator for SQSIterator<'_> {
    type Item = Complex<f32>;

    fn next(&mut self) -> Option<Self::Item> {
        if self.n >= self.sqs.n {
            return None;
        }

        let r = Some(self.sqs.get(self.n));

        self.n += 1;

        r
    }
}

// not sure if this implementation is proper, but it works without UB
unsafe impl Send for SQS {}
unsafe impl Sync for SQS {}