javamatrixapache-commonsmatrix-inverseapache-commons-math

How do I find the pseudo-inverse from Apache Commons Math - Java library


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.


Solution

  • 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:

    1. Get the pseudo inverse with
    RealMatrix pinv = solver.getInverse();
    
    1. or use it to solve a system of equations like Ax = b
    RealVector x = decompositionSolver.solve(b);
    
    1. or use it to solve a matrix system of equations like Ax = B
    RealMatrix X = decompositionSolver.solve(B);