Return-Path: X-Original-To: apmail-commons-commits-archive@minotaur.apache.org Delivered-To: apmail-commons-commits-archive@minotaur.apache.org Received: from mail.apache.org (hermes.apache.org [140.211.11.3]) by minotaur.apache.org (Postfix) with SMTP id 8732FDBC3 for ; Tue, 30 Oct 2012 00:22:11 +0000 (UTC) Received: (qmail 59928 invoked by uid 500); 30 Oct 2012 00:22:09 -0000 Delivered-To: apmail-commons-commits-archive@commons.apache.org Received: (qmail 59876 invoked by uid 500); 30 Oct 2012 00:22:09 -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 59869 invoked by uid 99); 30 Oct 2012 00:22:09 -0000 Received: from nike.apache.org (HELO nike.apache.org) (192.87.106.230) by apache.org (qpsmtpd/0.29) with ESMTP; Tue, 30 Oct 2012 00:22:09 +0000 X-ASF-Spam-Status: No, hits=-2000.0 required=5.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; Tue, 30 Oct 2012 00:22:06 +0000 Received: from eris.apache.org (localhost [127.0.0.1]) by eris.apache.org (Postfix) with ESMTP id 85EDF23888CD for ; Tue, 30 Oct 2012 00:21:21 +0000 (UTC) Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit Subject: svn commit: r1403587 - in /commons/proper/math/trunk/src: changes/changes.xml main/java/org/apache/commons/math3/linear/MatrixUtils.java test/java/org/apache/commons/math3/linear/MatrixUtilsTest.java Date: Tue, 30 Oct 2012 00:21:21 -0000 To: commits@commons.apache.org From: erans@apache.org X-Mailer: svnmailer-1.0.8-patched Message-Id: <20121030002121.85EDF23888CD@eris.apache.org> X-Virus-Checked: Checked by ClamAV on apache.org Author: erans Date: Tue Oct 30 00:21:20 2012 New Revision: 1403587 URL: http://svn.apache.org/viewvc?rev=1403587&view=rev Log: MATH-884 Added methods "isSymmetric" and "checkSymmetric". Modified: commons/proper/math/trunk/src/changes/changes.xml commons/proper/math/trunk/src/main/java/org/apache/commons/math3/linear/MatrixUtils.java commons/proper/math/trunk/src/test/java/org/apache/commons/math3/linear/MatrixUtilsTest.java Modified: commons/proper/math/trunk/src/changes/changes.xml URL: http://svn.apache.org/viewvc/commons/proper/math/trunk/src/changes/changes.xml?rev=1403587&r1=1403586&r2=1403587&view=diff ============================================================================== --- commons/proper/math/trunk/src/changes/changes.xml (original) +++ commons/proper/math/trunk/src/changes/changes.xml Tue Oct 30 00:21:20 2012 @@ -52,6 +52,10 @@ If the output is not quite correct, chec + + Added "isSymmetric" and "checkSymmetric" in "MatrixUtils" (package + "o.a.c.m.linear"). + Moved private array argument validation methods from ChiSquareTest to MathArrays. Modified: commons/proper/math/trunk/src/main/java/org/apache/commons/math3/linear/MatrixUtils.java URL: http://svn.apache.org/viewvc/commons/proper/math/trunk/src/main/java/org/apache/commons/math3/linear/MatrixUtils.java?rev=1403587&r1=1403586&r2=1403587&view=diff ============================================================================== --- commons/proper/math/trunk/src/main/java/org/apache/commons/math3/linear/MatrixUtils.java (original) +++ commons/proper/math/trunk/src/main/java/org/apache/commons/math3/linear/MatrixUtils.java Tue Oct 30 00:21:20 2012 @@ -375,6 +375,70 @@ public class MatrixUtils { } /** + * Checks whether a matrix is symmetric, within a given relative tolerance. + * + * @param matrix Matrix to check. + * @param relativeTolerance Tolerance of the symmetry check. + * @param raiseException If {@code true}, an exception will be raised if + * the matrix is not symmetric. + * @return {@code true} if {@code matrix} is symmetric. + * @throws NonSquareMatrixException if the matrix is not square. + * @throws NonSymmetricMatrixException if the matrix is not symmetric. + */ + private static boolean isSymmetricInternal(RealMatrix matrix, + double relativeTolerance, + boolean raiseException) { + final int rows = matrix.getRowDimension(); + if (rows != matrix.getColumnDimension()) { + if (raiseException) { + throw new NonSquareMatrixException(rows, matrix.getColumnDimension()); + } else { + return false; + } + } + for (int i = 0; i < rows; i++) { + for (int j = i + 1; j < rows; j++) { + final double mij = matrix.getEntry(i, j); + final double mji = matrix.getEntry(j, i); + if (FastMath.abs(mij - mji) > + FastMath.max(FastMath.abs(mij), FastMath.abs(mji)) * relativeTolerance) { + if (raiseException) { + throw new NonSymmetricMatrixException(i, j, relativeTolerance); + } else { + return false; + } + } + } + } + return true; + } + + /** + * Checks whether a matrix is symmetric. + * + * @param matrix Matrix to check. + * @param eps Relative tolerance. + * @throws NonSquareMatrixException if the matrix is not square. + * @throws NonSymmetricMatrixException if the matrix is not symmetric. + */ + public static void checkSymmetric(RealMatrix matrix, + double eps) { + isSymmetricInternal(matrix, eps, true); + } + + /** + * Checks whether a matrix is symmetric. + * + * @param matrix Matrix to check. + * @param eps Relative tolerance. + * @return {@code true} if {@code matrix} is symmetric. + */ + public static boolean isSymmetric(RealMatrix matrix, + double eps) { + return isSymmetricInternal(matrix, eps, false); + } + + /** * Check if matrix indices are valid. * * @param m Matrix. Modified: commons/proper/math/trunk/src/test/java/org/apache/commons/math3/linear/MatrixUtilsTest.java URL: http://svn.apache.org/viewvc/commons/proper/math/trunk/src/test/java/org/apache/commons/math3/linear/MatrixUtilsTest.java?rev=1403587&r1=1403586&r2=1403587&view=diff ============================================================================== --- commons/proper/math/trunk/src/test/java/org/apache/commons/math3/linear/MatrixUtilsTest.java (original) +++ commons/proper/math/trunk/src/test/java/org/apache/commons/math3/linear/MatrixUtilsTest.java Tue Oct 30 00:21:20 2012 @@ -363,4 +363,74 @@ public final class MatrixUtilsTest { } } } + + @Test + public void testIsSymmetric() { + final double eps = Math.ulp(1d); + + final double[][] dataSym = { + { 1, 2, 3 }, + { 2, 2, 5 }, + { 3, 5, 6 }, + }; + Assert.assertTrue(MatrixUtils.isSymmetric(MatrixUtils.createRealMatrix(dataSym), eps)); + + final double[][] dataNonSym = { + { 1, 2, -3 }, + { 2, 2, 5 }, + { 3, 5, 6 }, + }; + Assert.assertFalse(MatrixUtils.isSymmetric(MatrixUtils.createRealMatrix(dataNonSym), eps)); + } + + @Test + public void testIsSymmetricTolerance() { + final double eps = 1e-4; + + final double[][] dataSym1 = { + { 1, 1, 1.00009 }, + { 1, 1, 1 }, + { 1.0, 1, 1 }, + }; + Assert.assertTrue(MatrixUtils.isSymmetric(MatrixUtils.createRealMatrix(dataSym1), eps)); + final double[][] dataSym2 = { + { 1, 1, 0.99990 }, + { 1, 1, 1 }, + { 1.0, 1, 1 }, + }; + Assert.assertTrue(MatrixUtils.isSymmetric(MatrixUtils.createRealMatrix(dataSym2), eps)); + + final double[][] dataNonSym1 = { + { 1, 1, 1.00011 }, + { 1, 1, 1 }, + { 1.0, 1, 1 }, + }; + Assert.assertFalse(MatrixUtils.isSymmetric(MatrixUtils.createRealMatrix(dataNonSym1), eps)); + final double[][] dataNonSym2 = { + { 1, 1, 0.99989 }, + { 1, 1, 1 }, + { 1.0, 1, 1 }, + }; + Assert.assertFalse(MatrixUtils.isSymmetric(MatrixUtils.createRealMatrix(dataNonSym2), eps)); + } + + @Test + public void testCheckSymmetric1() { + final double[][] dataSym = { + { 1, 2, 3 }, + { 2, 2, 5 }, + { 3, 5, 6 }, + }; + MatrixUtils.checkSymmetric(MatrixUtils.createRealMatrix(dataSym), Math.ulp(1d)); + } + + @Test(expected=NonSymmetricMatrixException.class) + public void testCheckSymmetric2() { + final double[][] dataNonSym = { + { 1, 2, -3 }, + { 2, 2, 5 }, + { 3, 5, 6 }, + }; + MatrixUtils.checkSymmetric(MatrixUtils.createRealMatrix(dataNonSym), Math.ulp(1d)); + } }