diff --git a/src/main/java/org/apache/commons/math3/linear/EigenDecomposition.java b/src/main/java/org/apache/commons/math3/linear/EigenDecomposition.java index 4d4d794a2..2bb8fd754 100644 --- a/src/main/java/org/apache/commons/math3/linear/EigenDecomposition.java +++ b/src/main/java/org/apache/commons/math3/linear/EigenDecomposition.java @@ -513,8 +513,12 @@ public class EigenDecomposition { * @return true if the decomposed matrix is non-singular. */ public boolean isNonSingular() { - // The eigenvalues are sorted by size, descending - double largestEigenvalueNorm = eigenvalueNorm(0); + double largestEigenvalueNorm = 0.0; + // Looping over all values (in case they are not sorted in decreasing + // order of their norm). + for (int i = 0; i < realEigenvalues.length; ++i) { + largestEigenvalueNorm = FastMath.max(largestEigenvalueNorm, eigenvalueNorm(i)); + } // Corner case: zero matrix, all exactly 0 eigenvalues if (largestEigenvalueNorm == 0.0) { return false; diff --git a/src/test/java/org/apache/commons/math3/linear/EigenSolverTest.java b/src/test/java/org/apache/commons/math3/linear/EigenSolverTest.java index f55dad9df..cff868333 100644 --- a/src/test/java/org/apache/commons/math3/linear/EigenSolverTest.java +++ b/src/test/java/org/apache/commons/math3/linear/EigenSolverTest.java @@ -107,6 +107,17 @@ public class EigenSolverTest { eigen.getSolver().getInverse(); } + @Test + public void testIsNonSingularTinyOutOfOrderEigenvalue() { + final EigenDecomposition eigen + = new EigenDecomposition(MatrixUtils.createRealMatrix(new double[][] { + { 1e-13, 0 }, + { 1, 1 }, + })); + Assert.assertFalse("Singular matrix not detected", + eigen.getSolver().isNonSingular()); + } + /** test solve dimension errors */ @Test public void testSolveDimensionErrors() {