1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
use matrix::{Matrix, MatrixSlice, BaseMatrix};
use error::{Error, ErrorKind};
use std::any::Any;
use libnum::Float;
impl<T> Matrix<T>
where T: Any + Float
{
pub fn qr_decomp(self) -> Result<(Matrix<T>, Matrix<T>), Error> {
let m = self.rows();
let n = self.cols();
let mut q = Matrix::<T>::identity(m);
let mut r = self;
for i in 0..(n - ((m == n) as usize)) {
let holder_transform: Result<Matrix<T>, Error>;
{
let lower_slice = MatrixSlice::from_matrix(&r, [i, i], m - i, 1);
holder_transform =
Matrix::make_householder(&lower_slice.iter().cloned().collect::<Vec<_>>());
}
if !holder_transform.is_ok() {
return Err(Error::new(ErrorKind::DecompFailure,
"Cannot compute QR decomposition."));
} else {
let mut holder_data = holder_transform.unwrap().into_vec();
let mut h_full_data = Vec::with_capacity(m * m);
for j in 0..m {
let mut row_data: Vec<T>;
if j < i {
row_data = vec![T::zero(); m];
row_data[j] = T::one();
h_full_data.extend(row_data);
} else {
row_data = vec![T::zero(); i];
h_full_data.extend(row_data);
h_full_data.extend(holder_data.drain(..m - i));
}
}
let h = Matrix::new(m, m, h_full_data);
q = q * &h;
r = h * &r;
}
}
Ok((q, r))
}
}