Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
47 changes: 39 additions & 8 deletions ops/core.rkt
Original file line number Diff line number Diff line change
Expand Up @@ -105,6 +105,7 @@
ival-==
ival-!=
ival-if
ival-mobilize
ival-and
ival-or
ival-not
Expand Down Expand Up @@ -661,16 +662,46 @@
(ival (endpoint lo #f) (endpoint hi #f) err? err))

(define (ival-fmin x y)
(ival (endpoint-min2 (ival-lo x) (ival-lo y) 'down)
(endpoint-min2 (ival-hi x) (ival-hi y) 'up)
(or (ival-err? x) (ival-err? y))
(or (ival-err x) (ival-err y))))
(match-define (ival (endpoint xlo xlo!) (endpoint xhi xhi!) xerr? xerr) x)
(match-define (ival (endpoint ylo ylo!) (endpoint yhi yhi!) yerr? yerr) y)
(define lo (bf 0))
(define hi (bf 0))
(define lo-exact? (= 0 (mpfr-min! lo xlo ylo 'down)))
(define hi-exact? (= 0 (mpfr-min! hi xhi yhi 'up)))
;; For lower endpoints (which can only move upward under refinement),
;; a fixed minimum is stable if one fixed endpoint is <= the other.
(define lo-stable?
(cond
[(and xlo! ylo!) #t]
[xlo! (bflte? xlo ylo)]
[ylo! (bflte? ylo xlo)]
[else #f]))
(define lo! (and lo-exact? lo-stable?))
;; For upper endpoints (which can only move downward), a fixed minimum is
;; only guaranteed when both endpoints are fixed.
(define hi! (and hi-exact? xhi! yhi!))
(ival (endpoint lo lo!) (endpoint hi hi!) (or xerr? yerr?) (or xerr yerr)))

(define (ival-fmax x y)
(ival (endpoint-max2 (ival-lo x) (ival-lo y) 'down)
(endpoint-max2 (ival-hi x) (ival-hi y) 'up)
(or (ival-err? x) (ival-err? y))
(or (ival-err x) (ival-err y))))
(match-define (ival (endpoint xlo xlo!) (endpoint xhi xhi!) xerr? xerr) x)
(match-define (ival (endpoint ylo ylo!) (endpoint yhi yhi!) yerr? yerr) y)
(define lo (bf 0))
(define hi (bf 0))
(define lo-exact? (= 0 (mpfr-max! lo xlo ylo 'down)))
(define hi-exact? (= 0 (mpfr-max! hi xhi yhi 'up)))
;; For lower endpoints (which can only move upward), a fixed maximum is
;; only guaranteed when both endpoints are fixed.
(define lo! (and lo-exact? xlo! ylo!))
;; For upper endpoints (which can only move downward), a fixed maximum is
;; stable if one fixed endpoint is >= the other.
(define hi-stable?
(cond
[(and xhi! yhi!) #t]
[xhi! (bfgte? xhi yhi)]
[yhi! (bfgte? yhi xhi)]
[else #f]))
(define hi! (and hi-exact? hi-stable?))
(ival (endpoint lo lo!) (endpoint hi hi!) (or xerr? yerr?) (or xerr yerr)))

(define (ival-copysign x y)
(match-define (ival xlo xhi xerr? xerr) (ival-fabs x))
Expand Down
7 changes: 6 additions & 1 deletion ops/pow.rkt
Original file line number Diff line number Diff line change
Expand Up @@ -161,4 +161,9 @@
[(or (= (mpfr-sign (ival-lo-val x)) 1) (bfzero? (ival-lo-val x))) (ival-pow-pos x y)]
[else
(define-values (neg pos) (split-ival x 0.bf))
(ival-union (ival-pow-neg neg y) (ival-pow-pos pos y))]))
(define out (ival-union (ival-pow-neg neg y) (ival-pow-pos pos y)))
;; If x straddles 0 with movable endpoints, a refinement can drop one
;; branch entirely, so branch-derived endpoint fixedness is not stable.
(if (and (ival-lo-fixed? x) (ival-hi-fixed? x))
out
(ival-mobilize out))]))