[ 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