Author: psteitz Date: Sat Aug 13 06:20:12 2011 New Revision: 1157336 URL: http://svn.apache.org/viewvc?rev=1157336&view=rev Log: Made pseudo-inverse consistent with rank computation in SingularValueDecompositionImpl. JIRA: MATH-601 Reported by Chris Nix Patched by Chris Nix and Greg Sterijevxki
Modified: commons/proper/math/trunk/src/main/java/org/apache/commons/math/linear/SingularValueDecompositionImpl.java commons/proper/math/trunk/src/site/xdoc/changes.xml Modified: commons/proper/math/trunk/src/main/java/org/apache/commons/math/linear/SingularValueDecompositionImpl.java URL: http://svn.apache.org/viewvc/commons/proper/math/trunk/src/main/java/org/apache/commons/math/linear/SingularValueDecompositionImpl.java?rev=1157336&r1=1157335&r2=1157336&view=diff ============================================================================== --- commons/proper/math/trunk/src/main/java/org/apache/commons/math/linear/SingularValueDecompositionImpl.java (original) +++ commons/proper/math/trunk/src/main/java/org/apache/commons/math/linear/SingularValueDecompositionImpl.java Sat Aug 13 06:20:12 2011 @@ -19,6 +19,7 @@ package org.apache.commons.math.linear; import org.apache.commons.math.exception.NumberIsTooLargeException; import org.apache.commons.math.exception.util.LocalizedFormats; import org.apache.commons.math.util.FastMath; +import org.apache.commons.math.util.MathUtils; /** * Calculates the compact Singular Value Decomposition of a matrix. @@ -56,6 +57,8 @@ public class SingularValueDecompositionI private final RealMatrix cachedV; /** Cached value of transposed V matrix. */ private RealMatrix cachedVt; + /** Tolerance value for small singular values, calculated once we have populated singularValues **/ + private final double tol; /** * Calculates the compact Singular Value Decomposition of the given matrix. @@ -77,7 +80,7 @@ public class SingularValueDecompositionI m = matrix.getRowDimension(); n = matrix.getColumnDimension(); } - + singularValues = new double[n]; final double[][] U = new double[m][n]; final double[][] V = new double[n][n]; @@ -442,6 +445,10 @@ public class SingularValueDecompositionI } } + // Set the small value tolerance used to calculate rank and pseudo-inverse + tol = FastMath.max(FastMath.max(m, n) * singularValues[0] * EPS, + FastMath.sqrt( MathUtils.SAFE_MIN)); + if (!transposed) { cachedU = MatrixUtils.createRealMatrix(U); cachedV = MatrixUtils.createRealMatrix(V); @@ -537,7 +544,6 @@ public class SingularValueDecompositionI /** {@inheritDoc} */ public int getRank() { - final double tol = m * singularValues[0] * EPS; int r = 0; for (int i = 0; i < singularValues.length; i++) { if (singularValues[i] > tol) { @@ -549,7 +555,7 @@ public class SingularValueDecompositionI /** {@inheritDoc} */ public DecompositionSolver getSolver() { - return new Solver(singularValues, getUT(), getV(), getRank() == m); + return new Solver(singularValues, getUT(), getV(), getRank() == m, tol); } /** Specialized solver. */ @@ -566,13 +572,14 @@ public class SingularValueDecompositionI * @param uT U<sup>T</sup> matrix of the decomposition. * @param v V matrix of the decomposition. * @param nonSingular Singularity indicator. + * @param tol tolerance for singular values */ private Solver(final double[] singularValues, final RealMatrix uT, - final RealMatrix v, final boolean nonSingular) { + final RealMatrix v, final boolean nonSingular, final double tol) { final double[][] suT = uT.getData(); for (int i = 0; i < singularValues.length; ++i) { final double a; - if (singularValues[i] > 0) { + if (singularValues[i] > tol) { a = 1 / singularValues[i]; } else { a = 0; Modified: commons/proper/math/trunk/src/site/xdoc/changes.xml URL: http://svn.apache.org/viewvc/commons/proper/math/trunk/src/site/xdoc/changes.xml?rev=1157336&r1=1157335&r2=1157336&view=diff ============================================================================== --- commons/proper/math/trunk/src/site/xdoc/changes.xml (original) +++ commons/proper/math/trunk/src/site/xdoc/changes.xml Sat Aug 13 06:20:12 2011 @@ -52,6 +52,9 @@ The <action> type attribute can be add,u If the output is not quite correct, check for invisible trailing spaces! --> <release version="3.0" date="TBD" description="TBD"> + <action dev="psteitz" type="fix" issue="MATH-601" due-to="Chris Nix and Greg Serijevski"> + Made pseudo-inverse consistent with rank computation in SingularValueDecompositionImpl. + </action> <action dev="psteitz" type="update" issue="MATH-624" due-to="Greg Sterijevski"> Added methods to solve upper and lower triangular systems to MatrixUtils. </action>