According to this code. It can finding the pseudo-inverse by using Apache Commons Math library.
RealMatrix Swinv = new LUDecomposition(Sw).getSolver().getInverse(); // MATLAB: Swinv = pinv(Sw)
But even if Sw
is square, I can get the exception org.apache.commons.math3.linear.SingularMatrixException:
And according to the documentation, this getInverse()
is pseudo-inverse.
Get the pseudo-inverse of the decomposed matrix.
This is equal to the inverse of the decomposed matrix, if such an inverse exists.
If no such inverse exists, then the result has properties that resemble that of an inverse.
In particular, in this case, if the decomposed matrix is A, then the system of equations ( A x = b ) may have no solutions, or many. If it has no solutions, then the pseudo-inverse ( A^+ ) gives the "closest" solution ( z = A^+ b ), meaning ( \left \| A z - b \right \|_2 ) is minimized. If there are many solutions, then ( z = A^+ b ) is the smallest solution, meaning ( \left \| z \right \|_2 ) is minimized.
So what should I do here? I want to find the pseudo-inverse. But I still got an error because Sw
is singular.
So I'm not sure where you got the idea that the solver from the LUDecomposition
yields the pseudoinverse. In fact if you look at the code, you can see that this only works if a solution exists "in exact linear sense".
Instead, you should first create a SingularValueDecomposition
with
SingularValueDecomposition svd = new SingularValueDecomposition(A);
Then get the Decomposition solver that this Singular Value Decomposition creates,
DecompositionSolver solver = svd.getSolver();
Then you can either:
RealMatrix pinv = solver.getInverse();
RealVector x = decompositionSolver.solve(b);
RealMatrix X = decompositionSolver.solve(B);