From 894af6c4aaa3b83f3c13d2e59735c33f79abdc20 Mon Sep 17 00:00:00 2001
From: Raymond Toy <toy.raymond@gmail.com>
Date: Mon, 23 Dec 2013 10:40:03 -0800
Subject: [PATCH] Add tests for the branch cut for atanh.  Not clear that this
 is correct because atanh(-2) appears to be wrong.

---
 tests/trig.lisp | 63 +++++++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 63 insertions(+)

diff --git a/tests/trig.lisp b/tests/trig.lisp
index 9565ef54a..05437e586 100644
--- a/tests/trig.lisp
+++ b/tests/trig.lisp
@@ -725,3 +725,66 @@
       (get-signs (acosh-def #c(0.25d0 -1d-20)))
     (assert-true (check-signs #'acosh #c(0.25d0 -0d0) tr ti))
     (assert-true (check-signs #'acosh #c(0.25w0 -0w0) tr ti))))
+
+;; atanh(z) = 1/2*(log(1+z) - log(1-z))
+;;
+;; The branch cut is on the real axis for |x| > 1.  For x < -1, it is
+;; continuous with Quadrant III.  For x > 1, it is continuous with
+;; quadrant I.
+;;
+;; NOTE: The rules above are what is given by the CLHS. However,
+;; consider the value of atanh(-2) and atanh(-2-0.0*i)
+;;
+;;  atanh(-2) = 1/2*(log(1-2) - log(1+2))
+;;            = 1/2*(log(-1) - log(3))
+;;            = 1/2*(i*pi - log(3))
+;;            = -1/2*log(3) + i*pi/2
+;;
+;;  atanh(-2-0*i) = 1/2*(log(1+(-2-0*i)) - log(1-(-2-0*i)))
+;;                = 1/2*(log(-1-0*i) - log(3-0*i))
+;;                = 1/2*(-i*pi - log(3))
+;;                = -1/2*log(3) - i*pi/2
+;;
+;;  atanh(-2+0*i) = 1/2*(log(1+(-2+0*i)) - log(1-(-2+0*i)))
+;;                = 1/2*(log(-1+0*i) - log(3-0*i))
+;;                = 1/2*(i*pi - log(3))
+;;                = -1/2*log(3) + i*pi/2
+;;
+;; Thus, atanh(-2) is continuous with Quadrant II, NOT continuous with
+;; Quadrant III!
+;;
+;; What do we do?
+(defun atanh-def (z)
+  (r*z 1/2
+       (- (log (1+z z))
+	  (log (1-z z)))))
+
+(define-test branch-cut.atanh
+  (:tag :atanh :branch-cuts)
+  ;; Test for x < -1, which is continuous with Quadrant III.  Use the
+  ;; the value at #c(-2d0 -1d-20) as the reference.
+  (multiple-value-bind (tr ti)
+      (get-signs (atanh-def #c(-2d0 -1d-20)))
+    (assert-true (check-signs #'atanh -2d0 tr ti))
+    (assert-true (check-signs #'atanh -2w0 tr ti))
+    (assert-true (check-signs #'atanh #c(-2d0 -0d0) tr ti))
+    (assert-true (check-signs #'atanh #c(-2w0 -0w0) tr ti)))
+  ;; Test the other side of the branch cut for x < -1.
+  (multiple-value-bind (tr ti)
+      (get-signs (atanh-def #c(-2d0 +1d-20)))
+    (assert-true (check-signs #'atanh #c(-2d0 0d0) tr ti))
+    (assert-true (check-signs #'atanh #c(-2w0 0w0) tr ti)))
+
+  ;; Test for x > 1, which is continuous with Quadrant I, using the
+  ;; value at #c(+2d0 1d-10) as the reference
+  (multiple-value-bind (tr ti)
+      (get-signs (atanh-def #c(2d0 1d-20)))
+    (assert-true (check-signs #'atanh 2d0 tr ti))
+    (assert-true (check-signs #'atanh 2w0 tr ti))
+    (assert-true (check-signs #'atanh #c(2d0 0) tr ti))
+    (assert-true (check-signs #'atanh #c(2w0 0) tr ti)))
+  ;; Test the other side of the branch cut for x > 1.
+  (multiple-value-bind (tr ti)
+      (get-signs (atanh-def #c(2d0 -1d-20)))
+    (assert-true (check-signs #'atanh #c(2d0 -0d0) tr ti))
+    (assert-true (check-signs #'atanh #c(2w0 -0w0) tr ti))))
-- 
GitLab