I was trying to port some code to Rust that required computing the pseudo-inverse of a matrix and had to realize that rulinalg currently does not provide such functionality.
According to Wikipedia the pseudo-inverse of a matrix can be implemented using singular value decomposition (SVD), which is already available in rulinalg.
I found some Coffeescript impl (for complex matrices) on Github:
cpinv = (A) ->
{U, S, V} = csvd A
tol = max(size(A))*nm.epsilon*S[0]
Z = ((if x>tol then 1/x else 0) for x in S)
V.dot(nm.diag(Z)).dot(U.transjugate())
Attempting to port the code to rulinalg (stripping it down to work with plain old real values), I got stuck at the use of dot in the last line:
impl<T: Any + Float + Signed + FromPrimitive> Matrix<T> {
pub fn pseudo_inverse(self) -> Result<Matrix<T>, Error> {
self.svd().map(|(s, u, v)| {
let max = T::from_usize(::std::cmp::max(self.cols(), self.rows())).unwrap();
let s_zero = s.get_unchecked([0, 0]).clone();
let epsilon = max * T::epsilon() * s_zero;
let z = s.diag().apply(&|x| if x > epsilon { T::one() / x } else { T::zero() });
v.dot(z).dot(u.transpose())
})
}
}
Any idea how the use of dot would translate to rulinalg (or if I'm on the right track to begin with)?
I was trying to port some code to Rust that required computing the pseudo-inverse of a matrix and had to realize that rulinalg currently does not provide such functionality.
According to Wikipedia the pseudo-inverse of a matrix can be implemented using singular value decomposition (SVD), which is already available in rulinalg.
I found some Coffeescript impl (for complex matrices) on Github:
Attempting to port the code to rulinalg (stripping it down to work with plain old real values), I got stuck at the use of
dotin the last line:Any idea how the use of
dotwould translate to rulinalg (or if I'm on the right track to begin with)?