|
5 | 5 | (low nil :type (or null real (cons real null))) |
6 | 6 | (high nil :type (or null real (cons real null)))) |
7 | 7 |
|
| 8 | +(defun make-unbounded-interval () (make-interval nil nil)) |
| 9 | +(defun make-empty-interval () (make-interval '(0) '(0))) |
| 10 | + |
8 | 11 | (defun bound-parts (finite-bound) |
9 | 12 | (if (consp finite-bound) |
10 | 13 | (values (car finite-bound) t) |
|
21 | 24 | (let ((r (funcall unop b))) |
22 | 25 | (if bxp (list r) r)))) |
23 | 26 |
|
| 27 | +(defun empty-interval-p (interval) |
| 28 | + (let ((low (interval-low interval)) (high (interval-high interval))) |
| 29 | + (and low high |
| 30 | + (multiple-value-bind (low lxp) (bound-parts low) |
| 31 | + (multiple-value-bind (high hxp) (bound-parts high) |
| 32 | + (or (> low high) (and (= low high) (or lxp hxp)))))))) |
| 33 | + |
| 34 | +(defun intervals-disjoint-p (i1 i2) |
| 35 | + (let ((i1l (interval-low i1)) (i2l (interval-low i2)) |
| 36 | + (i1h (interval-high i1)) (i2h (interval-high i2))) |
| 37 | + (or (and i1h i2l |
| 38 | + (multiple-value-bind (i1high i1hxp) (bound-parts i1h) |
| 39 | + (multiple-value-bind (i2low i2lxp) (bound-parts i2l) |
| 40 | + (or (< i1high i2low) |
| 41 | + (and (= i1high i2low) (or i1hxp i2lxp)))))) |
| 42 | + (and i2h i1l |
| 43 | + (multiple-value-bind (i2high i2hxp) (bound-parts i2h) |
| 44 | + (multiple-value-bind (i1low i1lxp) (bound-parts i1l) |
| 45 | + (or (< i2high i1low) |
| 46 | + (and (= i2high i1low) (or i2hxp i1lxp))))))))) |
| 47 | + |
24 | 48 | (defun interval+ (i1 i2) |
25 | 49 | (make-interval |
26 | 50 | (let ((l1 (interval-low i1)) (l2 (interval-low i2))) |
|
35 | 59 | (let ((low (interval-low interval))) |
36 | 60 | (if low (finite-bound-unop #'- low) nil)))) |
37 | 61 |
|
| 62 | +(defun interval-= (i1 i2) |
| 63 | + (let ((i1l (interval-low i1)) (i2l (interval-low i2)) |
| 64 | + (i1h (interval-high i1)) (i2h (interval-high i2))) |
| 65 | + (and (realp i1l) (realp i2l) (realp i1h) (realp i2h) |
| 66 | + (= i1l i2l i1h i2h)))) |
| 67 | +(defun interval-/= (i1 i2) (intervals-disjoint-p i1 i2)) |
| 68 | + |
| 69 | +(defun interval-< (i1 i2) |
| 70 | + (let ((i1h (interval-high i1)) (i2l (interval-low i2))) |
| 71 | + (and i1h i2l |
| 72 | + (multiple-value-bind (i1high i1hxp) (bound-parts i1h) |
| 73 | + (multiple-value-bind (i2low i2lxp) (bound-parts i2l) |
| 74 | + (or (< i1high i2low) |
| 75 | + (and (= i1high i2low) (or i1hxp i2lxp)))))))) |
| 76 | +(defun interval-<= (i1 i2) |
| 77 | + (let ((i1h (interval-high i1)) (i2l (interval-low i2))) |
| 78 | + (and i1h i2l (<= (bound-parts i1h) (bound-parts i2l))))) |
| 79 | + |
| 80 | +(defun interval-> (i1 i2) (interval-< i2 i1)) |
| 81 | +(defun interval->= (i1 i2) (interval-<= i2 i1)) |
| 82 | + |
38 | 83 | ;; Return -1 if the number is below the interval, 1 if above, 0 if in the interval. |
39 | 84 | (defun interval-num-compare (interval num) |
40 | 85 | (let ((low (interval-low interval)) (high (interval-high interval))) |
|
64 | 109 | (defun interval-merge (i1 i2) |
65 | 110 | ;; Return the smallest interval including both input intervals. |
66 | 111 | ;; If the inputs do not intersect, this will not be a strict join. |
| 112 | + (labels ((lbmin (b1 b2) |
| 113 | + (cond ((not b1) b1) |
| 114 | + ((not b2) b2) |
| 115 | + (t (multiple-value-bind (b1 xp1) (bound-parts b1) |
| 116 | + (multiple-value-bind (b2 xp2) (bound-parts b2) |
| 117 | + (if (and xp1 xp2) (list (min b1 b2)) (min b1 b2))))))) |
| 118 | + (hbmax (b1 b2) |
| 119 | + (cond ((not b1) b1) |
| 120 | + ((not b2) b2) |
| 121 | + (t (multiple-value-bind (b1 xp1) (bound-parts b1) |
| 122 | + (multiple-value-bind (b2 xp2) (bound-parts b2) |
| 123 | + (if (and xp1 xp2) (list (max b1 b2)) (max b1 b2)))))))) |
| 124 | + (make-interval (lbmin (interval-low i1) (interval-low i2)) |
| 125 | + (hbmax (interval-high i1) (interval-high i2))))) |
| 126 | + |
| 127 | +(defun interval-intersect (i1 i2) |
| 128 | + ;; Return the smallest interval included by both input intervals. |
| 129 | + ;; If the inputs do not intersect, this will be empty. |
67 | 130 | (labels ((fb< (b1 b2) |
68 | 131 | (multiple-value-bind (b1 xp1) (bound-parts b1) |
69 | 132 | (multiple-value-bind (b2 xp2) (bound-parts b2) |
70 | 133 | (or (< b1 b2) (and (= b1 b2) xp1 (not xp2)))))) |
71 | | - (lbmin (b1 b2) |
72 | | - (if (and b2 (or (not b1) (fb< b1 b2))) b1 b2)) |
73 | | - (hbmax (b1 b2) |
74 | | - (if (and b1 (or (not b2) (fb< b1 b2))) b2 b1))) |
75 | | - (make-interval (lbmin (interval-low i1) (interval-low i2)) |
76 | | - (hbmax (interval-high i1) (interval-high i2))))) |
| 134 | + (lbmax (b1 b2) |
| 135 | + (if (and b2 (or (not b1) (fb< b1 b2))) b2 b1)) |
| 136 | + (hbmin (b1 b2) |
| 137 | + (if (and b1 (or (not b2) (fb< b1 b2))) b1 b2))) |
| 138 | + (make-interval (lbmax (interval-low i1) (interval-low i2)) |
| 139 | + (hbmin (interval-high i1) (interval-high i2))))) |
77 | 140 |
|
78 | 141 | ;; Multiply a positive interval by any interval. |
79 | 142 | (defun interval*-1-pos (i1 i2) |
|
0 commit comments