Author: luc Date: Fri Mar 22 16:25:17 2013 New Revision: 1459887 URL: http://svn.apache.org/r1459887 Log: Improved speed of FastMath copysign methods.
JIRA: MATH-951 Modified: commons/proper/math/trunk/pom.xml commons/proper/math/trunk/src/changes/changes.xml commons/proper/math/trunk/src/main/java/org/apache/commons/math3/util/FastMath.java commons/proper/math/trunk/src/test/java/org/apache/commons/math3/util/FastMathTest.java Modified: commons/proper/math/trunk/pom.xml URL: http://svn.apache.org/viewvc/commons/proper/math/trunk/pom.xml?rev=1459887&r1=1459886&r2=1459887&view=diff ============================================================================== --- commons/proper/math/trunk/pom.xml (original) +++ commons/proper/math/trunk/pom.xml Fri Mar 22 16:25:17 2013 @@ -163,6 +163,9 @@ <name>Dan Checkoway</name> </contributor> <contributor> + <name>Charles Cooper</name> + </contributor> + <contributor> <name>Paul Cowan</name> </contributor> <contributor> Modified: commons/proper/math/trunk/src/changes/changes.xml URL: http://svn.apache.org/viewvc/commons/proper/math/trunk/src/changes/changes.xml?rev=1459887&r1=1459886&r2=1459887&view=diff ============================================================================== --- commons/proper/math/trunk/src/changes/changes.xml (original) +++ commons/proper/math/trunk/src/changes/changes.xml Fri Mar 22 16:25:17 2013 @@ -55,6 +55,9 @@ This is a minor release: It combines bug Changes to existing features were made in a backwards-compatible way such as to allow drop-in replacement of the v3.1[.1] JAR file. "> + <action dev="luc" type="update" issue="MATH-951" due-to="Charles Cooper"> + Improved speed of FastMath copysign methods. + </action> <action dev="erans" type="add" issue="MATH-817" due-to="Jared Becksfort"> Added Multivariate Normal Mixture Model Fitting by Expectation Maximization. </action> Modified: commons/proper/math/trunk/src/main/java/org/apache/commons/math3/util/FastMath.java URL: http://svn.apache.org/viewvc/commons/proper/math/trunk/src/main/java/org/apache/commons/math3/util/FastMath.java?rev=1459887&r1=1459886&r2=1459887&view=diff ============================================================================== --- commons/proper/math/trunk/src/main/java/org/apache/commons/math3/util/FastMath.java (original) +++ commons/proper/math/trunk/src/main/java/org/apache/commons/math3/util/FastMath.java Fri Mar 22 16:25:17 2013 @@ -3630,9 +3630,13 @@ public class FastMath { * @return the magnitude with the same sign as the {@code sign} argument */ public static double copySign(double magnitude, double sign){ - long m = Double.doubleToLongBits(magnitude); - long s = Double.doubleToLongBits(sign); - if ((m >= 0 && s >= 0) || (m < 0 && s < 0)) { // Sign is currently OK + // The highest order bit is going to be zero if the + // highest order bit of m and s is the same and one otherwise. + // So (m^s) will be positive if both m and s have the same sign + // and negative otherwise. + final long m = Double.doubleToLongBits(magnitude); + final long s = Double.doubleToLongBits(sign); + if ((m^s) >= 0) { return magnitude; } return -magnitude; // flip sign @@ -3647,9 +3651,13 @@ public class FastMath { * @return the magnitude with the same sign as the {@code sign} argument */ public static float copySign(float magnitude, float sign){ - int m = Float.floatToIntBits(magnitude); - int s = Float.floatToIntBits(sign); - if ((m >= 0 && s >= 0) || (m < 0 && s < 0)) { // Sign is currently OK + // The highest order bit is going to be zero if the + // highest order bit of m and s is the same and one otherwise. + // So (m^s) will be positive if both m and s have the same sign + // and negative otherwise. + final int m = Float.floatToIntBits(magnitude); + final int s = Float.floatToIntBits(sign); + if ((m^s) >= 0) { return magnitude; } return -magnitude; // flip sign Modified: commons/proper/math/trunk/src/test/java/org/apache/commons/math3/util/FastMathTest.java URL: http://svn.apache.org/viewvc/commons/proper/math/trunk/src/test/java/org/apache/commons/math3/util/FastMathTest.java?rev=1459887&r1=1459886&r2=1459887&view=diff ============================================================================== --- commons/proper/math/trunk/src/test/java/org/apache/commons/math3/util/FastMathTest.java (original) +++ commons/proper/math/trunk/src/test/java/org/apache/commons/math3/util/FastMathTest.java Fri Mar 22 16:25:17 2013 @@ -1149,6 +1149,10 @@ public class FastMathTest { double delta = 0.0; Assert.assertEquals(1.0, FastMath.copySign(1d, 2.0), delta); Assert.assertEquals(1.0, FastMath.copySign(1d, 0.0), delta); + Assert.assertEquals(-1.0, FastMath.copySign(1d, -0.0), delta); + Assert.assertEquals(1.0, FastMath.copySign(1d, Double.POSITIVE_INFINITY), delta); + Assert.assertEquals(-1.0, FastMath.copySign(1d, Double.NEGATIVE_INFINITY), delta); + Assert.assertEquals(1.0, FastMath.copySign(1d, Double.NaN), delta); Assert.assertEquals(-1.0, FastMath.copySign(1d, -2.0), delta); } @@ -1157,6 +1161,10 @@ public class FastMathTest { float delta = 0.0F; Assert.assertEquals(1.0F, FastMath.copySign(1d, 2.0F), delta); Assert.assertEquals(1.0F, FastMath.copySign(1d, 0.0F), delta); + Assert.assertEquals(-1.0F, FastMath.copySign(1d, -0.0F), delta); + Assert.assertEquals(1.0F, FastMath.copySign(1d, Float.POSITIVE_INFINITY), delta); + Assert.assertEquals(-1.0F, FastMath.copySign(1d, Float.NEGATIVE_INFINITY), delta); + Assert.assertEquals(1.0F, FastMath.copySign(1d, Float.NaN), delta); Assert.assertEquals(-1.0F, FastMath.copySign(1d, -2.0F), delta); }