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 9114BDD42 for ; Thu, 20 Sep 2012 10:10:35 +0000 (UTC) Received: (qmail 44356 invoked by uid 500); 20 Sep 2012 10:10:34 -0000 Delivered-To: apmail-commons-commits-archive@commons.apache.org Received: (qmail 44048 invoked by uid 500); 20 Sep 2012 10:10:29 -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 43999 invoked by uid 99); 20 Sep 2012 10:10:28 -0000 Received: from athena.apache.org (HELO athena.apache.org) (140.211.11.136) by apache.org (qpsmtpd/0.29) with ESMTP; Thu, 20 Sep 2012 10:10:28 +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; Thu, 20 Sep 2012 10:10:21 +0000 Received: from eris.apache.org (localhost [127.0.0.1]) by eris.apache.org (Postfix) with ESMTP id 84FAF23888E4 for ; Thu, 20 Sep 2012 10:09:38 +0000 (UTC) Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit Subject: svn commit: r1387941 - in /commons/proper/math/trunk/src: changes/changes.xml main/java/org/apache/commons/math3/util/Precision.java test/java/org/apache/commons/math3/util/PrecisionTest.java Date: Thu, 20 Sep 2012 10:09:38 -0000 To: commits@commons.apache.org From: erans@apache.org X-Mailer: svnmailer-1.0.8-patched Message-Id: <20120920100938.84FAF23888E4@eris.apache.org> X-Virus-Checked: Checked by ClamAV on apache.org Author: erans Date: Thu Sep 20 10:09:37 2012 New Revision: 1387941 URL: http://svn.apache.org/viewvc?rev=1387941&view=rev Log: MATH-866 Method to test for equality with a given relative tolerance (due to Yannick Tanguy and Julien Anxionnat). Original patch provided in JIRA MATH-863 and committed with a few changes. Modified: commons/proper/math/trunk/src/changes/changes.xml commons/proper/math/trunk/src/main/java/org/apache/commons/math3/util/Precision.java commons/proper/math/trunk/src/test/java/org/apache/commons/math3/util/PrecisionTest.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=1387941&r1=1387940&r2=1387941&view=diff ============================================================================== --- commons/proper/math/trunk/src/changes/changes.xml (original) +++ commons/proper/math/trunk/src/changes/changes.xml Thu Sep 20 10:09:37 2012 @@ -52,6 +52,10 @@ If the output is not quite correct, chec + + Added method to test for floating-point numbers equality with a + relative tolerance (class "o.a.c.m.util.Precision"). + Deprecated "FieldVector#getData()" in favor of "toArray()". Modified: commons/proper/math/trunk/src/main/java/org/apache/commons/math3/util/Precision.java URL: http://svn.apache.org/viewvc/commons/proper/math/trunk/src/main/java/org/apache/commons/math3/util/Precision.java?rev=1387941&r1=1387940&r2=1387941&view=diff ============================================================================== --- commons/proper/math/trunk/src/main/java/org/apache/commons/math3/util/Precision.java (original) +++ commons/proper/math/trunk/src/main/java/org/apache/commons/math3/util/Precision.java Thu Sep 20 10:09:37 2012 @@ -273,6 +273,28 @@ public class Precision { } /** + * Returns {@code true} if there is no double value strictly between the + * arguments or the reltaive difference between them is smaller or equal + * to the given tolerance. + * + * @param x First value. + * @param y Second value. + * @param eps Amount of allowed relative error. + * @return {@code true} if the values are two adjacent floating point + * numbers or they are within range of each other. + */ + public static boolean equalsWithRelativeTolerance(double x, double y, double eps) { + if (equals(x, y, 1)) { + return true; + } + + final double absoluteMax = FastMath.max(FastMath.abs(x), FastMath.abs(y)); + final double relativeDifference = FastMath.abs((x - y) / absoluteMax); + + return relativeDifference <= eps; + } + + /** * Returns true if both arguments are NaN or are equal or within the range * of allowed error (inclusive). * Modified: commons/proper/math/trunk/src/test/java/org/apache/commons/math3/util/PrecisionTest.java URL: http://svn.apache.org/viewvc/commons/proper/math/trunk/src/test/java/org/apache/commons/math3/util/PrecisionTest.java?rev=1387941&r1=1387940&r2=1387941&view=diff ============================================================================== --- commons/proper/math/trunk/src/test/java/org/apache/commons/math3/util/PrecisionTest.java (original) +++ commons/proper/math/trunk/src/test/java/org/apache/commons/math3/util/PrecisionTest.java Thu Sep 20 10:09:37 2012 @@ -28,6 +28,33 @@ import org.junit.Test; */ public class PrecisionTest { @Test + public void testEqualsWithRelativeTolerance() { + Assert.assertTrue(Precision.equalsWithRelativeTolerance(0d, 0d, 0d)); + Assert.assertTrue(Precision.equalsWithRelativeTolerance(0d, 1 / Double.NEGATIVE_INFINITY, 0d)); + + final double eps = 1e-14; + Assert.assertFalse(Precision.equalsWithRelativeTolerance(1.987654687654968, 1.987654687654988, eps)); + Assert.assertTrue(Precision.equalsWithRelativeTolerance(1.987654687654968, 1.987654687654987, eps)); + Assert.assertFalse(Precision.equalsWithRelativeTolerance(1.987654687654968, 1.987654687654948, eps)); + Assert.assertTrue(Precision.equalsWithRelativeTolerance(1.987654687654968, 1.987654687654949, eps)); + + Assert.assertFalse(Precision.equalsWithRelativeTolerance(Precision.SAFE_MIN, 0.0, eps)); + + Assert.assertFalse(Precision.equalsWithRelativeTolerance(1.0000000000001e-300, 1e-300, eps)); + Assert.assertTrue(Precision.equalsWithRelativeTolerance(1.00000000000001e-300, 1e-300, eps)); + + Assert.assertFalse(Precision.equalsWithRelativeTolerance(Double.NEGATIVE_INFINITY, 1.23, eps)); + Assert.assertFalse(Precision.equalsWithRelativeTolerance(Double.POSITIVE_INFINITY, 1.23, eps)); + + Assert.assertTrue(Precision.equalsWithRelativeTolerance(Double.NEGATIVE_INFINITY, Double.NEGATIVE_INFINITY, eps)); + Assert.assertTrue(Precision.equalsWithRelativeTolerance(Double.POSITIVE_INFINITY, Double.POSITIVE_INFINITY, eps)); + Assert.assertFalse(Precision.equalsWithRelativeTolerance(Double.NEGATIVE_INFINITY, Double.POSITIVE_INFINITY, eps)); + + Assert.assertFalse(Precision.equalsWithRelativeTolerance(Double.NaN, 1.23, eps)); + Assert.assertFalse(Precision.equalsWithRelativeTolerance(Double.NaN, Double.NaN, eps)); + } + + @Test public void testEqualsIncludingNaN() { double[] testArray = { Double.NaN,