Return-Path: Delivered-To: apmail-commons-commits-archive@minotaur.apache.org Received: (qmail 36649 invoked from network); 18 Oct 2009 23:30:02 -0000 Received: from hermes.apache.org (HELO mail.apache.org) (140.211.11.3) by minotaur.apache.org with SMTP; 18 Oct 2009 23:30:02 -0000 Received: (qmail 82876 invoked by uid 500); 18 Oct 2009 23:30:02 -0000 Delivered-To: apmail-commons-commits-archive@commons.apache.org Received: (qmail 82790 invoked by uid 500); 18 Oct 2009 23:30:01 -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 82781 invoked by uid 99); 18 Oct 2009 23:30:01 -0000 Received: from nike.apache.org (HELO nike.apache.org) (192.87.106.230) by apache.org (qpsmtpd/0.29) with ESMTP; Sun, 18 Oct 2009 23:30:01 +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; Sun, 18 Oct 2009 23:29:59 +0000 Received: by eris.apache.org (Postfix, from userid 65534) id F14632388906; Sun, 18 Oct 2009 23:29:37 +0000 (UTC) Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit Subject: svn commit: r826550 - in /commons/proper/math/trunk/src: main/java/org/apache/commons/math/linear/EigenDecompositionImpl.java test/java/org/apache/commons/math/linear/EigenDecompositionImplTest.java Date: Sun, 18 Oct 2009 23:29:37 -0000 To: commits@commons.apache.org From: billbarker@apache.org X-Mailer: svnmailer-1.0.8 Message-Id: <20091018232937.F14632388906@eris.apache.org> X-Virus-Checked: Checked by ClamAV on apache.org Author: billbarker Date: Sun Oct 18 23:29:37 2009 New Revision: 826550 URL: http://svn.apache.org/viewvc?rev=826550&view=rev Log: Fix for possible zero divide on an indefinite matrix Fix for: MATH-297 Modified: commons/proper/math/trunk/src/main/java/org/apache/commons/math/linear/EigenDecompositionImpl.java commons/proper/math/trunk/src/test/java/org/apache/commons/math/linear/EigenDecompositionImplTest.java Modified: commons/proper/math/trunk/src/main/java/org/apache/commons/math/linear/EigenDecompositionImpl.java URL: http://svn.apache.org/viewvc/commons/proper/math/trunk/src/main/java/org/apache/commons/math/linear/EigenDecompositionImpl.java?rev=826550&r1=826549&r2=826550&view=diff ============================================================================== --- commons/proper/math/trunk/src/main/java/org/apache/commons/math/linear/EigenDecompositionImpl.java (original) +++ commons/proper/math/trunk/src/main/java/org/apache/commons/math/linear/EigenDecompositionImpl.java Sun Oct 18 23:29:37 2009 @@ -1699,19 +1699,21 @@ // perform an initial non-shifted LDLt decomposition final double[] d = new double[m]; final double[] l = new double[m - 1]; - double di = main[0]; + // avoid zero divide on indefinite matrix + final double mu = realEigenvalues[m-1] <= 0 && realEigenvalues[0] > 0 ? 0.5-realEigenvalues[m-1] : 0; + double di = main[0]+mu; d[0] = di; for (int i = 1; i < m; ++i) { final double eiM1 = secondary[i - 1]; final double ratio = eiM1 / di; - di = main[i] - eiM1 * ratio; + di = main[i] - eiM1 * ratio + mu; l[i - 1] = ratio; d[i] = di; } // compute eigenvectors for (int i = 0; i < m; ++i) { - eigenvectors[i] = findEigenvector(realEigenvalues[i], d, l); + eigenvectors[i] = findEigenvector(realEigenvalues[i]+mu, d, l); } } Modified: commons/proper/math/trunk/src/test/java/org/apache/commons/math/linear/EigenDecompositionImplTest.java URL: http://svn.apache.org/viewvc/commons/proper/math/trunk/src/test/java/org/apache/commons/math/linear/EigenDecompositionImplTest.java?rev=826550&r1=826549&r2=826550&view=diff ============================================================================== --- commons/proper/math/trunk/src/test/java/org/apache/commons/math/linear/EigenDecompositionImplTest.java (original) +++ commons/proper/math/trunk/src/test/java/org/apache/commons/math/linear/EigenDecompositionImplTest.java Sun Oct 18 23:29:37 2009 @@ -244,6 +244,24 @@ } /** + * Verifies operation on indefinite matrix + */ + public void testZeroDivide() { + RealMatrix indefinite = MatrixUtils.createRealMatrix(new double [][] { + { 0.0, 1.0, -1.0 }, + { 1.0, 1.0, 0.0 }, + { -1.0,0.0, 1.0 } + }); + EigenDecomposition ed = new EigenDecompositionImpl(indefinite, MathUtils.SAFE_MIN); + checkEigenValues((new double[] {2, 1, -1}), ed, 1E-12); + double isqrt3 = 1/Math.sqrt(3.0); + checkEigenVector((new double[] {isqrt3,isqrt3,-isqrt3}), ed, 1E-12); + double isqrt2 = 1/Math.sqrt(2.0); + checkEigenVector((new double[] {0.0,-isqrt2,-isqrt2}), ed, 1E-12); + double isqrt6 = 1/Math.sqrt(6.0); + checkEigenVector((new double[] {2*isqrt6,-isqrt6,isqrt6}), ed, 1E-12); + } + /** * Verifies that the given EigenDecomposition has eigenvalues equivalent to * the targetValues, ignoring the order of the values and allowing * values to differ by tolerance. @@ -257,6 +275,7 @@ } } + /** * Returns true iff there is an entry within tolerance of value in * searchArray.