| ... |
... |
@@ -729,59 +729,58 @@ |
|
729
|
729
|
(defun ,internal (a b c d)
|
|
730
|
730
|
(declare (,type a b c d)
|
|
731
|
731
|
,@opt)
|
|
732
|
|
- (let ()
|
|
733
|
|
- (flet ((maybe-scale (abs-tst a b c d)
|
|
734
|
|
- (declare (,type a b c d))
|
|
735
|
|
- ;; This implements McGehearty's iteration 3 to
|
|
736
|
|
- ;; handle the case when some values are too big
|
|
737
|
|
- ;; and should be scaled down. Also if some
|
|
738
|
|
- ;; values are too tiny, scale them up.
|
|
739
|
|
- (let ((abs-a (abs a))
|
|
740
|
|
- (abs-b (abs b)))
|
|
741
|
|
- (if (or (> abs-tst ,+rbig+)
|
|
742
|
|
- (> abs-a ,+rbig+)
|
|
743
|
|
- (> abs-b ,+rbig+))
|
|
744
|
|
- (setf a (* a 0.5d0)
|
|
745
|
|
- b (* b 0.5d0)
|
|
746
|
|
- c (* c 0.5d0)
|
|
747
|
|
- d (* d 0.5d0))
|
|
748
|
|
- (if (< abs-tst ,+rmin2+)
|
|
749
|
|
- (setf a (* a ,+rminscal+)
|
|
750
|
|
- b (* b ,+rminscal+)
|
|
751
|
|
- c (* c ,+rminscal+)
|
|
752
|
|
- d (* d ,+rminscal+))
|
|
753
|
|
- (if (or (and (< abs-a ,+rmin+)
|
|
754
|
|
- (< abs-b ,+rmax2+)
|
|
755
|
|
- (< abs-tst ,+rmax2+))
|
|
756
|
|
- (and (< abs-b ,+rmin+)
|
|
757
|
|
- (< abs-a ,+rmax2+)
|
|
758
|
|
- (< abs-tst ,+rmax2+)))
|
|
759
|
|
- (setf a (* a ,+rminscal+)
|
|
760
|
|
- b (* b ,+rminscal+)
|
|
761
|
|
- c (* c ,+rminscal+)
|
|
762
|
|
- d (* d ,+rminscal+)))))
|
|
763
|
|
- (values a b c d))))
|
|
764
|
|
- (cond
|
|
765
|
|
- ((<= (abs d) (abs c))
|
|
766
|
|
- ;; |d| <= |c|, so we can use robust-subinternal to
|
|
767
|
|
- ;; perform the division.
|
|
768
|
|
- (multiple-value-bind (a b c d)
|
|
769
|
|
- (maybe-scale (abs c) a b c d)
|
|
770
|
|
- (,subinternal a b c d)))
|
|
771
|
|
- (t
|
|
772
|
|
- ;; |d| > |c|. So, instead compute
|
|
773
|
|
- ;;
|
|
774
|
|
- ;; (b + i*a)/(d + i*c) = ((b*d+a*c) + (a*d-b*c)*i)/(d^2+c^2)
|
|
775
|
|
- ;;
|
|
776
|
|
- ;; Compare this to (a+i*b)/(c+i*d) and we see that
|
|
777
|
|
- ;; realpart of the former is the same, but the
|
|
778
|
|
- ;; imagpart of the former is the negative of the
|
|
779
|
|
- ;; desired division.
|
|
780
|
|
- (multiple-value-bind (a b c d)
|
|
781
|
|
- (maybe-scale (abs d) a b c d)
|
|
782
|
|
- (multiple-value-bind (e f)
|
|
783
|
|
- (,subinternal b a d c)
|
|
784
|
|
- (values e (- f)))))))))
|
|
|
732
|
+ (flet ((maybe-scale (abs-tst a b c d)
|
|
|
733
|
+ (declare (,type a b c d))
|
|
|
734
|
+ ;; This implements McGehearty's iteration 3 to
|
|
|
735
|
+ ;; handle the case when some values are too big
|
|
|
736
|
+ ;; and should be scaled down. Also if some
|
|
|
737
|
+ ;; values are too tiny, scale them up.
|
|
|
738
|
+ (let ((abs-a (abs a))
|
|
|
739
|
+ (abs-b (abs b)))
|
|
|
740
|
+ (if (or (> abs-tst ,+rbig+)
|
|
|
741
|
+ (> abs-a ,+rbig+)
|
|
|
742
|
+ (> abs-b ,+rbig+))
|
|
|
743
|
+ (setf a (* a 0.5d0)
|
|
|
744
|
+ b (* b 0.5d0)
|
|
|
745
|
+ c (* c 0.5d0)
|
|
|
746
|
+ d (* d 0.5d0))
|
|
|
747
|
+ (if (< abs-tst ,+rmin2+)
|
|
|
748
|
+ (setf a (* a ,+rminscal+)
|
|
|
749
|
+ b (* b ,+rminscal+)
|
|
|
750
|
+ c (* c ,+rminscal+)
|
|
|
751
|
+ d (* d ,+rminscal+))
|
|
|
752
|
+ (if (or (and (< abs-a ,+rmin+)
|
|
|
753
|
+ (< abs-b ,+rmax2+)
|
|
|
754
|
+ (< abs-tst ,+rmax2+))
|
|
|
755
|
+ (and (< abs-b ,+rmin+)
|
|
|
756
|
+ (< abs-a ,+rmax2+)
|
|
|
757
|
+ (< abs-tst ,+rmax2+)))
|
|
|
758
|
+ (setf a (* a ,+rminscal+)
|
|
|
759
|
+ b (* b ,+rminscal+)
|
|
|
760
|
+ c (* c ,+rminscal+)
|
|
|
761
|
+ d (* d ,+rminscal+)))))
|
|
|
762
|
+ (values a b c d))))
|
|
|
763
|
+ (cond
|
|
|
764
|
+ ((<= (abs d) (abs c))
|
|
|
765
|
+ ;; |d| <= |c|, so we can use robust-subinternal to
|
|
|
766
|
+ ;; perform the division.
|
|
|
767
|
+ (multiple-value-bind (a b c d)
|
|
|
768
|
+ (maybe-scale (abs c) a b c d)
|
|
|
769
|
+ (,subinternal a b c d)))
|
|
|
770
|
+ (t
|
|
|
771
|
+ ;; |d| > |c|. So, instead compute
|
|
|
772
|
+ ;;
|
|
|
773
|
+ ;; (b + i*a)/(d + i*c) = ((b*d+a*c) + (a*d-b*c)*i)/(d^2+c^2)
|
|
|
774
|
+ ;;
|
|
|
775
|
+ ;; Compare this to (a+i*b)/(c+i*d) and we see that
|
|
|
776
|
+ ;; realpart of the former is the same, but the
|
|
|
777
|
+ ;; imagpart of the former is the negative of the
|
|
|
778
|
+ ;; desired division.
|
|
|
779
|
+ (multiple-value-bind (a b c d)
|
|
|
780
|
+ (maybe-scale (abs d) a b c d)
|
|
|
781
|
+ (multiple-value-bind (e f)
|
|
|
782
|
+ (,subinternal b a d c)
|
|
|
783
|
+ (values e (- f))))))))
|
|
785
|
784
|
(defun ,name (a b c d)
|
|
786
|
785
|
,docstring
|
|
787
|
786
|
(declare (,type a b c d)
|