You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@commons.apache.org by lu...@apache.org on 2009/06/04 22:07:29 UTC

svn commit: r781845 - in /commons/proper/math/trunk/src: java/org/apache/commons/math/linear/CholeskyDecompositionImpl.java site/xdoc/changes.xml test/org/apache/commons/math/linear/CholeskyDecompositionImplTest.java

Author: luc
Date: Thu Jun  4 20:07:29 2009
New Revision: 781845

URL: http://svn.apache.org/viewvc?rev=781845&view=rev
Log:
fixed detection of not positive definite matrices
JIRA: MATH-274

Modified:
    commons/proper/math/trunk/src/java/org/apache/commons/math/linear/CholeskyDecompositionImpl.java
    commons/proper/math/trunk/src/site/xdoc/changes.xml
    commons/proper/math/trunk/src/test/org/apache/commons/math/linear/CholeskyDecompositionImplTest.java

Modified: commons/proper/math/trunk/src/java/org/apache/commons/math/linear/CholeskyDecompositionImpl.java
URL: http://svn.apache.org/viewvc/commons/proper/math/trunk/src/java/org/apache/commons/math/linear/CholeskyDecompositionImpl.java?rev=781845&r1=781844&r2=781845&view=diff
==============================================================================
--- commons/proper/math/trunk/src/java/org/apache/commons/math/linear/CholeskyDecompositionImpl.java (original)
+++ commons/proper/math/trunk/src/java/org/apache/commons/math/linear/CholeskyDecompositionImpl.java Thu Jun  4 20:07:29 2009
@@ -111,11 +111,6 @@
 
             final double[] lI = lTData[i];
 
-            // check diagonal element
-            if (lTData[i][i] < absolutePositivityThreshold) {
-                throw new NotPositiveDefiniteMatrixException();
-            }
-
             // check off-diagonal elements (and reset them to 0)
             for (int j = i + 1; j < order; ++j) {
                 final double[] lJ = lTData[j];
@@ -134,6 +129,12 @@
         for (int i = 0; i < order; ++i) {
 
             final double[] ltI = lTData[i];
+
+            // check diagonal element
+            if (ltI[i] < absolutePositivityThreshold) {
+                throw new NotPositiveDefiniteMatrixException();
+            }
+
             ltI[i] = Math.sqrt(ltI[i]);
             final double inverse = 1.0 / ltI[i];
 

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=781845&r1=781844&r2=781845&view=diff
==============================================================================
--- commons/proper/math/trunk/src/site/xdoc/changes.xml (original)
+++ commons/proper/math/trunk/src/site/xdoc/changes.xml Thu Jun  4 20:07:29 2009
@@ -39,6 +39,9 @@
   </properties>
   <body>
     <release version="2.0" date="TBD" description="TBD">
+      <action dev="luc" type="fix" issue="MATH-274" >
+        Fixed detection of not positive definite matrices in Cholesky decomposition
+      </action>
       <action dev="luc" type="fix" issue="MATH-273" due-to="Benjamin McCann">
         Fixed a wrong check for basic variables
       </action>

Modified: commons/proper/math/trunk/src/test/org/apache/commons/math/linear/CholeskyDecompositionImplTest.java
URL: http://svn.apache.org/viewvc/commons/proper/math/trunk/src/test/org/apache/commons/math/linear/CholeskyDecompositionImplTest.java?rev=781845&r1=781844&r2=781845&view=diff
==============================================================================
--- commons/proper/math/trunk/src/test/org/apache/commons/math/linear/CholeskyDecompositionImplTest.java (original)
+++ commons/proper/math/trunk/src/test/org/apache/commons/math/linear/CholeskyDecompositionImplTest.java Thu Jun  4 20:07:29 2009
@@ -17,6 +17,9 @@
 
 package org.apache.commons.math.linear;
 
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertTrue;
+
 import org.apache.commons.math.MathException;
 import org.apache.commons.math.linear.CholeskyDecomposition;
 import org.apache.commons.math.linear.CholeskyDecompositionImpl;
@@ -25,12 +28,9 @@
 import org.apache.commons.math.linear.NotPositiveDefiniteMatrixException;
 import org.apache.commons.math.linear.NotSymmetricMatrixException;
 import org.apache.commons.math.linear.RealMatrix;
+import org.junit.Test;
 
-import junit.framework.Test;
-import junit.framework.TestCase;
-import junit.framework.TestSuite;
-
-public class CholeskyDecompositionImplTest extends TestCase {
+public class CholeskyDecompositionImplTest {
 
     private double[][] testData = new double[][] {
             {  1,  2,   4,   7,  11 },
@@ -40,17 +40,8 @@
             { 11, 58, 182, 430, 855 }
     };
 
-    public CholeskyDecompositionImplTest(String name) {
-        super(name);
-    }
-
-    public static Test suite() {
-        TestSuite suite = new TestSuite(CholeskyDecompositionImplTest.class);
-        suite.setName("CholeskyDecompositionImpl Tests");
-        return suite;
-    }
-
     /** test dimensions */
+    @Test
     public void testDimensions() throws MathException {
         CholeskyDecomposition llt =
             new CholeskyDecompositionImpl(MatrixUtils.createRealMatrix(testData));
@@ -61,47 +52,45 @@
     }
 
     /** test non-square matrix */
-    public void testNonSquare() {
-        try {
-            new CholeskyDecompositionImpl(MatrixUtils.createRealMatrix(new double[3][2]));
-        } catch (NonSquareMatrixException ime) {
-            // expected behavior
-        } catch (Exception e) {
-            fail("wrong exception caught");
-        }
+    @Test(expected = NonSquareMatrixException.class)
+    public void testNonSquare() throws MathException {
+        new CholeskyDecompositionImpl(MatrixUtils.createRealMatrix(new double[3][2]));
     }
 
     /** test non-symmetric matrix */
-    public void testNotSymmetricMatrixException() {
-        try {
-            double[][] changed = testData.clone();
-            changed[0][changed[0].length - 1] += 1.0e-5;
-            new CholeskyDecompositionImpl(MatrixUtils.createRealMatrix(changed));
-        } catch (NotSymmetricMatrixException e) {
-            // expected behavior
-        } catch (Exception e) {
-            fail("wrong exception caught");
-        }
+    @Test(expected = NotSymmetricMatrixException.class)
+    public void testNotSymmetricMatrixException() throws MathException {
+        double[][] changed = testData.clone();
+        changed[0][changed[0].length - 1] += 1.0e-5;
+        new CholeskyDecompositionImpl(MatrixUtils.createRealMatrix(changed));
     }
 
     /** test non positive definite matrix */
-    public void testNotPositiveDefinite() {
-        try {
-            new CholeskyDecompositionImpl(MatrixUtils.createRealMatrix(new double[][] {
-                    { 14, 11, 13, 15, 24 },
-                    { 11, 34, 13, 8,  25 },
-                    { 13, 13, 14, 15, 21 },
-                    { 15, 8,  15, 18, 23 },
-                    { 24, 25, 21, 23, 45 }
-            }));
-        } catch (NotPositiveDefiniteMatrixException e) {
-            // expected behavior
-        } catch (Exception e) {
-            fail("wrong exception caught");
-        }
+    @Test(expected = NotPositiveDefiniteMatrixException.class)
+    public void testNotPositiveDefinite() throws MathException {
+        CholeskyDecomposition cd = new CholeskyDecompositionImpl(MatrixUtils.createRealMatrix(new double[][] {
+                { 14, 11, 13, 15, 24 },
+                { 11, 34, 13, 8,  25 },
+                { 13, 13, 14, 15, 21 },
+                { 15, 8,  15, 18, 23 },
+                { 24, 25, 21, 23, 45 }
+        }));
+        System.out.println(cd.getL().multiply(cd.getLT()));
+    }
+
+    @Test(expected = NotPositiveDefiniteMatrixException.class)
+    public void testMath274() throws MathException {
+        new CholeskyDecompositionImpl(MatrixUtils.createRealMatrix(new double[][] {
+                { 0.40434286, -0.09376327, 0.30328980, 0.04909388 },
+                {-0.09376327,  0.10400408, 0.07137959, 0.04762857 },
+                { 0.30328980,  0.07137959, 0.30458776, 0.04882449 },
+                { 0.04909388,  0.04762857, 0.04882449, 0.07543265 }
+            
+        }));
     }
 
     /** test A = LLT */
+    @Test
     public void testAEqualLLT() throws MathException {
         RealMatrix matrix = MatrixUtils.createRealMatrix(testData);
         CholeskyDecomposition llt = new CholeskyDecompositionImpl(matrix);
@@ -112,17 +101,19 @@
     }
 
     /** test that L is lower triangular */
+    @Test
     public void testLLowerTriangular() throws MathException {
         RealMatrix matrix = MatrixUtils.createRealMatrix(testData);
         RealMatrix l = new CholeskyDecompositionImpl(matrix).getL();
         for (int i = 0; i < l.getRowDimension(); i++) {
             for (int j = i + 1; j < l.getColumnDimension(); j++) {
-                assertEquals(0.0, l.getEntry(i, j));
+                assertEquals(0.0, l.getEntry(i, j), 0.0);
             }
         }
     }
 
     /** test that LT is transpose of L */
+    @Test
     public void testLTTransposed() throws MathException {
         RealMatrix matrix = MatrixUtils.createRealMatrix(testData);
         CholeskyDecomposition llt = new CholeskyDecompositionImpl(matrix);
@@ -133,6 +124,7 @@
     }
 
     /** test matrices values */
+    @Test
     public void testMatricesValues() throws MathException {
         RealMatrix lRef = MatrixUtils.createRealMatrix(new double[][] {
                 {  1,  0,  0,  0,  0 },