[cmucl-commit] [git] CMU Common Lisp branch master updated. snapshot-2013-12-a-26-gb71b7c8

Raymond Toy rtoy at common-lisp.net
Sat Dec 21 02:12:14 UTC 2013


This is an automated email from the git hooks/post-receive script. It was
generated because a ref change was pushed to the repository containing
the project "CMU Common Lisp".

The branch, master has been updated
       via  b71b7c854469191e462162c9d11d0c35222a284a (commit)
      from  712df0bc4e655226bc5c9ed91aa9c875b4a5eb0d (commit)

Those revisions listed above that are new to this repository have
not appeared on any other notification email; so we list those
revisions in full, below.

- Log -----------------------------------------------------------------
commit b71b7c854469191e462162c9d11d0c35222a284a
Author: Raymond Toy <toy.raymond at gmail.com>
Date:   Fri Dec 20 18:12:03 2013 -0800

    Increase accuracy of tan near multiples of pi/4.
    
    code/irrat-dd.lisp
    o Make REDUCE-ARG return an extra result.  Since the reduction returns
      3 double's, return a double-double result and the third double
      result for extra accuracy
    o Update dd-%tan and dd-%%tan to take the extra arg.
    o Add new constant dd-pi/4-lo.
    o Increase accuracy of tan by using the relationship
      tan(pi/4-y)=(1-tan(y))/(1+tan(y)).
    
    tests/trig.lisp:
    o Update the allowed error threshold for two tests to reflect the
      increased accuracy.

diff --git a/src/code/irrat-dd.lisp b/src/code/irrat-dd.lisp
index 381d678..2eabb58 100644
--- a/src/code/irrat-dd.lisp
+++ b/src/code/irrat-dd.lisp
@@ -56,6 +56,12 @@
   0.7853981633974483096156608458198757210492923w0
   _N"Pi/4")
 
+;; dd-pi/4-lo is such that dd-pi/4-lo + dd-pi/4 is equal to pi/4 to
+;; twice the precision of a double-double-float.
+(defconstant dd-pi/4-lo
+  -7.486924524295848886603985669688687133352026408988280860093283232w-34
+  )
+
 ;; log2-c1 and log-c2 are log(2) arranged in such a way that log2-c1 +
 ;; log2-c2 is log(2) to an accuracy greater than double-double-float.
 (defconstant log2-c1
@@ -1072,9 +1078,24 @@ pi/4    11001001000011111101101010100010001000010110100011000 010001101001100010
 	  (/ y)
 	  y))))
 
-(defun dd-%%tan (x)
-  (declare (type double-double-float x))
-  (dd-tancot x nil))
+(defun dd-%%tan (x extra)
+  (declare (type double-double-float x)
+	   (double-float extra))
+  (cond ((>= (abs x) 0.6744)
+	 ;; For 0.6744 <= |x| <= pi/4, we want to use the relationship
+	 ;;
+	 ;;   tan(x) = tan(pi/4-y) = (1 - tan(y))/(1 + tan(y))
+	 ;;          = 1 - 2*(tan(y) - tan(y)^2)/(1+tan(y))
+	 (if (minusp x)
+	     (- (dd-%%tan (- x) (- extra)))
+	     (let* ((z (- dd-pi/4 x))
+		    (w (- dd-pi/4-lo extra))
+		    (tan (dd-tancot (+ z w) nil)))
+	       (- 1
+		  (/ (* 2 (- tan (* tan tan)))
+		     (+ 1 tan))))))
+	(t
+	 (dd-tancot x nil))))
 
 (declaim (inline %kernel-rem-pi/2))
 (alien:def-alien-routine ("__kernel_rem_pio2" %kernel-rem-pi/2) c-call:int
@@ -1139,10 +1160,9 @@ pi/4    11001001000011111101101010100010001000010110100011000 010001101001100010
 				 (length parts)
 				 3
 				 (vector-sap two-over-pi))))
-	   (sum (+ (coerce (aref y 2) 'double-double-float)
-		   (coerce (aref y 1) 'double-double-float)
+	   (sum (+ (coerce (aref y 1) 'double-double-float)
 		   (coerce (aref y 0) 'double-double-float))))
-      (values n sum))))
+      (values n sum (aref y 2)))))
 			       
 
 (declaim (ftype (function (double-double-float) double-double-float)
@@ -1181,15 +1201,15 @@ pi/4    11001001000011111101101010100010001000010110100011000 010001101001100010
 		dd-%tan))
 (defun dd-%tan (x)
   (declare (double-double-float x))
-  (cond ((< (abs x) (/ pi 4))
-	 (dd-%%tan x))
+  (cond ((<= (abs x) (/ pi 4))
+	 (dd-%%tan x 0d0))
 	(t
 	 ;; Argument reduction needed
-	 (multiple-value-bind (n reduced)
+	 (multiple-value-bind (n reduced extra)
 	     (reduce-arg x)
 	   (if (evenp n)
-	       (dd-%%tan reduced)
-	       (- (/ (dd-%%tan reduced))))))))
+	       (dd-%%tan reduced extra)
+	       (- (/ (dd-%%tan reduced extra))))))))
 
 (defun dd-%sincos (x)
   (declare (double-double-float x))
diff --git a/src/tests/trig.lisp b/src/tests/trig.lisp
index b46c904..58d5440 100644
--- a/src/tests/trig.lisp
+++ b/src/tests/trig.lisp
@@ -376,12 +376,12 @@
   (assert-eq t (rel-or-abs-error
 		(tan (* 7/4 kernel:dd-pi))
 		-1.000000000000000000000000000000001844257310064121018312678894979w0
-		6.467w-33))
+		3.422w-49))
   ;; Test for argument reduction with n odd
   (assert-eq t (rel-or-abs-error
 		(tan (* 9/4 kernel:dd-pi))
 		1.000000000000000000000000000000025802415787810837455445433037983w0
-		5.773w-33))
+		0w0))
   ;; Test for argument reduction, big value
   (assert-eq t (rel-or-abs-error
 		(tan (scale-float 1w0 120))

-----------------------------------------------------------------------

Summary of changes:
 src/code/irrat-dd.lisp |   42 +++++++++++++++++++++++++++++++-----------
 src/tests/trig.lisp    |    4 ++--
 2 files changed, 33 insertions(+), 13 deletions(-)


hooks/post-receive
-- 
CMU Common Lisp


More information about the cmucl-commit mailing list