fn lu_inv(&self) -> Option<Self> {
let d = self.raw_dim();
assert!(d[0] == d[1]);
if let Some((l, u, p)) = self.lu() {
let lt = l.lt_inv()?;
let ut = u.ut_inv()?;
Some(ut.dot(<).dot(&p))
} else {
None
}
}
fn lt_inv(&self) -> Option<Self> {
let d = self.raw_dim();
assert!(d[0] == d[1]);
let n = d[0];
let mut m: Array2<T> = Array2::zeros((n, n));
for i in 0 .. n {
if self[(i, i)].is_zero() {
return None;
}
m[(i, i)] = self[(i, i)].recip();
for j in 0 .. i {
for k in j .. i {
m[(i, j)] = m[(i, j)] + self[(i, k)] * m[(k, j)];
}
m[(i, j)] = -m[(i, j)] / self[(i, i)];
}
}
Some(m)
}
fn ut_inv(&self) -> Option<Self> {
Some(self.lt_inv()?.t().to_owned().t().to_owned())
}