(module cdf-beta-inc mzscheme
(provide
(all-defined))
(require "../machine.ss")
(require "../math.ss")
(require "../special-functions/beta.ss")
(define (beta-cont-frac a b x epsabs)
(define max-iter 512)
(define cutoff (* 2.0 double-min))
(let ((iter-count 0)
(cf 0.0)
(num-term 1.0)
(den-term (- 1.0 (/ (* (+ a b) x) (+ a 1.0)))))
(if (< (abs den-term) cutoff)
(set! den-term +nan.0))
(set! den-term (/ 1.0 den-term))
(set! cf den-term)
(let loop ()
(when (< iter-count max-iter)
(let* ((k (+ iter-count 1))
(coeff (/ (* k (- b k) x)
(* (+ (- a 1.0) (* 2 k))
(+ a (* 2 k)))))
(delta-frac 0.0))
(set! den-term (+ 1.0 (* coeff den-term)))
(set! num-term (+ 1.0 (/ coeff num-term)))
(if (< (abs den-term) cutoff)
(set! den-term +nan.0))
(if (< (abs num-term) cutoff)
(set! num-term +nan.0))
(set! den-term (/ 1.0 den-term))
(set! delta-frac (* den-term num-term))
(set! cf (* cf delta-frac))
(set! coeff (/ (* (- (+ a k)) (+ a b k) x)
(* (+ a (* 2 k)) (+ a (* 2 k) 1.0))))
(set! den-term (+ 1.0 (* coeff den-term)))
(set! num-term (+ 1.0 (/ coeff num-term)))
(if (< (abs den-term) cutoff)
(set! den-term +nan.0))
(if (< (abs num-term) cutoff)
(set! num-term +nan.0))
(set! den-term (/ 1.0 den-term))
(set! delta-frac (* den-term num-term))
(set! cf (* cf delta-frac))
(when (and (>= (- delta-frac 1.0) (* 2.0 double-epsilon))
(>= (* cf (abs (- delta-frac 1.0))) epsabs))
(set! iter-count (+ iter-count 1))
(loop)))))
(if (>= iter-count max-iter)
+nan.0
cf)))
(define (beta-inc-axpy acap ycap a b x)
(cond ((= x 0.0)
(+ (* acap 0) ycap))
((= x 1.0)
(+ (* acap 1) ycap))
(else
(let* ((ln-beta (lnbeta a b))
(ln-pre (+ (- ln-beta)
(* a (log x))
(* b (log1p (- x)))))
(prefactor (exp ln-pre)))
(if (< x (/ (+ a 1.0) (+ a b 2.0)))
(let* ((epsabs (* (abs (/ ycap
(/ (* acap prefactor)
a)))
double-epsilon))
(cf (beta-cont-frac a b x epsabs)))
(+ (* acap (/ (* prefactor cf) a)) ycap))
(let* ((epsabs (* (abs (/ (+ acap ycap)
(/ (* acap prefactor)
b)))
double-epsilon))
(cf (beta-cont-frac b a (- 1.0 x) epsabs))
(term (/ (* prefactor cf) b)))
(if (= acap (- ycap))
(* (- acap) term)
(+ (* acap (- 1.0 term))
ycap))))))))
)