use crate::{
instruction::Instruction,
sparse_mat::SMat,
state_vector::{nq_mat_prep, sq_mat_prep},
};
#[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),
}
}
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),
})
}
}