Repository: commons-math
Updated Branches:
  refs/heads/master 83c61da2c -> 0c0455fd6


Added a fast implementation of IEEEremainder in FastMath.

Project: http://git-wip-us.apache.org/repos/asf/commons-math/repo
Commit: http://git-wip-us.apache.org/repos/asf/commons-math/commit/15a24dc0
Tree: http://git-wip-us.apache.org/repos/asf/commons-math/tree/15a24dc0
Diff: http://git-wip-us.apache.org/repos/asf/commons-math/diff/15a24dc0

Branch: refs/heads/master
Commit: 15a24dc0fc9067fabe00857f8546aee4a5234a78
Parents: 83c61da
Author: Luc Maisonobe <[email protected]>
Authored: Sat May 16 14:22:46 2015 +0200
Committer: Luc Maisonobe <[email protected]>
Committed: Sat May 16 14:24:13 2015 +0200

----------------------------------------------------------------------
 src/changes/changes.xml                         |  3 ++
 .../org/apache/commons/math4/util/FastMath.java | 17 +++++++--
 .../userguide/FastMathTestPerformance.java      | 40 ++++++++++++++++++--
 3 files changed, 54 insertions(+), 6 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/commons-math/blob/15a24dc0/src/changes/changes.xml
----------------------------------------------------------------------
diff --git a/src/changes/changes.xml b/src/changes/changes.xml
index 6afa831..1b448a8 100644
--- a/src/changes/changes.xml
+++ b/src/changes/changes.xml
@@ -54,6 +54,9 @@ If the output is not quite correct, check for invisible 
trailing spaces!
     </release>
 
     <release version="4.0" date="XXXX-XX-XX" description="">
+      <action dev="luc" type="add" >
+        Added a fast implementation of IEEEremainder in FastMath.
+      </action>
       <action dev="luc" type="fix" issue="MATH-1222" due-to="Benedikt Ritter">
         Use Double.isNaN rather than x != x in FastMath.
       </action>

http://git-wip-us.apache.org/repos/asf/commons-math/blob/15a24dc0/src/main/java/org/apache/commons/math4/util/FastMath.java
----------------------------------------------------------------------
diff --git a/src/main/java/org/apache/commons/math4/util/FastMath.java 
b/src/main/java/org/apache/commons/math4/util/FastMath.java
index cd56192..3e96f69 100644
--- a/src/main/java/org/apache/commons/math4/util/FastMath.java
+++ b/src/main/java/org/apache/commons/math4/util/FastMath.java
@@ -3628,13 +3628,24 @@ public class FastMath {
      * <li>If the dividend is finite and the divisor is an infinity, the 
result equals the dividend.</li>
      * <li>If the dividend is a zero and the divisor is finite, the result 
equals the dividend.</li>
      * </ul>
-     * <p><b>Note:</b> this implementation currently delegates to {@link 
StrictMath#IEEEremainder}
      * @param dividend the number to be divided
      * @param divisor the number by which to divide
      * @return the remainder, rounded
      */
-    public static double IEEEremainder(double dividend, double divisor) {
-        return StrictMath.IEEEremainder(dividend, divisor); // TODO provide 
our own implementation
+    public static double IEEEremainder(final double dividend, final double 
divisor) {
+        if (getExponent(dividend) == 1024 || getExponent(divisor) == 1024 || 
divisor == 0.0) {
+            // we are in one of the special cases
+            if (Double.isInfinite(divisor) && !Double.isInfinite(dividend)) {
+                return dividend;
+            } else {
+                return Double.NaN;
+            }
+        } else {
+            // we are in the general case
+            final double n         = FastMath.rint(dividend / divisor);
+            final double remainder = Double.isInfinite(n) ? 0.0 : dividend - 
divisor * n;
+            return (remainder == 0) ? FastMath.copySign(remainder, dividend) : 
remainder;
+        }
     }
 
     /** Convert a long to interger, detecting overflows

http://git-wip-us.apache.org/repos/asf/commons-math/blob/15a24dc0/src/userguide/java/org/apache/commons/math4/userguide/FastMathTestPerformance.java
----------------------------------------------------------------------
diff --git 
a/src/userguide/java/org/apache/commons/math4/userguide/FastMathTestPerformance.java
 
b/src/userguide/java/org/apache/commons/math4/userguide/FastMathTestPerformance.java
index 8af6fca..697bd60 100644
--- 
a/src/userguide/java/org/apache/commons/math4/userguide/FastMathTestPerformance.java
+++ 
b/src/userguide/java/org/apache/commons/math4/userguide/FastMathTestPerformance.java
@@ -28,9 +28,9 @@ public class FastMathTestPerformance {
     private static final double F1 = 1d / RUNS;
 
     // Header format
-    private static final String FMT_HDR = "%-5s %13s %13s %13s Runs=%d Java %s 
(%s) %s (%s)";
+    private static final String FMT_HDR = "%-13s %13s %13s %13s Runs=%d Java 
%s (%s) %s (%s)";
     // Detail format
-    private static final String FMT_DTL = "%-5s %6d %6.1f %6d %6.4f %6d %6.4f";
+    private static final String FMT_DTL = "%-13s %6d %6.1f %6d %6.4f %6d 
%6.4f";
 
     public static void main(String[] args) {
         System.out.println(String.format(FMT_HDR,
@@ -60,6 +60,7 @@ public class FastMathTestPerformance {
         testSqrt();
         testTan();
         testTanh();
+        testIEEEremainder();
 
     }
 
@@ -429,7 +430,40 @@ public class FastMathTestPerformance {
         report("hypot",strictTime,fastTime,mathTime);
         assertTrue(!Double.isNaN(x));
     }
-     
+
+    private static void testIEEEremainder() {
+        double x = 0;
+        long time = System.nanoTime();
+        int max   = (int) FastMath.floor(FastMath.sqrt(RUNS));
+        for (int i = 0; i < max; i++) {
+            for (int j = 0; j < max; j++) {
+                x += StrictMath.IEEEremainder((i - max/2) * (100.0 / max), (j 
+ 1) * (100.0 / max));
+            }
+        }
+        long strictTime = System.nanoTime() - time;
+
+        x = 0;
+        time = System.nanoTime();
+        for (int i = 0; i < max; i++) {
+            for (int j = 0; j < max; j++) {
+                x += FastMath.IEEEremainder((i - max/2) * (100.0 / max), (j + 
1) * (100.0 / max));
+            }
+        }
+        long fastTime = System.nanoTime() - time;
+
+        x = 0;
+        time = System.nanoTime();
+        for (int i = 0; i < max; i++) {
+            for (int j = 0; j < max; j++) {
+                x += Math.IEEEremainder((i - max/2) * (100.0 / max), (j + 1) * 
(100.0 / max));
+            }
+        }
+        long mathTime = System.nanoTime() - time;
+
+        report("IEEEremainder",strictTime,fastTime,mathTime);
+        assertTrue(!Double.isNaN(x));
+    }
+
     private static void testCbrt() {
         double x = 0;
         long time = System.nanoTime();

Reply via email to