|
2 | 2 | pub use impl2::LapackScalar;
|
3 | 3 | pub use impl2::NormType;
|
4 | 4 |
|
| 5 | +use num_traits::Zero; |
5 | 6 | use ndarray::*;
|
6 | 7 |
|
7 | 8 | use super::types::*;
|
@@ -39,16 +40,32 @@ pub trait QR<Q, R> {
|
39 | 40 | fn qr2(self) -> Result<(Q, R)>;
|
40 | 41 | }
|
41 | 42 |
|
42 |
| -impl<A, Sq, Sr> QR<ArrayBase<Sq, Ix2>, ArrayBase<Sr, Ix2>> for ArrayBase<Sq, Ix2> |
43 |
| - where A: LapackScalar, |
44 |
| - Sq: DataMut<Elem = A>, |
45 |
| - Sr: DataOwned<Elem = A> |
| 43 | +impl<A, S, Sq, Sr> QR<ArrayBase<Sq, Ix2>, ArrayBase<Sr, Ix2>> for ArrayBase<S, Ix2> |
| 44 | + where A: LapackScalar + Copy + Zero, |
| 45 | + S: DataMut<Elem = A>, |
| 46 | + Sq: DataOwned<Elem = A> + DataMut, |
| 47 | + Sr: DataOwned<Elem = A> + DataMut |
46 | 48 | {
|
47 | 49 | fn qr2(mut self) -> Result<(ArrayBase<Sq, Ix2>, ArrayBase<Sr, Ix2>)> {
|
| 50 | + let n = self.rows(); |
| 51 | + let m = self.cols(); |
| 52 | + let k = ::std::cmp::min(n, m); |
48 | 53 | let l = self.layout()?;
|
| 54 | + // calc QR decomposition |
49 | 55 | let r = A::qr(l, self.as_allocated_mut()?)?;
|
50 |
| - let r = reconstruct(l, r)?; |
| 56 | + let r: Array2<_> = reconstruct(l, r)?; |
51 | 57 | 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 | + } |
52 | 69 | Ok((q, r))
|
53 | 70 | }
|
54 | 71 | }
|
0 commit comments