Repository: commons-math
Updated Branches:
  refs/heads/master 093e3bb2e -> c440f668a


MATH-1210

Improved error reporting.


Project: http://git-wip-us.apache.org/repos/asf/commons-math/repo
Commit: http://git-wip-us.apache.org/repos/asf/commons-math/commit/c440f668
Tree: http://git-wip-us.apache.org/repos/asf/commons-math/tree/c440f668
Diff: http://git-wip-us.apache.org/repos/asf/commons-math/diff/c440f668

Branch: refs/heads/master
Commit: c440f668aca99266b5379235f6d99d378630c938
Parents: 093e3bb
Author: Gilles <[email protected]>
Authored: Wed Mar 18 16:57:16 2015 +0100
Committer: Gilles <[email protected]>
Committed: Wed Mar 18 16:57:16 2015 +0100

----------------------------------------------------------------------
 src/changes/changes.xml                         |  4 ++
 .../commons/math4/linear/QRDecomposition.java   | 48 +++++++++++++++-----
 2 files changed, 40 insertions(+), 12 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/commons-math/blob/c440f668/src/changes/changes.xml
----------------------------------------------------------------------
diff --git a/src/changes/changes.xml b/src/changes/changes.xml
index f3cf214..485458b 100644
--- a/src/changes/changes.xml
+++ b/src/changes/changes.xml
@@ -54,6 +54,10 @@ If the output is not quite correct, check for invisible 
trailing spaces!
     </release>
 
     <release version="4.0" date="XXXX-XX-XX" description="">
+      <action dev="erans" type="update" issue="MATH-1210">
+        "QRDecomposition": include information about the condition that
+        triggers a "SingularMatrixException".
+      </action>
       <action dev="tn" type="fix" issue="MATH-1209" due-to="Jonathan Ogilvie">
         Fixed link to algorithm description in "PoissonDistribution#sample()".
       </action>

http://git-wip-us.apache.org/repos/asf/commons-math/blob/c440f668/src/main/java/org/apache/commons/math4/linear/QRDecomposition.java
----------------------------------------------------------------------
diff --git a/src/main/java/org/apache/commons/math4/linear/QRDecomposition.java 
b/src/main/java/org/apache/commons/math4/linear/QRDecomposition.java
index 02ac7e9..d96bb45 100644
--- a/src/main/java/org/apache/commons/math4/linear/QRDecomposition.java
+++ b/src/main/java/org/apache/commons/math4/linear/QRDecomposition.java
@@ -21,6 +21,7 @@ import java.util.Arrays;
 
 import org.apache.commons.math4.exception.DimensionMismatchException;
 import org.apache.commons.math4.util.FastMath;
+import org.apache.commons.math4.exception.util.LocalizedFormats;
 
 
 /**
@@ -335,12 +336,7 @@ public class QRDecomposition {
 
         /** {@inheritDoc} */
         public boolean isNonSingular() {
-            for (double diag : rDiag) {
-                if (FastMath.abs(diag) <= threshold) {
-                    return false;
-                }
-            }
-            return true;
+            return !checkSingular(rDiag, threshold, false);
         }
 
         /** {@inheritDoc} */
@@ -350,9 +346,7 @@ public class QRDecomposition {
             if (b.getDimension() != m) {
                 throw new DimensionMismatchException(b.getDimension(), m);
             }
-            if (!isNonSingular()) {
-                throw new SingularMatrixException();
-            }
+            checkSingular(rDiag, threshold, true);
 
             final double[] x = new double[n];
             final double[] y = b.toArray();
@@ -393,9 +387,7 @@ public class QRDecomposition {
             if (b.getRowDimension() != m) {
                 throw new DimensionMismatchException(b.getRowDimension(), m);
             }
-            if (!isNonSingular()) {
-                throw new SingularMatrixException();
-            }
+            checkSingular(rDiag, threshold, true);
 
             final int columns        = b.getColumnDimension();
             final int blockSize      = BlockRealMatrix.BLOCK_SIZE;
@@ -472,5 +464,37 @@ public class QRDecomposition {
         public RealMatrix getInverse() {
             return solve(MatrixUtils.createRealIdentityMatrix(qrt[0].length));
         }
+
+        /**
+         * Check singularity.
+         *
+         * @param diag Diagonal elements of the R matrix.
+         * @param min Singularity threshold.
+         * @param raise Whether to raise a {@link SingularMatrixException}
+         * if any element of the diagonal fails the check.
+         * @return {@code true} if any element of the diagonal is smaller
+         * or equal to {@code min}.
+         * @throws SingularMatrixException if the matrix is singular and
+         * {@code raise} is {@code true}.
+         */
+        private static boolean checkSingular(double[] diag,
+                                             double min,
+                                             boolean raise) {
+            final int len = diag.length;
+            for (int i = 0; i < len; i++) {
+                final double d = diag[i];
+                if (FastMath.abs(d) <= min) {
+                    if (raise) {
+                        final SingularMatrixException e = new 
SingularMatrixException();
+                        
e.getContext().addMessage(LocalizedFormats.NUMBER_TOO_SMALL, d, min);
+                        e.getContext().addMessage(LocalizedFormats.INDEX, i);
+                        throw e;
+                    } else {
+                        return true;
+                    }
+                }
+            }
+            return false;
+        }
     }
 }

Reply via email to