You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@commons.apache.org by ah...@apache.org on 2019/12/04 21:53:55 UTC
[commons-numbers] 05/06: [NUMBERS-78] Increase edge case coverage
of atanh.
This is an automated email from the ASF dual-hosted git repository.
aherbert pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/commons-numbers.git
commit d258522e2ec93b06f120fe66e3b8837afb8389b2
Author: Alex Herbert <ah...@apache.org>
AuthorDate: Wed Dec 4 21:43:32 2019 +0000
[NUMBERS-78] Increase edge case coverage of atanh.
Requires implementation of subtractFromReal to negate the sign of the
imaginary zero when subtracting from 0 imaginary.
---
.../org/apache/commons/numbers/complex/Complex.java | 18 +++++++++++++++++-
.../apache/commons/numbers/complex/ComplexTest.java | 9 +++++++++
2 files changed, 26 insertions(+), 1 deletion(-)
diff --git a/commons-numbers-complex/src/main/java/org/apache/commons/numbers/complex/Complex.java b/commons-numbers-complex/src/main/java/org/apache/commons/numbers/complex/Complex.java
index fc80ecb..b14ff97 100644
--- a/commons-numbers-complex/src/main/java/org/apache/commons/numbers/complex/Complex.java
+++ b/commons-numbers-complex/src/main/java/org/apache/commons/numbers/complex/Complex.java
@@ -858,6 +858,22 @@ public final class Complex implements Serializable {
/**
* Returns a {@code Complex} whose value is
+ * {@code (minuend - this)}.
+ * Uses the definitional formula
+ * <p>
+ * {@code a - (c + di) = (a-c) -di}
+ * </p>
+ *
+ * @param minuend value that this {@code Complex} is to be subtracted from.
+ * @return {@code minuend - this}.
+ */
+ private Complex subtractFromReal(double minuend) {
+ return new Complex(minuend - real,
+ -imaginary);
+ }
+
+ /**
+ * Returns a {@code Complex} whose value is
* {@code (this - subtrahend)}.
*
* @param subtrahend value to be subtracted from this {@code Complex}.
@@ -1080,7 +1096,7 @@ public final class Complex implements Serializable {
// ISO C99: Preserve the equality
// atanh(conj(z)) = conj(atanh(z))
final Complex z = negative(imaginary) ? conjugate() : this;
- final Complex result = z.add(ONE).divide(ONE.subtract(z)).log().multiply(0.5);
+ final Complex result = z.add(1).divide(z.subtractFromReal(1)).log().multiply(0.5);
return z == this ? result : result.conjugate();
}
if (Double.isInfinite(imaginary)) {
diff --git a/commons-numbers-complex/src/test/java/org/apache/commons/numbers/complex/ComplexTest.java b/commons-numbers-complex/src/test/java/org/apache/commons/numbers/complex/ComplexTest.java
index 78c61d7..977553b 100644
--- a/commons-numbers-complex/src/test/java/org/apache/commons/numbers/complex/ComplexTest.java
+++ b/commons-numbers-complex/src/test/java/org/apache/commons/numbers/complex/ComplexTest.java
@@ -1299,4 +1299,13 @@ public class ComplexTest {
TestUtils.assertEquals(Complex.ONE, Complex.ofCartesian(0, 25).tan(), 0);
TestUtils.assertEquals(Complex.ofCartesian(0, -1), Complex.ofCartesian(0, -25).tan(), 0);
}
+
+ @Test
+ public void testAtanhEdgeConditions() {
+ // Hits the edge case when imaginary == 0 but real != 0 or 1
+ final Complex c = Complex.ofCartesian(2, 0).atanh();
+ // Answer from g++
+ Assertions.assertEquals(0.54930614433405489, c.getReal());
+ Assertions.assertEquals(1.5707963267948966, c.getImaginary());
+ }
}