From e64d8653d1a4a653dc47da9f398d31955700ebae Mon Sep 17 00:00:00 2001 From: Gilles Sadowski Date: Fri, 27 Jul 2012 14:56:10 +0000 Subject: [PATCH] MATH-762 Created an inner class to collect statements that were duplicated. git-svn-id: https://svn.apache.org/repos/asf/commons/proper/math/trunk@1366400 13f79535-47bb-0310-9956-ffa450edef68 --- .../apache/commons/math3/util/FastMath.java | 215 ++++++++---------- 1 file changed, 97 insertions(+), 118 deletions(-) diff --git a/src/main/java/org/apache/commons/math3/util/FastMath.java b/src/main/java/org/apache/commons/math3/util/FastMath.java index e58087719..9152d193c 100644 --- a/src/main/java/org/apache/commons/math3/util/FastMath.java +++ b/src/main/java/org/apache/commons/math3/util/FastMath.java @@ -2127,9 +2127,10 @@ public class FastMath { } /** - * Sine function. - * @param x a number - * @return sin(x) + * Sine function. + * + * @param x Argument. + * @return sin(x) */ public static double sin(double x) { boolean negative = false; @@ -2168,42 +2169,10 @@ public class FastMath { xa = reduceResults[1]; xb = reduceResults[2]; } else if (xa > 1.5707963267948966) { - /* Inline the Cody/Waite reduction for performance */ - - // Estimate k - //k = (int)(xa / 1.5707963267948966); - int k = (int)(xa * 0.6366197723675814); - - // Compute remainder - double remA; - double remB; - while (true) { - double a = -k * 1.570796251296997; - remA = xa + a; - remB = -(remA - xa - a); - - a = -k * 7.549789948768648E-8; - double b = remA; - remA = a + b; - remB += -(remA - b - a); - - a = -k * 6.123233995736766E-17; - b = remA; - remA = a + b; - remB += -(remA - b - a); - - if (remA > 0.0) { - break; - } - - // Remainder is negative, so decrement k and try again. - // This should only happen if the input is very close - // to an even multiple of pi/2 - k--; - } - quadrant = k & 3; - xa = remA; - xb = remB; + final CodyWaite cw = new CodyWaite(xa, xb); + quadrant = cw.getK() & 3; + xa = cw.getRemA(); + xb = cw.getRemB(); } if (negative) { @@ -2225,9 +2194,10 @@ public class FastMath { } /** - * Cosine function - * @param x a number - * @return cos(x) + * Cosine function. + * + * @param x Argument. + * @return cos(x) */ public static double cos(double x) { int quadrant = 0; @@ -2254,42 +2224,10 @@ public class FastMath { xa = reduceResults[1]; xb = reduceResults[2]; } else if (xa > 1.5707963267948966) { - /* Inline the Cody/Waite reduction for performance */ - - // Estimate k - //k = (int)(xa / 1.5707963267948966); - int k = (int)(xa * 0.6366197723675814); - - // Compute remainder - double remA; - double remB; - while (true) { - double a = -k * 1.570796251296997; - remA = xa + a; - remB = -(remA - xa - a); - - a = -k * 7.549789948768648E-8; - double b = remA; - remA = a + b; - remB += -(remA - b - a); - - a = -k * 6.123233995736766E-17; - b = remA; - remA = a + b; - remB += -(remA - b - a); - - if (remA > 0.0) { - break; - } - - // Remainder is negative, so decrement k and try again. - // This should only happen if the input is very close - // to an even multiple of pi/2 - k--; - } - quadrant = k & 3; - xa = remA; - xb = remB; + final CodyWaite cw = new CodyWaite(xa, xb); + quadrant = cw.getK() & 3; + xa = cw.getRemA(); + xb = cw.getRemB(); } //if (negative) @@ -2310,9 +2248,10 @@ public class FastMath { } /** - * Tangent function - * @param x a number - * @return tan(x) + * Tangent function. + * + * @param x Argument. + * @return tan(x) */ public static double tan(double x) { boolean negative = false; @@ -2350,46 +2289,14 @@ public class FastMath { xa = reduceResults[1]; xb = reduceResults[2]; } else if (xa > 1.5707963267948966) { - /* Inline the Cody/Waite reduction for performance */ - - // Estimate k - //k = (int)(xa / 1.5707963267948966); - int k = (int)(xa * 0.6366197723675814); - - // Compute remainder - double remA; - double remB; - while (true) { - double a = -k * 1.570796251296997; - remA = xa + a; - remB = -(remA - xa - a); - - a = -k * 7.549789948768648E-8; - double b = remA; - remA = a + b; - remB += -(remA - b - a); - - a = -k * 6.123233995736766E-17; - b = remA; - remA = a + b; - remB += -(remA - b - a); - - if (remA > 0.0) { - break; - } - - // Remainder is negative, so decrement k and try again. - // This should only happen if the input is very close - // to an even multiple of pi/2 - k--; - } - quadrant = k & 3; - xa = remA; - xb = remB; + final CodyWaite cw = new CodyWaite(xa, xb); + quadrant = cw.getK() & 3; + xa = cw.getRemA(); + xb = cw.getRemB(); } if (xa > 1.5) { - // Accurracy suffers between 1.5 and PI/2 + // Accuracy suffers between 1.5 and PI/2 final double pi2a = 1.5707963267948966; final double pi2b = 6.123233995736766E-17; @@ -3795,4 +3702,76 @@ public class FastMath { } } } + + /** Enclose the Cody/Waite reduction (used in "sin", "cos" and "tan"). */ + private static class CodyWaite { + /** k */ + private final int finalK; + /** remA */ + private final double finalRemA; + /** remB */ + private final double finalRemB; + + /** + * @param xa Argument. + * @param xb Argument. + */ + CodyWaite(double xa, + double xb) { + // Estimate k. + //k = (int)(xa / 1.5707963267948966); + int k = (int)(xa * 0.6366197723675814); + + // Compute remainder. + double remA; + double remB; + while (true) { + double a = -k * 1.570796251296997; + remA = xa + a; + remB = -(remA - xa - a); + + a = -k * 7.549789948768648E-8; + double b = remA; + remA = a + b; + remB += -(remA - b - a); + + a = -k * 6.123233995736766E-17; + b = remA; + remA = a + b; + remB += -(remA - b - a); + + if (remA > 0) { + break; + } + + // Remainder is negative, so decrement k and try again. + // This should only happen if the input is very close + // to an even multiple of pi/2. + --k; + } + + this.finalK = k; + this.finalRemA = remA; + this.finalRemB = remB; + } + + /** + * @return k + */ + int getK() { + return finalK; + } + /** + * @return remA + */ + double getRemA() { + return finalRemA; + } + /** + * @return remB + */ + double getRemB() { + return finalRemB; + } + } }