rqism 0.4.1

A multi-backend quantum circuit simulator
Documentation
use crate::{
    instruction::Instruction,
    sparse_mat::SMat,
    state_vector::{nq_mat_prep, sq_mat_prep},
};

/// The circuit is currently represented as a flat list of instructions, but
/// runtime optimization of circuits might require restructuring in the
/// future.
#[derive(Clone)]
pub struct Circuit<'a> {
    pub ins: Vec<Instruction<'a>>,
    pub n: usize,
}

impl<'a> Circuit<'a> {
    pub fn stitch(&self, other: &Self) -> Self {
        Self {
            ins: self.ins.iter().chain(other.ins.iter()).cloned().collect(),
            n: self.n.max(other.n),
        }
    }

    /// Consumes the circuit to convert it into a matrix. Returns None if the circuit is not
    /// composed of gates only.
    pub fn to_gate(self) -> Option<Instruction<'static>> {
        let mut mat = SMat::eye(2_u32.pow(self.n as u32));

        for i in self.ins.into_iter() {
            match i {
                Instruction::Pauli { kind, target } => {
                    let t = kind.to_matrix();
                    mat = mat.dot(&sq_mat_prep(t, target, self.n));
                }
                Instruction::Clifford { kind, target } => {
                    let v = target.to_vec();
                    let t = kind.to_matrix();

                    if v.len() != 1 {
                        mat = mat.dot(&nq_mat_prep(t, &target.to_vec(), self.n));
                    } else {
                        mat = mat.dot(&sq_mat_prep(t, v[0], self.n));
                    }
                }
                Instruction::Gate {
                    matrix, indices, ..
                } => {
                    if indices.len() != 1 {
                        mat = mat.dot(&nq_mat_prep(&matrix, &indices, self.n));
                    } else {
                        mat = mat.dot(&sq_mat_prep(&matrix, indices[0], self.n));
                    }
                }
                Instruction::Identity => {}
                _ => return None,
            }
        }

        Some(Instruction::StateVecMat {
            mat: std::borrow::Cow::Owned(mat),
        })
    }
}