This is an automated email from the ASF dual-hosted git repository. erans pushed a commit to branch master in repository https://gitbox.apache.org/repos/asf/commons-numbers.git
The following commit(s) were added to refs/heads/master by this push: new 3cf0a49 NUMBERS-158: Angle "normalization" operators. 3cf0a49 is described below commit 3cf0a49a330c3c9918f0fdc7f4d3fc6c08be0c36 Author: Gilles Sadowski <gillese...@gmail.com> AuthorDate: Thu May 27 11:09:59 2021 +0200 NUMBERS-158: Angle "normalization" operators. API based on JDK 8 replaces "static" functions. --- .../apache/commons/numbers/angle/PlaneAngle.java | 77 +++++++++++++++------- .../commons/numbers/angle/PlaneAngleRadians.java | 59 +++++++++-------- .../numbers/angle/PlaneAngleRadiansTest.java | 26 ++++---- .../commons/numbers/angle/PlaneAngleTest.java | 56 +++++++++------- .../apache/commons/numbers/angle/ReduceTest.java | 4 +- 5 files changed, 130 insertions(+), 92 deletions(-) diff --git a/commons-numbers-angle/src/main/java/org/apache/commons/numbers/angle/PlaneAngle.java b/commons-numbers-angle/src/main/java/org/apache/commons/numbers/angle/PlaneAngle.java index a421e43..78347af 100644 --- a/commons-numbers-angle/src/main/java/org/apache/commons/numbers/angle/PlaneAngle.java +++ b/commons-numbers-angle/src/main/java/org/apache/commons/numbers/angle/PlaneAngle.java @@ -16,6 +16,8 @@ */ package org.apache.commons.numbers.angle; +import java.util.function.UnaryOperator; + /** * Represents the <a href="https://en.wikipedia.org/wiki/Angle">angle</a> concept. */ @@ -90,31 +92,6 @@ public final class PlaneAngle { } /** - * Normalize an angle in an interval of size 1 turn around a - * center value. - * - * @param center Center of the desired interval for the result. - * @return {@code a - k} with integer {@code k} such that - * {@code center - 0.5 <= a - k < center + 0.5} (in turns). - */ - public PlaneAngle normalize(PlaneAngle center) { - final double lowerBound = center.value - HALF_TURN; - final double upperBound = center.value + HALF_TURN; - - final double normalized = value - Math.floor(value - lowerBound); - - return normalized < upperBound ? - new PlaneAngle(normalized) : - // If value is too small to be representable compared to the - // floor expression above (ie, if value + x = x), then we may - // end up with a number exactly equal to the upper bound here. - // In that case, subtract one from the normalized value so that - // we can fulfill the contract of only returning results strictly - // less than the upper bound. - new PlaneAngle(normalized - 1); - } - - /** * Test for equality with another object. * Objects are considered to be equal if the two values are exactly the * same, or both are {@code Double.NaN}. @@ -141,4 +118,54 @@ public final class PlaneAngle { public int hashCode() { return Double.hashCode(value); } + + /** + * Normalizes an angle in an interval of size 1 turn around a center value. + */ + public static final class Normalizer implements UnaryOperator<PlaneAngle> { + /** Lower bound. */ + private final double lowerBound; + /** Upper bound. */ + private final double upperBound; + /** Normalizer. */ + private final Reduce reduce; + + /** + * @param center Center of the desired interval. + */ + private Normalizer(PlaneAngle center) { + lowerBound = center.value - HALF_TURN; + upperBound = center.value + HALF_TURN; + reduce = new Reduce(lowerBound, 1d); + } + + /** + * @param a Angle. + * @return {@code = a - k} where {@code k} is an integer that satisfies + * {@code center - 0.5 <= a - k < center + 0.5} (in turns). + */ + @Override + public PlaneAngle apply(PlaneAngle a) { + final double normalized = reduce.applyAsDouble(a.value) + lowerBound; + return normalized < upperBound ? + new PlaneAngle(normalized) : + // If value is too small to be representable compared to the + // floor expression above (ie, if value + x = x), then we may + // end up with a number exactly equal to the upper bound here. + // In that case, subtract one from the normalized value so that + // we can fulfill the contract of only returning results strictly + // less than the upper bound. + new PlaneAngle(normalized - 1); + } + } + + /** + * Factory method. + * + * @param center Center of the desired interval. + * @return a {@link Normalizer} instance. + */ + public static Normalizer normalizer(PlaneAngle center) { + return new Normalizer(center); + } } diff --git a/commons-numbers-angle/src/main/java/org/apache/commons/numbers/angle/PlaneAngleRadians.java b/commons-numbers-angle/src/main/java/org/apache/commons/numbers/angle/PlaneAngleRadians.java index a4f0edc..c9a1c5c 100644 --- a/commons-numbers-angle/src/main/java/org/apache/commons/numbers/angle/PlaneAngleRadians.java +++ b/commons-numbers-angle/src/main/java/org/apache/commons/numbers/angle/PlaneAngleRadians.java @@ -16,6 +16,8 @@ */ package org.apache.commons.numbers.angle; +import java.util.function.DoubleUnaryOperator; + /** * Utility class where all {@code double} values are assumed to be in * radians. @@ -31,45 +33,46 @@ public final class PlaneAngleRadians { public static final double PI_OVER_TWO = 0.5 * PI; /** Value of \( 3\pi/2 \): {@value}. */ public static final double THREE_PI_OVER_TWO = 3 * PI_OVER_TWO; + /** Normalizes an angle to be in the range [-π, π). */ + public static final Normalizer WITHIN_MINUS_PI_AND_PI = new Normalizer(PlaneAngle.ZERO); + /** Normalize an angle to be in the range [0, 2π). */ + public static final Normalizer WITHIN_0_AND_2PI = new Normalizer(PlaneAngle.PI); /** Utility class. */ private PlaneAngleRadians() {} /** - * Normalize an angle in an interval of size 2π around a - * center value. - * - * @param angle Value to be normalized. - * @param center Center of the desired interval for the result. - * @return {@code a - 2 * k} with integer {@code k} such that - * {@code center - pi <= a - 2 * k * pi < center + pi}. + * Normalizes an angle in an interval of size 2π around a center value. */ - public static double normalize(double angle, - double center) { - final PlaneAngle a = PlaneAngle.ofRadians(angle); - final PlaneAngle c = PlaneAngle.ofRadians(center); - return a.normalize(c).toRadians(); - } + public static final class Normalizer implements DoubleUnaryOperator { + /** Underlying normalizer. */ + private final PlaneAngle.Normalizer normalizer; - /** - * Normalize an angle to be in the range [-π, π). - * - * @param angle Value to be normalized. - * @return {@code a - 2 * k} with integer {@code k} such that - * {@code -pi <= a - 2 * k * pi < pi}. - */ - public static double normalizeBetweenMinusPiAndPi(double angle) { - return PlaneAngle.ofRadians(angle).normalize(PlaneAngle.ZERO).toRadians(); + /** + * @param center Center (in radians) of the desired interval. + */ + private Normalizer(PlaneAngle center) { + normalizer = PlaneAngle.normalizer(center); + } + + /** + * @param a Angle (in radians). + * @return {@code a - 2 * k} with integer {@code k} such that + * {@code center - pi <= a - 2 * k * pi < center + pi} (in radians). + */ + @Override + public double applyAsDouble(double a) { + return normalizer.apply(PlaneAngle.ofRadians(a)).toRadians(); + } } /** - * Normalize an angle to be in the range [0, 2π). + * Factory method. * - * @param angle Value to be normalized. - * @return {@code a - 2 * k} with integer {@code k} such that - * {@code 0 <= a - 2 * k * pi < 2 * pi}. + * @param center Center (in radians) of the desired interval. + * @return a {@link Normalizer} instance. */ - public static double normalizeBetweenZeroAndTwoPi(double angle) { - return PlaneAngle.ofRadians(angle).normalize(PlaneAngle.PI).toRadians(); + public static Normalizer normalizer(double center) { + return new Normalizer(PlaneAngle.ofRadians(center)); } } diff --git a/commons-numbers-angle/src/test/java/org/apache/commons/numbers/angle/PlaneAngleRadiansTest.java b/commons-numbers-angle/src/test/java/org/apache/commons/numbers/angle/PlaneAngleRadiansTest.java index a320e26..2d31944 100644 --- a/commons-numbers-angle/src/test/java/org/apache/commons/numbers/angle/PlaneAngleRadiansTest.java +++ b/commons-numbers-angle/src/test/java/org/apache/commons/numbers/angle/PlaneAngleRadiansTest.java @@ -56,7 +56,7 @@ class PlaneAngleRadiansTest { void testNormalize() { for (double a = -15.0; a <= 15.0; a += 0.1) { for (double b = -15.0; b <= 15.0; b += 0.2) { - final double c = PlaneAngleRadians.normalize(a, b); + final double c = PlaneAngleRadians.normalizer(b).applyAsDouble(a); Assertions.assertTrue((b - PlaneAngleRadians.PI) <= c); Assertions.assertTrue(c <= (b + PlaneAngleRadians.PI)); double twoK = Math.rint((a - c) / PlaneAngleRadians.PI); @@ -69,7 +69,7 @@ class PlaneAngleRadiansTest { void testNormalizeBetweenMinusPiAndPi1() { final double value = 1.25 * PlaneAngleRadians.TWO_PI; final double expected = PlaneAngleRadians.PI_OVER_TWO; - final double actual = PlaneAngleRadians.normalizeBetweenMinusPiAndPi(value); + final double actual = PlaneAngleRadians.WITHIN_MINUS_PI_AND_PI.applyAsDouble(value); final double tol = Math.ulp(expected); Assertions.assertEquals(expected, actual, tol); } @@ -77,7 +77,7 @@ class PlaneAngleRadiansTest { void testNormalizeBetweenMinusPiAndPi2() { final double value = 0.75 * PlaneAngleRadians.TWO_PI; final double expected = -PlaneAngleRadians.PI_OVER_TWO; - final double actual = PlaneAngleRadians.normalizeBetweenMinusPiAndPi(value); + final double actual = PlaneAngleRadians.WITHIN_MINUS_PI_AND_PI.applyAsDouble(value); final double tol = Math.ulp(expected); Assertions.assertEquals(expected, actual, tol); } @@ -85,7 +85,7 @@ class PlaneAngleRadiansTest { void testNormalizeBetweenMinusPiAndPi3() { final double value = PlaneAngleRadians.PI + 1e-10; final double expected = -PlaneAngleRadians.PI + 1e-10; - final double actual = PlaneAngleRadians.normalizeBetweenMinusPiAndPi(value); + final double actual = PlaneAngleRadians.WITHIN_MINUS_PI_AND_PI.applyAsDouble(value); final double tol = Math.ulp(expected); Assertions.assertEquals(expected, actual, tol); } @@ -93,7 +93,7 @@ class PlaneAngleRadiansTest { void testNormalizeBetweenMinusPiAndPi4() { final double value = 5 * PlaneAngleRadians.PI / 4; final double expected = PlaneAngleRadians.PI * (1d / 4 - 1); - final double actual = PlaneAngleRadians.normalizeBetweenMinusPiAndPi(value); + final double actual = PlaneAngleRadians.WITHIN_MINUS_PI_AND_PI.applyAsDouble(value); final double tol = Math.ulp(expected); Assertions.assertEquals(expected, actual, tol); } @@ -102,7 +102,7 @@ class PlaneAngleRadiansTest { void testNormalizeBetweenMinusPiAndPi_lowerBound() { final double value = PlaneAngleRadians.PI; final double expected = -PlaneAngleRadians.PI; - final double actual = PlaneAngleRadians.normalizeBetweenMinusPiAndPi(value); + final double actual = PlaneAngleRadians.WITHIN_MINUS_PI_AND_PI.applyAsDouble(value); final double tol = Math.ulp(expected); Assertions.assertEquals(expected, actual, tol); } @@ -110,7 +110,7 @@ class PlaneAngleRadiansTest { void testNormalizeBetweenMinusPiAndPi_upperBound() { final double value = PlaneAngleRadians.PI; final double expected = -PlaneAngleRadians.PI; - final double actual = PlaneAngleRadians.normalizeBetweenMinusPiAndPi(value); + final double actual = PlaneAngleRadians.WITHIN_MINUS_PI_AND_PI.applyAsDouble(value); final double tol = Math.ulp(expected); Assertions.assertEquals(expected, actual, tol); } @@ -119,7 +119,7 @@ class PlaneAngleRadiansTest { void testNormalizeBetweenZeroAndTwoPi1() { final double value = 1.25 * PlaneAngleRadians.TWO_PI; final double expected = PlaneAngleRadians.PI_OVER_TWO; - final double actual = PlaneAngleRadians.normalizeBetweenZeroAndTwoPi(value); + final double actual = PlaneAngleRadians.WITHIN_0_AND_2PI.applyAsDouble(value); final double tol = Math.ulp(expected); Assertions.assertEquals(expected, actual, tol); } @@ -127,7 +127,7 @@ class PlaneAngleRadiansTest { void testNormalizeBetweenZeroAndTwoPi2() { final double value = 1.75 * PlaneAngleRadians.TWO_PI; final double expected = PlaneAngleRadians.THREE_PI_OVER_TWO; - final double actual = PlaneAngleRadians.normalizeBetweenZeroAndTwoPi(value); + final double actual = PlaneAngleRadians.WITHIN_0_AND_2PI.applyAsDouble(value); final double tol = Math.ulp(expected); Assertions.assertEquals(expected, actual, tol); } @@ -135,7 +135,7 @@ class PlaneAngleRadiansTest { void testNormalizeBetweenZeroAndTwoPi3() { final double value = -PlaneAngleRadians.PI + 1e-10; final double expected = PlaneAngleRadians.PI + 1e-10; - final double actual = PlaneAngleRadians.normalizeBetweenZeroAndTwoPi(value); + final double actual = PlaneAngleRadians.WITHIN_0_AND_2PI.applyAsDouble(value); final double tol = Math.ulp(expected); Assertions.assertEquals(expected, actual, tol); } @@ -143,7 +143,7 @@ class PlaneAngleRadiansTest { void testNormalizeBetweenZeroAndTwoPi4() { final double value = 9 * PlaneAngleRadians.PI / 4; final double expected = PlaneAngleRadians.PI / 4; - final double actual = PlaneAngleRadians.normalizeBetweenZeroAndTwoPi(value); + final double actual = PlaneAngleRadians.WITHIN_0_AND_2PI.applyAsDouble(value); final double tol = Math.ulp(expected); Assertions.assertEquals(expected, actual, tol); } @@ -152,7 +152,7 @@ class PlaneAngleRadiansTest { void testNormalizeBetweenZeroAndTwoPi_lowerBound() { final double value = 0.0; final double expected = 0.0; - final double actual = PlaneAngleRadians.normalizeBetweenZeroAndTwoPi(value); + final double actual = PlaneAngleRadians.WITHIN_0_AND_2PI.applyAsDouble(value); final double tol = Math.ulp(expected); Assertions.assertEquals(expected, actual, tol); } @@ -160,7 +160,7 @@ class PlaneAngleRadiansTest { void testNormalizeBetweenZeroAndTwoPi_upperBound() { final double value = PlaneAngleRadians.TWO_PI; final double expected = 0.0; - final double actual = PlaneAngleRadians.normalizeBetweenZeroAndTwoPi(value); + final double actual = PlaneAngleRadians.WITHIN_0_AND_2PI.applyAsDouble(value); final double tol = Math.ulp(expected); Assertions.assertEquals(expected, actual, tol); } diff --git a/commons-numbers-angle/src/test/java/org/apache/commons/numbers/angle/PlaneAngleTest.java b/commons-numbers-angle/src/test/java/org/apache/commons/numbers/angle/PlaneAngleTest.java index bf37b89..ab1f64f 100644 --- a/commons-numbers-angle/src/test/java/org/apache/commons/numbers/angle/PlaneAngleTest.java +++ b/commons-numbers-angle/src/test/java/org/apache/commons/numbers/angle/PlaneAngleTest.java @@ -16,6 +16,8 @@ */ package org.apache.commons.numbers.angle; +import java.util.function.UnaryOperator; + import org.junit.jupiter.api.Assertions; import org.junit.jupiter.api.Test; @@ -52,7 +54,7 @@ class PlaneAngleTest { for (double b = -15.0; b <= 15.0; b += 0.2) { final PlaneAngle aA = PlaneAngle.ofRadians(a); final PlaneAngle aB = PlaneAngle.ofRadians(b); - final double c = aA.normalize(aB).toRadians(); + final double c = PlaneAngle.normalizer(aB).apply(aA).toRadians(); Assertions.assertTrue((b - Math.PI) <= c); Assertions.assertTrue(c <= (b + Math.PI)); double twoK = Math.rint((a - c) / Math.PI); @@ -67,7 +69,7 @@ class PlaneAngleTest { for (double b = -15.0; b <= 15.0; b += 0.2) { final PlaneAngle aA = PlaneAngle.ofDegrees(a); final PlaneAngle aB = PlaneAngle.ofRadians(b); - final double c = aA.normalize(aB).toTurns(); + final double c = PlaneAngle.normalizer(aB).apply(aA).toTurns(); Assertions.assertTrue((aB.toTurns() - 0.5) <= c); Assertions.assertTrue(c <= (aB.toTurns() + 0.5)); double twoK = Math.rint(aA.toTurns() - c); @@ -80,7 +82,7 @@ class PlaneAngleTest { void testNormalizeAroundZero1() { final double value = 1.25; final double expected = 0.25; - final double actual = PlaneAngle.ofTurns(value).normalize(PlaneAngle.ZERO).toTurns(); + final double actual = PlaneAngle.normalizer(PlaneAngle.ZERO).apply(PlaneAngle.ofTurns(value)).toTurns(); final double tol = Math.ulp(expected); Assertions.assertEquals(expected, actual, tol); } @@ -88,7 +90,7 @@ class PlaneAngleTest { void testNormalizeAroundZero2() { final double value = 0.75; final double expected = -0.25; - final double actual = PlaneAngle.ofTurns(value).normalize(PlaneAngle.ZERO).toTurns(); + final double actual = PlaneAngle.normalizer(PlaneAngle.ZERO).apply(PlaneAngle.ofTurns(value)).toTurns(); final double tol = Math.ulp(expected); Assertions.assertEquals(expected, actual, tol); } @@ -96,7 +98,7 @@ class PlaneAngleTest { void testNormalizeAroundZero3() { final double value = 0.5 + 1e-10; final double expected = -0.5 + 1e-10; - final double actual = PlaneAngle.ofTurns(value).normalize(PlaneAngle.ZERO).toTurns(); + final double actual = PlaneAngle.normalizer(PlaneAngle.ZERO).apply(PlaneAngle.ofTurns(value)).toTurns(); final double tol = Math.ulp(expected); Assertions.assertEquals(expected, actual, tol); } @@ -104,50 +106,56 @@ class PlaneAngleTest { void testNormalizeAroundZero4() { final double value = 5 * Math.PI / 4; final double expected = Math.PI * (1d / 4 - 1); - final double actual = PlaneAngle.ofRadians(value).normalize(PlaneAngle.ZERO).toRadians(); + final double actual = PlaneAngle.normalizer(PlaneAngle.ZERO).apply(PlaneAngle.ofRadians(value)).toRadians(); final double tol = Math.ulp(expected); Assertions.assertEquals(expected, actual, tol); } @Test void testNormalizeUpperAndLowerBounds() { + final UnaryOperator<PlaneAngle> nZero = PlaneAngle.normalizer(PlaneAngle.ZERO); + final UnaryOperator<PlaneAngle> nPi = PlaneAngle.normalizer(PlaneAngle.PI); + // arrange double eps = 1e-15; // act/assert - Assertions.assertEquals(-0.5, PlaneAngle.ofTurns(-0.5).normalize(PlaneAngle.ZERO).toTurns(), eps); - Assertions.assertEquals(-0.5, PlaneAngle.ofTurns(0.5).normalize(PlaneAngle.ZERO).toTurns(), eps); + Assertions.assertEquals(-0.5, nZero.apply(PlaneAngle.ofTurns(-0.5)).toTurns(), eps); + Assertions.assertEquals(-0.5, nZero.apply(PlaneAngle.ofTurns(0.5)).toTurns(), eps); - Assertions.assertEquals(-0.5, PlaneAngle.ofTurns(-1.5).normalize(PlaneAngle.ZERO).toTurns(), eps); - Assertions.assertEquals(-0.5, PlaneAngle.ofTurns(1.5).normalize(PlaneAngle.ZERO).toTurns(), eps); + Assertions.assertEquals(-0.5, nZero.apply(PlaneAngle.ofTurns(-1.5)).toTurns(), eps); + Assertions.assertEquals(-0.5, nZero.apply(PlaneAngle.ofTurns(1.5)).toTurns(), eps); - Assertions.assertEquals(0.0, PlaneAngle.ofTurns(0).normalize(PlaneAngle.PI).toTurns(), eps); - Assertions.assertEquals(0.0, PlaneAngle.ofTurns(1).normalize(PlaneAngle.PI).toTurns(), eps); + Assertions.assertEquals(0.0, nPi.apply(PlaneAngle.ofTurns(0)).toTurns(), eps); + Assertions.assertEquals(0.0, nPi.apply(PlaneAngle.ofTurns(1)).toTurns(), eps); - Assertions.assertEquals(0.0, PlaneAngle.ofTurns(-1).normalize(PlaneAngle.PI).toTurns(), eps); - Assertions.assertEquals(0.0, PlaneAngle.ofTurns(2).normalize(PlaneAngle.PI).toTurns(), eps); + Assertions.assertEquals(0.0, nPi.apply(PlaneAngle.ofTurns(-1)).toTurns(), eps); + Assertions.assertEquals(0.0, nPi.apply(PlaneAngle.ofTurns(2)).toTurns(), eps); } @Test void testNormalizeVeryCloseToBounds() { + final UnaryOperator<PlaneAngle> nZero = PlaneAngle.normalizer(PlaneAngle.ZERO); + final UnaryOperator<PlaneAngle> nPi = PlaneAngle.normalizer(PlaneAngle.PI); + // arrange double eps = 1e-22; - double small = 1e-16; - double tiny = 1e-18; // 0.5 + tiny = 0.5 (the value is too small to add to 0.5) + double small = 2e-16; + double tiny = 5e-17; // 0.5 + tiny = 0.5 (the value is too small to add to 0.5) // act/assert - Assertions.assertEquals(1.0 - small, PlaneAngle.ofTurns(-small).normalize(PlaneAngle.PI).toTurns(), eps); - Assertions.assertEquals(small, PlaneAngle.ofTurns(small).normalize(PlaneAngle.PI).toTurns(), eps); + Assertions.assertEquals(1.0 - small, nPi.apply(PlaneAngle.ofTurns(-small)).toTurns(), eps); + Assertions.assertEquals(small, nPi.apply(PlaneAngle.ofTurns(small)).toTurns(), eps); - Assertions.assertEquals(0.5 - small, PlaneAngle.ofTurns(-0.5 - small).normalize(PlaneAngle.ZERO).toTurns(), eps); - Assertions.assertEquals(-0.5 + small, PlaneAngle.ofTurns(0.5 + small).normalize(PlaneAngle.ZERO).toTurns(), eps); + Assertions.assertEquals(0.5 - small, nZero.apply(PlaneAngle.ofTurns(-0.5 - small)).toTurns(), eps); + Assertions.assertEquals(-0.5 + small, nZero.apply(PlaneAngle.ofTurns(0.5 + small)).toTurns(), eps); - Assertions.assertEquals(0.0, PlaneAngle.ofTurns(-tiny).normalize(PlaneAngle.PI).toTurns(), eps); - Assertions.assertEquals(tiny, PlaneAngle.ofTurns(tiny).normalize(PlaneAngle.PI).toTurns(), eps); + Assertions.assertEquals(0.0, nPi.apply(PlaneAngle.ofTurns(-tiny)).toTurns(), eps); + Assertions.assertEquals(tiny, nPi.apply(PlaneAngle.ofTurns(tiny)).toTurns(), eps); - Assertions.assertEquals(-0.5, PlaneAngle.ofTurns(-0.5 - tiny).normalize(PlaneAngle.ZERO).toTurns(), eps); - Assertions.assertEquals(-0.5, PlaneAngle.ofTurns(0.5 + tiny).normalize(PlaneAngle.ZERO).toTurns(), eps); + Assertions.assertEquals(-0.5, nZero.apply(PlaneAngle.ofTurns(-0.5 - tiny)).toTurns(), eps); + Assertions.assertEquals(-0.5, nZero.apply(PlaneAngle.ofTurns(0.5 + tiny)).toTurns(), eps); } @Test diff --git a/commons-numbers-angle/src/test/java/org/apache/commons/numbers/angle/ReduceTest.java b/commons-numbers-angle/src/test/java/org/apache/commons/numbers/angle/ReduceTest.java index f78818f..9dc0c34 100644 --- a/commons-numbers-angle/src/test/java/org/apache/commons/numbers/angle/ReduceTest.java +++ b/commons-numbers-angle/src/test/java/org/apache/commons/numbers/angle/ReduceTest.java @@ -98,11 +98,11 @@ class ReduceTest { final double period = 2 * Math.PI; for (double a = -15; a <= 15; a += 0.5) { for (double center = -15; center <= 15; center += 1) { - final double nA = PlaneAngleRadians.normalize(a, center); + final double nA = PlaneAngleRadians.normalizer(center).applyAsDouble(a); final double offset = center - Math.PI; final Reduce reduce = new Reduce(offset, period); final double r = reduce.applyAsDouble(a) + offset; - Assertions.assertEquals(nA, r, 52 * Math.ulp(nA), + Assertions.assertEquals(nA, r, 1.1e2 * Math.ulp(nA), "a=" + a + " center=" + center); } }