[ 
https://issues.apache.org/jira/browse/MATH-465?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=13054046#comment-13054046
 ] 

greg sterijevski commented on MATH-465:
---------------------------------------

My apologies if I am missing something, but here is what I noticed about the 
SVD. 

On lines 124-127 of SingularValueDecompositionImpl we have:

        for (int i = 0; i < p; i++) {
            singularValues[i] = FastMath.sqrt(FastMath.abs(singularValues[i]));
        }

This is potentially the offending line. First is the problem of negative 
eigenvalues. Negative variance in the principal components should probably be 
dealt with explicitly? Perhaps by throwing a MathException? Second, and the 
issue which this bug report deals with, is taking a square root of a very small 
number (<1) will return a larger number. If you apply the threshold test in 
getRank() (final double threshold = FastMath.max(m, n) * 
FastMath.ulp(singularValues[0]) )  prior to taking the square root, I believe 
this problem would be resolved. More importantly, philosophically, you test for 
zero variance. This is the appropriate test.

Also, rank could be precalculated in the above loop. 

> Incorrect matrix rank via SVD
> -----------------------------
>
>                 Key: MATH-465
>                 URL: https://issues.apache.org/jira/browse/MATH-465
>             Project: Commons Math
>          Issue Type: Bug
>    Affects Versions: 2.1
>         Environment: Windows XP Prof. Vs. 2002
>            Reporter: Marisa Thoma
>             Fix For: 3.0
>
>
> The getRank() function of SingularValueDecompositionImpl does not work 
> properly. This problem is probably related to the numerical stability 
> problems mentioned in 
> [MATH-327|https://issues.apache.org/jira/browse/MATH-327] and 
> [MATH-320|https://issues.apache.org/jira/browse/MATH-320].
> Example call with the standard matrix from R (rank 2):
> {code:title=TestSVDRank.java}
> import org.apache.commons.math.linear.Array2DRowRealMatrix;
> import org.apache.commons.math.linear.RealMatrix;
> import org.apache.commons.math.linear.SingularValueDecomposition;
> import org.apache.commons.math.linear.SingularValueDecompositionImpl;
> public class TestSVDRank {
>       public static void main(String[] args) {
>               double[][] d = { { 1, 1, 1 }, { 0, 0, 0 }, { 1, 2, 3 } };
>               RealMatrix m = new Array2DRowRealMatrix(d);
>               SingularValueDecomposition svd = new 
> SingularValueDecompositionImpl(m);
>               int r = svd.getRank();
>               System.out.println("Rank: "+r);
>       }
> }
> {code} 
> The rank is computed as 3. This problem also occurs for larger matrices. I 
> discovered the problem when trying to replace the corresponding JAMA method.

--
This message is automatically generated by JIRA.
For more information on JIRA, see: http://www.atlassian.com/software/jira

        

Reply via email to