Return-Path: Delivered-To: apmail-commons-commits-archive@minotaur.apache.org Received: (qmail 75225 invoked from network); 4 Jun 2009 20:07:40 -0000 Received: from hermes.apache.org (HELO mail.apache.org) (140.211.11.3) by minotaur.apache.org with SMTP; 4 Jun 2009 20:07:40 -0000 Received: (qmail 40109 invoked by uid 500); 4 Jun 2009 20:07:52 -0000 Delivered-To: apmail-commons-commits-archive@commons.apache.org Received: (qmail 39998 invoked by uid 500); 4 Jun 2009 20:07:52 -0000 Mailing-List: contact commits-help@commons.apache.org; run by ezmlm Precedence: bulk List-Help: List-Unsubscribe: List-Post: List-Id: Reply-To: dev@commons.apache.org Delivered-To: mailing list commits@commons.apache.org Received: (qmail 39989 invoked by uid 99); 4 Jun 2009 20:07:52 -0000 Received: from athena.apache.org (HELO athena.apache.org) (140.211.11.136) by apache.org (qpsmtpd/0.29) with ESMTP; Thu, 04 Jun 2009 20:07:52 +0000 X-ASF-Spam-Status: No, hits=-2000.0 required=10.0 tests=ALL_TRUSTED X-Spam-Check-By: apache.org Received: from [140.211.11.4] (HELO eris.apache.org) (140.211.11.4) by apache.org (qpsmtpd/0.29) with ESMTP; Thu, 04 Jun 2009 20:07:50 +0000 Received: by eris.apache.org (Postfix, from userid 65534) id C38B023888D0; Thu, 4 Jun 2009 20:07:29 +0000 (UTC) Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit Subject: 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 Date: Thu, 04 Jun 2009 20:07:29 -0000 To: commits@commons.apache.org From: luc@apache.org X-Mailer: svnmailer-1.0.8 Message-Id: <20090604200729.C38B023888D0@eris.apache.org> X-Virus-Checked: Checked by ClamAV on apache.org 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 @@ + + Fixed detection of not positive definite matrices in Cholesky decomposition + Fixed a wrong check for basic variables 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 },