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/20 17:58:00 UTC
[commons-numbers] 09/30: Compute log() within a safe region without
using the sqrt.
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 <ah...@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.