rqism 0.4.1

A multi-backend quantum circuit simulator
Documentation
use ndarray::{Array2, ArrayBase, Data, DataMut, Ix2, RawDataClone};
use num::Complex;

#[derive(Clone)]
pub struct QRDecomp {
    pub q: Array2<Complex<f32>>,
    pub r: Array2<Complex<f32>>,
}

impl QRDecomp {
    pub fn new<S: Data<Elem = Complex<f32>> + RawDataClone + DataMut<Elem = Complex<f32>>>(
        a: &ArrayBase<S, Ix2>,
    ) -> Option<Self> {
        let s = a.shape();
        let (m, n) = (s[0], s[1]);

        let mut q = Array2::zeros((m, n));
        let mut r = Array2::zeros((n, n));

        for j in 0..n {
            let mut v = a.row(j).to_owned();

            for i in 0..j {
                *r.get_mut((i, j)).unwrap() = q.row(i).dot(&v);
                v = v - (*r.get((i, j)).unwrap() * q.row(i).to_owned());
            }

            *r.get_mut((j, j)).unwrap() = v.iter().map(|x| x.powu(2)).sum::<Complex<f32>>().sqrt();
            q.row_mut(j)
                .iter_mut()
                .enumerate()
                .for_each(|(i, x)| *x = *v.get(i).unwrap() / *r.get((j, j)).unwrap());
        }

        Some(Self { q, r })
    }

    pub fn to_tuple(self) -> (Array2<Complex<f32>>, Array2<Complex<f32>>) {
        (self.q, self.r)
    }
}