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
use crate::matrix::Matrix;
impl Matrix {
pub fn posvcgm(self, constants: Matrix) -> Result<Matrix, String> {
if self.rows != constants.rows || constants.columns != 1 {
return Err("dimension mismatch".to_owned());
}
let mut x = Matrix::zeros(constants.rows, 1);
let mut r = constants;
let mut p = r.clone();
loop {
let r_t = r.t();
let a_p = &self * &p;
let alpha = (&r_t * &p)[0][0] / (p.t() * &a_p)[0][0];
let old_r = r.clone();
x = x + p.clone() * alpha;
r = r - a_p.clone() * alpha;
let max_r = r.elements.iter().fold(0.0 / 0.0, |m, v| v.max(m));
if max_r < 0.001 {
break;
}
let beta = (r.t() * &r)[0][0] / (&r_t * &old_r)[0][0];
p = r.clone() + p.clone() * beta;
}
Ok(x)
}
}