You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@commons.apache.org by er...@apache.org on 2012/09/20 12:09:38 UTC

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

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
   <body>
     <release version="3.1" date="TBD" description="
 ">
+      <action dev="erans" type="add" issue="MATH-866" due-to="Yannick Tanguy">
+        Added method to test for floating-point numbers equality with a
+        relative tolerance (class "o.a.c.m.util.Precision").
+      </action>
       <action dev="tn" type="fix" issue="MATH-666">
         Deprecated "FieldVector#getData()" in favor of "toArray()".
       </action>

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,