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 67dc19de65579b1a3335919e6459b8946d1fae75 Author: aherbert <aherb...@apache.org> AuthorDate: Thu Dec 19 16:49:25 2019 +0000 Compute log() within a safe region without using the sqrt. --- .../java/org/apache/commons/numbers/complex/Complex.java | 12 ++++++++++++ 1 file changed, 12 insertions(+) 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 7577ddf..11f468f 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 @@ -2097,6 +2097,18 @@ public final class Complex implements Serializable { private Complex log(UnaryOperation log, double logOf2, ComplexConstructor constructor) { // All ISO C99 edge cases satisfied by the Math library. // Make computation overflow safe. + + // Note: + // log(|a + b i|) = log(sqrt(a^2 + b^2)) = 0.5 * log(a^2 + b^2) + // If real and imaginary are with a safe region then omit the sqrt(). + final double x = Math.abs(real); + final double y = Math.abs(imaginary); + + // Use the safe region defined for atanh to avoid over/underflow for x^2 + if ((x > SAFE_LOWER) && (x < SAFE_UPPER) && (y > SAFE_LOWER) && (y < SAFE_UPPER)) { + return constructor.create(0.5 * log.apply(x * x + y * y), arg()); + } + final double abs = abs(); if (abs == Double.POSITIVE_INFINITY && isFinite()) { // Edge-case where the |a + b i| overflows.