Skip to content

Commit a17ec9d

Browse files
committed
Split slice
1 parent 0a6f959 commit a17ec9d

File tree

1 file changed

+54
-13
lines changed

1 file changed

+54
-13
lines changed

src/traits.rs

Lines changed: 54 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -45,27 +45,68 @@ impl<A, S, Sq, Sr> QR<ArrayBase<Sq, Ix2>, ArrayBase<Sr, Ix2>> for ArrayBase<S, I
4545
S: DataMut<Elem = A>,
4646
Sq: DataOwned<Elem = A> + DataMut,
4747
Sr: DataOwned<Elem = A> + DataMut
48+
{
49+
fn qr(mut self) -> Result<(ArrayBase<Sq, Ix2>, ArrayBase<Sr, Ix2>)> {
50+
(&mut self).qr()
51+
}
52+
}
53+
54+
fn take_slice<A, S1, S2>(a: &ArrayBase<S1, Ix2>, n: usize, m: usize) -> ArrayBase<S2, Ix2>
55+
where A: Copy,
56+
S1: Data<Elem = A>,
57+
S2: DataMut<Elem = A> + DataOwned
58+
{
59+
let av = a.slice(s![..n as isize, ..m as isize]);
60+
let mut a = unsafe { ArrayBase::uninitialized((n, m)) };
61+
a.assign(&av);
62+
a
63+
}
64+
65+
fn take_slice_upper<A, S1, S2>(a: &ArrayBase<S1, Ix2>, n: usize, m: usize) -> ArrayBase<S2, Ix2>
66+
where A: Copy + Zero,
67+
S1: Data<Elem = A>,
68+
S2: DataMut<Elem = A> + DataOwned
69+
{
70+
let av = a.slice(s![..n as isize, ..m as isize]);
71+
let mut a = unsafe { ArrayBase::uninitialized((n, m)) };
72+
for ((i, j), val) in a.indexed_iter_mut() {
73+
*val = if i <= j { av[(i, j)] } else { A::zero() };
74+
}
75+
a
76+
}
77+
78+
impl<'a, A, S, Sq, Sr> QR<ArrayBase<Sq, Ix2>, ArrayBase<Sr, Ix2>> for &'a mut ArrayBase<S, Ix2>
79+
where A: LapackScalar + Copy + Zero,
80+
S: DataMut<Elem = A>,
81+
Sq: DataOwned<Elem = A> + DataMut,
82+
Sr: DataOwned<Elem = A> + DataMut
4883
{
4984
fn qr(mut self) -> Result<(ArrayBase<Sq, Ix2>, ArrayBase<Sr, Ix2>)> {
5085
let n = self.rows();
5186
let m = self.cols();
5287
let k = ::std::cmp::min(n, m);
5388
let l = self.layout()?;
54-
// calc QR decomposition
5589
let r = A::qr(l, self.as_allocated_mut()?)?;
5690
let r: Array2<_> = reconstruct(l, r)?;
5791
let q = self;
58-
// get slice
59-
let qv = q.slice(s![..n as isize, ..k as isize]);
60-
let mut q = unsafe { ArrayBase::uninitialized((n, k)) };
61-
q.assign(&qv);
62-
let rv = r.slice(s![..k as isize, ..m as isize]);
63-
let mut r = ArrayBase::zeros((k, m));
64-
for ((i, j), val) in r.indexed_iter_mut() {
65-
if i <= j {
66-
*val = rv[(i, j)];
67-
}
68-
}
69-
Ok((q, r))
92+
Ok((take_slice(q, n, k), take_slice_upper(&r, k, m)))
93+
}
94+
}
95+
96+
impl<'a, A, S, Sq, Sr> QR<ArrayBase<Sq, Ix2>, ArrayBase<Sr, Ix2>> for &'a ArrayBase<S, Ix2>
97+
where A: LapackScalar + Copy + Zero,
98+
S: Data<Elem = A>,
99+
Sq: DataOwned<Elem = A> + DataMut,
100+
Sr: DataOwned<Elem = A> + DataMut
101+
{
102+
fn qr(self) -> Result<(ArrayBase<Sq, Ix2>, ArrayBase<Sr, Ix2>)> {
103+
let n = self.rows();
104+
let m = self.cols();
105+
let k = ::std::cmp::min(n, m);
106+
let l = self.layout()?;
107+
let mut q = self.to_owned();
108+
let r = A::qr(l, q.as_allocated_mut()?)?;
109+
let r: Array2<_> = reconstruct(l, r)?;
110+
Ok((take_slice(&q, n, k), take_slice_upper(&r, k, m)))
70111
}
71112
}

0 commit comments

Comments
 (0)