| ... |
... |
@@ -602,17 +602,19 @@ |
|
602
|
602
|
;; In particular iteration 1 and 3 are added. Iteration 2 and 4 were
|
|
603
|
603
|
;; not added. The test examples from iteration 2 and 4 didn't change
|
|
604
|
604
|
;; with or without changes added.
|
|
605
|
|
-(let* (;; This is the value of Scilab's %eps variable.
|
|
606
|
|
- (eps (scale-float 1d0 -52))
|
|
607
|
|
- (rmin least-positive-normalized-double-float)
|
|
608
|
|
- (rbig (/ most-positive-double-float 2))
|
|
609
|
|
- (rmin2 (scale-float 1d0 -53))
|
|
610
|
|
- (rminscal (scale-float 1d0 51))
|
|
611
|
|
- (rmax2 (* rbig rmin2))
|
|
612
|
|
- (be (/ 2 (* eps eps)))
|
|
613
|
|
- (2/eps (/ 2 eps)))
|
|
|
605
|
+(let* ((+eps+ (scale-float 1d0 -52))
|
|
|
606
|
+ (+rmin+ least-positive-normalized-double-float)
|
|
|
607
|
+ (+rbig+ (/ most-positive-double-float 2))
|
|
|
608
|
+ (+rmin2+ (scale-float 1d0 -53))
|
|
|
609
|
+ (+rminscal+ (scale-float 1d0 51))
|
|
|
610
|
+ (+rmax2+ (* +rbig+ +rmin2+))
|
|
|
611
|
+ (+be+ (/ 2 (* +eps+ +eps+)))
|
|
|
612
|
+ (+2/eps+ (/ 2 +eps+)))
|
|
|
613
|
+ (declare (double-float +eps+ +rmin+ +rbig+ +rmin2+
|
|
|
614
|
+ +rminscal+ +rmax2+ +be+ +2/eps+))
|
|
614
|
615
|
(defun cdiv-double-float (x y)
|
|
615
|
|
- (declare (type (complex double-float) x y))
|
|
|
616
|
+ (declare (type (complex double-float) x y)
|
|
|
617
|
+ (optimize (speed 3) (safety 0)))
|
|
616
|
618
|
(labels
|
|
617
|
619
|
((internal-compreal (a b c d r tt)
|
|
618
|
620
|
(declare (double-float a b c d r tt))
|
| ... |
... |
@@ -634,7 +636,7 @@ |
|
634
|
636
|
(progn
|
|
635
|
637
|
(format t "a,b,c,d = ~A ~A ~A ~A~%" a b c d)
|
|
636
|
638
|
(format t " r, tt = ~A ~A~%" r tt))
|
|
637
|
|
- (cond ((>= (abs r) rmin)
|
|
|
639
|
+ (cond ((>= (abs r) +rmin+)
|
|
638
|
640
|
(let ((br (* b r)))
|
|
639
|
641
|
#+nil
|
|
640
|
642
|
(format t "br = ~A~%" br)
|
| ... |
... |
@@ -678,43 +680,47 @@ |
|
678
|
680
|
(b (imagpart x))
|
|
679
|
681
|
(c (realpart y))
|
|
680
|
682
|
(d (imagpart y)))
|
|
681
|
|
- (flet ((maybe-scale (abs-tst)
|
|
|
683
|
+ (declare (double-float a b c d))
|
|
|
684
|
+ (flet ((maybe-scale (abs-tst a b c d)
|
|
|
685
|
+ (declare (double-float a b c d))
|
|
682
|
686
|
;; This implements McGehearty's iteration 3 to
|
|
683
|
687
|
;; handle the case when some values are too big
|
|
684
|
688
|
;; and should be scaled down. Also if some
|
|
685
|
689
|
;; values are too tiny, scale them up.
|
|
686
|
690
|
(let ((abs-a (abs a))
|
|
687
|
691
|
(abs-b (abs b)))
|
|
688
|
|
- (if (or (> abs-tst rbig)
|
|
689
|
|
- (> abs-a rbig)
|
|
690
|
|
- (> abs-b rbig))
|
|
|
692
|
+ (if (or (> abs-tst +rbig+)
|
|
|
693
|
+ (> abs-a +rbig+)
|
|
|
694
|
+ (> abs-b +rbig+))
|
|
691
|
695
|
(setf a (* a 0.5d0)
|
|
692
|
696
|
b (* b 0.5d0)
|
|
693
|
697
|
c (* c 0.5d0)
|
|
694
|
698
|
d (* d 0.5d0))
|
|
695
|
|
- (if (< abs-tst rmin2)
|
|
696
|
|
- (setf a (* a rminscal)
|
|
697
|
|
- b (* b rminscal)
|
|
698
|
|
- c (* c rminscal)
|
|
699
|
|
- d (* d rminscal))
|
|
700
|
|
- (if (or (and (< abs-a rmin)
|
|
701
|
|
- (< abs-b rmax2)
|
|
702
|
|
- (< abs-tst rmax2))
|
|
703
|
|
- (and (< abs-b rmin)
|
|
704
|
|
- (< abs-a rmax2)
|
|
705
|
|
- (< abs-tst rmax2)))
|
|
706
|
|
- (setf a (* a rminscal)
|
|
707
|
|
- b (* b rminscal)
|
|
708
|
|
- c (* c rminscal)
|
|
709
|
|
- d (* d rminscal))))))))
|
|
|
699
|
+ (if (< abs-tst +rmin2+)
|
|
|
700
|
+ (setf a (* a +rminscal+)
|
|
|
701
|
+ b (* b +rminscal+)
|
|
|
702
|
+ c (* c +rminscal+)
|
|
|
703
|
+ d (* d +rminscal+))
|
|
|
704
|
+ (if (or (and (< abs-a +rmin+)
|
|
|
705
|
+ (< abs-b +rmax2+)
|
|
|
706
|
+ (< abs-tst +rmax2+))
|
|
|
707
|
+ (and (< abs-b +rmin+)
|
|
|
708
|
+ (< abs-a +rmax2+)
|
|
|
709
|
+ (< abs-tst +rmax2+)))
|
|
|
710
|
+ (setf a (* a +rminscal+)
|
|
|
711
|
+ b (* b +rminscal+)
|
|
|
712
|
+ c (* c +rminscal+)
|
|
|
713
|
+ d (* d +rminscal+)))))
|
|
|
714
|
+ (values a b c d))))
|
|
710
|
715
|
(cond
|
|
711
|
716
|
((<= (abs d) (abs c))
|
|
712
|
717
|
;; |d| <= |c|, so we can use robust-subinternal to
|
|
713
|
718
|
;; perform the division.
|
|
714
|
|
- (maybe-scale (abs c))
|
|
715
|
|
- (multiple-value-bind (e f)
|
|
716
|
|
- (robust-subinternal a b c d)
|
|
717
|
|
- (complex e f)))
|
|
|
719
|
+ (multiple-value-bind (a b c d)
|
|
|
720
|
+ (maybe-scale (abs c) a b c d)
|
|
|
721
|
+ (multiple-value-bind (e f)
|
|
|
722
|
+ (robust-subinternal a b c d)
|
|
|
723
|
+ (complex e f))))
|
|
718
|
724
|
(t
|
|
719
|
725
|
;; |d| > |c|. So, instead compute
|
|
720
|
726
|
;;
|
| ... |
... |
@@ -724,10 +730,11 @@ |
|
724
|
730
|
;; realpart of the former is the same, but the
|
|
725
|
731
|
;; imagpart of the former is the negative of the
|
|
726
|
732
|
;; desired division.
|
|
727
|
|
- (maybe-scale (abs d))
|
|
728
|
|
- (multiple-value-bind (e f)
|
|
729
|
|
- (robust-subinternal b a d c)
|
|
730
|
|
- (complex e (- f)))))))))
|
|
|
733
|
+ (multiple-value-bind (a b c d)
|
|
|
734
|
+ (maybe-scale (abs d) a b c d)
|
|
|
735
|
+ (multiple-value-bind (e f)
|
|
|
736
|
+ (robust-subinternal b a d c)
|
|
|
737
|
+ (complex e (- f))))))))))
|
|
731
|
738
|
(let* ((a (realpart x))
|
|
732
|
739
|
(b (imagpart x))
|
|
733
|
740
|
(c (realpart y))
|
| ... |
... |
@@ -735,22 +742,23 @@ |
|
735
|
742
|
(ab (max (abs a) (abs b)))
|
|
736
|
743
|
(cd (max (abs c) (abs d)))
|
|
737
|
744
|
(s 1d0))
|
|
|
745
|
+ (declare (double-float s))
|
|
738
|
746
|
;; If a or b is big, scale down a and b.
|
|
739
|
|
- (when (>= ab rbig)
|
|
|
747
|
+ (when (>= ab +rbig+)
|
|
740
|
748
|
(setf x (/ x 2)
|
|
741
|
749
|
s (* s 2)))
|
|
742
|
750
|
;; If c or d is big, scale down c and d.
|
|
743
|
|
- (when (>= cd rbig)
|
|
|
751
|
+ (when (>= cd +rbig+)
|
|
744
|
752
|
(setf y (/ y 2)
|
|
745
|
753
|
s (/ s 2)))
|
|
746
|
754
|
;; If a or b is tiny, scale up a and b.
|
|
747
|
|
- (when (<= ab (* rmin 2/eps))
|
|
748
|
|
- (setf x (* x be)
|
|
749
|
|
- s (/ s be)))
|
|
|
755
|
+ (when (<= ab (* +rmin+ +2/eps+))
|
|
|
756
|
+ (setf x (* x +be+)
|
|
|
757
|
+ s (/ s +be+)))
|
|
750
|
758
|
;; If c or d is tiny, scale up c and d.
|
|
751
|
|
- (when (<= cd (* rmin 2/eps))
|
|
752
|
|
- (setf y (* y be)
|
|
753
|
|
- s (* s be)))
|
|
|
759
|
+ (when (<= cd (* +rmin+ +2/eps+))
|
|
|
760
|
+ (setf y (* y +be+)
|
|
|
761
|
+ s (* s +be+)))
|
|
754
|
762
|
(* s
|
|
755
|
763
|
(robust-internal x y))))))
|
|
756
|
764
|
|