yanyankangkang / efficient-java-matrix-library

Automatically exported from code.google.com/p/efficient-java-matrix-library
0 stars 0 forks source link

SolvePseudoInverse invert method returns zero #19

Closed GoogleCodeExporter closed 9 years ago

GoogleCodeExporter commented 9 years ago
What steps will reproduce the problem?
1. SolvePseudoInverse pinv = new SolvePseudoInverse();
2. pinv.setA(any input DenseMatrix64F);
3. pinv.invert(any output DenseMatrix64F);

What is the expected output? What do you see instead?
Expected: pseudo-inverse of the input matrix.
Obtained: zero matrix.

What version of the product are you using? On what operating system?
v0.17, Windows 7 64 bits

Please provide any additional information below.

Original issue reported on code.google.com by mwolff...@gmail.com on 27 Oct 2011 at 6:47

GoogleCodeExporter commented 9 years ago
Could you post a small code example showing this problem? I'm not able to 
reproduce your problem on my computer.

Original comment by peter.ab...@gmail.com on 27 Oct 2011 at 1:51

GoogleCodeExporter commented 9 years ago
I have been able to reproduce the problem with the following example:

double[][] dataA = { {1.0, 2.0, 3.0}, {4.0, 5.0, 6.0} };
DenseMatrix64F A = new DenseMatrix64F(dataA);
DenseMatrix64F B = new DenseMatrix64F(A.numCols, A.numRows);
SolvePseudoInverse pinv = new SolvePseudoInverse();
pinv.setA(A);
pinv.invert(B);
System.out.println(B.toString());

Original comment by mwolff...@gmail.com on 27 Oct 2011 at 2:05

GoogleCodeExporter commented 9 years ago
Found the problem.

if you change:
pinv.setA(A)
to:
if( !pinv.setA(A) )
  throw new IllegalArgumentException("It failed!");

you will see that it is failing.  This pseudo inverse is computed by 
inv(A^T*A)*A but it turns out that inv(A^T*A) in your example is a singular 
matrix.  So instead of returning garbage it is failing.

Try using this matrix instead:
double[][] dataA = { {1.0, 2.0, 3.0}, {4.0, 5.0, 20.0} };

to get the following output.

Type = dense , numRows = 3 , numCols = 2
-0.438   0.000  
 0.906  -0.375  
-0.164  -0.031

Original comment by peter.ab...@gmail.com on 27 Oct 2011 at 2:27

GoogleCodeExporter commented 9 years ago
OK, I hadn't seen that the error code is returned by the setA method.

Actually, I would have expected a different behaviour since the pseudo
inverse theoretically exists for any matrix.
In the case of the [[1 2 3], [4 5 6 ]] matrix, MATLAB returns for example
the following output.

   -0.9444    0.4444
   -0.1111    0.1111
    0.7222   -0.2222

Original comment by mwolff...@gmail.com on 27 Oct 2011 at 2:40

GoogleCodeExporter commented 9 years ago
Yeah I got the same output in octave.  I did a quick search to see if I missed 
something and there are a few ways to implement pseudo inverse.  To make a 
really robust version requires using SVD, By the definition of Moore-Penrose 
pseudoinverse on wikipedia it should never fail, so I'll add this to the TODO 
list and make a new unit test to catch this problem.  Matlab used the SVD 
technique in its pinv() function.

Original comment by peter.ab...@gmail.com on 27 Oct 2011 at 2:58

GoogleCodeExporter commented 9 years ago
well I felt like procrastinating so I already change the class's behavior.  Try 
updating from the SVN code and you should get the same output as matlab now.

Original comment by peter.ab...@gmail.com on 27 Oct 2011 at 3:51

GoogleCodeExporter commented 9 years ago
Great, I will test it today. Thanks a lot!

Original comment by mwolff...@gmail.com on 28 Oct 2011 at 6:07

GoogleCodeExporter commented 9 years ago
I'm assuming everything works now as advertised.  Closing the issue.

Original comment by peter.ab...@gmail.com on 16 Nov 2011 at 2:54