|
1 | 1 | #lang racket/base |
2 | 2 |
|
3 | | -(provide get-bounds |
4 | | - get-slack) |
5 | | - |
6 | 3 | (require racket/match |
7 | 4 | racket/function |
8 | 5 | racket/list) |
|
11 | 8 | "../ops/all.rkt" |
12 | 9 | "machine.rkt") |
13 | 10 |
|
| 11 | +(provide get-bounds |
| 12 | + get-slack) |
| 13 | + |
14 | 14 | (define (get-slack [iter (*sampling-iteration*)]) |
15 | 15 | (match iter |
16 | 16 | [0 0] |
|
25 | 25 |
|
26 | 26 | ; We assume the interval x is valid. Critical not to take mpfr-exp of inf or 0, |
27 | 27 | ; the results are platform-dependant |
28 | | -(define (maxlog x [iter (*sampling-iteration*)]) |
| 28 | +(define (maxlog x #:underestimate [underestimate #f]) |
| 29 | + (define iter (if underestimate (- (*sampling-iteration*) 1) (*sampling-iteration*))) |
29 | 30 | (define lo (ival-lo x)) |
30 | 31 | (define hi (ival-hi x)) |
31 | 32 | (cond |
|
36 | 37 | [else |
37 | 38 | (+ (max (mpfr-exp lo) (mpfr-exp hi)) 1)])) ; x does not contain inf, safe with respect to 0.bf |
38 | 39 |
|
39 | | -(define (minlog x [iter (*sampling-iteration*)]) |
| 40 | +(define (minlog x #:underestimate [underestimate #f]) |
| 41 | + (define iter (if underestimate (- (*sampling-iteration*) 1) (*sampling-iteration*))) |
40 | 42 | (define lo (ival-lo x)) |
41 | 43 | (define hi (ival-hi x)) |
42 | 44 | (cond |
|
72 | 74 | ; Function calculates an ampl factor per input for a certain output and inputs using condition formulas, |
73 | 75 | ; where an ampl is an additional precision that needs to be added to srcs evaluation so, |
74 | 76 | ; that the output will be fixed in its precision when evaluating again |
| 77 | +; Additionaly, the function retures lower bound of ampl factor for the early exit mechanism |
| 78 | +; Output: '( '(upper-ampl-bound lower-ampl-bound) ...) with len(srcs) number of elements |
75 | 79 | (define (get-bounds op z srcs) |
76 | 80 | (case (object-name op) |
77 | 81 | [(ival-mult) |
78 | 82 | ; k = 1: logspan(y) |
79 | 83 | ; k = 2: logspan(x) |
80 | 84 | (define x (first srcs)) |
81 | 85 | (define y (second srcs)) |
82 | | - (list (logspan y) ; exponent per x |
83 | | - (logspan x))] ; exponent per y |
| 86 | + (list (list (logspan y) 0) ; bounds per x |
| 87 | + (list (logspan x) 0))] ; bounds per y |
84 | 88 |
|
85 | 89 | [(ival-div) |
86 | 90 | ; k = 1: logspan(y) |
87 | 91 | ; k = 2: logspan(x) + 2 * logspan(y) |
88 | 92 | (define x (first srcs)) |
89 | 93 | (define y (second srcs)) |
90 | | - (list (logspan y) ; exponent per x |
91 | | - (+ (logspan x) (* 2 (logspan y))))] ; exponent per y |
| 94 | + (list (list (logspan y) 0) ; bounds per x |
| 95 | + (list (+ (logspan x) (* 2 (logspan y))) 0))] ; bounds per y |
92 | 96 |
|
93 | 97 | [(ival-sqrt ival-cbrt) |
94 | 98 | ; sqrt: logspan(x)/2 - 1 |
95 | 99 | ; cbrt: logspan(x)*2/3 - 1 |
96 | 100 | (define x (first srcs)) |
97 | | - (list (quotient (logspan x) 2))] |
| 101 | + (list (list (quotient (logspan x) 2) 0))] |
98 | 102 |
|
99 | 103 | [(ival-add ival-sub) |
100 | 104 | ; k = 1: maxlog(x) - minlog(z) |
101 | 105 | ; k = 2: maxlog(y) - minlog(z) |
102 | 106 | (define x (first srcs)) |
103 | 107 | (define y (second srcs)) |
104 | 108 |
|
105 | | - (list (- (maxlog x) (minlog z)) ; exponent per x |
106 | | - (- (maxlog y) (minlog z)))] ; exponent per y |
| 109 | + (list (list (- (maxlog x) (minlog z)) |
| 110 | + (- (minlog x #:underestimate #t) (maxlog z #:underestimate #t))) ; bounds per x |
| 111 | + (list (- (maxlog y) (minlog z)) |
| 112 | + (- (minlog y #:underestimate #t) (maxlog z #:underestimate #t))))] ; bounds per y |
107 | 113 |
|
108 | 114 | [(ival-pow) |
109 | 115 | ; k = 1: maxlog(y) + logspan(x) + logspan(z) |
|
115 | 121 | ; solution - add more slack for y to converge |
116 | 122 | (define slack (if (and (crosses-zero? z) (bfnegative? (ival-lo x))) (get-slack) 0)) |
117 | 123 |
|
118 | | - (list (+ (maxlog y) (logspan x) (logspan z)) ; exponent per x |
119 | | - (+ (maxlog y) (max (abs (maxlog x)) (abs (minlog x))) (logspan z) slack))] ; exponent per y |
| 124 | + (list (list (+ (maxlog y) (logspan x) (logspan z)) (minlog y #:underestimate #t)) ; bounds per x |
| 125 | + (list (+ (maxlog y) (max (abs (maxlog x)) (abs (minlog x))) (logspan z) slack) |
| 126 | + (minlog y #:underestimate #t)))] ; bounds per y |
120 | 127 |
|
121 | 128 | [(ival-exp ival-exp2) |
122 | 129 | ; maxlog(x) + logspan(z) |
123 | 130 | (define x (car srcs)) |
124 | | - (list (+ (maxlog x) (logspan z)))] |
| 131 | + (list (list (+ (maxlog x) (logspan z)) (minlog x #:underestimate #t)))] |
125 | 132 |
|
126 | 133 | [(ival-tan) |
127 | 134 | ; maxlog(x) + max(|minlog(z)|,|maxlog(z)|) + logspan(z) + 1 |
128 | 135 | (define x (first srcs)) |
129 | | - (list (+ (maxlog x) (max (abs (maxlog z)) (abs (minlog z))) (logspan z) 1))] |
| 136 | + (list (list (+ (maxlog x) (max (abs (maxlog z)) (abs (minlog z))) (logspan z) 1) |
| 137 | + (+ (minlog x #:underestimate #t) |
| 138 | + (min (abs (maxlog z #:underestimate #t)) (abs (minlog z #:underestimate #t))))))] |
130 | 139 |
|
131 | 140 | [(ival-sin) |
132 | 141 | ; maxlog(x) - minlog(z) |
133 | 142 | (define x (first srcs)) |
134 | | - (list (- (maxlog x) (minlog z)))] |
| 143 | + (list (list (- (maxlog x) (minlog z)) (- (maxlog z #:underestimate #t))))] |
135 | 144 |
|
136 | 145 | [(ival-cos) |
137 | 146 | ; maxlog(x) - minlog(z) + min(maxlog(x), 0) |
138 | 147 | (define x (first srcs)) |
139 | | - (list (+ (- (maxlog x) (minlog z)) (min (maxlog x) 0)))] |
| 148 | + (list (list (+ (- (maxlog x) (minlog z)) (min (maxlog x) 0)) (- (maxlog z #:underestimate #t))))] |
140 | 149 |
|
141 | 150 | [(ival-sinh) |
142 | 151 | ; maxlog(x) + logspan(z) - min(minlog(x), 0) |
143 | 152 | (define x (first srcs)) |
144 | | - (list (- (+ (maxlog x) (logspan z)) (min (minlog x) 0)))] |
| 153 | + (list (list (- (+ (maxlog x) (logspan z)) (min (minlog x) 0)) |
| 154 | + (max 0 (minlog x #:underestimate #t))))] |
145 | 155 |
|
146 | 156 | [(ival-cosh) |
147 | 157 | ; maxlog(x) + logspan(z) + min(maxlog(x), 0) |
148 | 158 | (define x (first srcs)) |
149 | | - (list (+ (maxlog x) (logspan z) (min (maxlog x) 0)))] |
| 159 | + (list (list (+ (maxlog x) (logspan z) (min (maxlog x) 0)) |
| 160 | + (max 0 (minlog x #:underestimate #t))))] |
150 | 161 |
|
151 | 162 | [(ival-log ival-log2 ival-log10) |
152 | 163 | ; log: logspan(x) - minlog(z) |
153 | 164 | ; log2: logspan(x) - minlog(z) + 1 |
154 | 165 | ; log10: logspan(x) - minlog(z) - 1 |
155 | 166 | (define x (first srcs)) |
156 | | - (list (+ (- (logspan x) (minlog z)) 1))] |
| 167 | + (list (list (+ (- (logspan x) (minlog z)) 1) (- (maxlog z #:underestimate #t))))] |
157 | 168 |
|
| 169 | + ; ---------------------------------------- TODO: LOWER BOUND NEEDED BELOW ----------------- |
158 | 170 | [(ival-asin) |
159 | 171 | ; maxlog(x) - log[1-x^2]/2 - minlog(z) |
160 | 172 | ; ^^^^^^^^^^^^ |
|
165 | 177 | (get-slack) ; assumes that log[1-x^2]/2 is equal to slack |
166 | 178 | 0)) |
167 | 179 |
|
168 | | - (list (+ (- (maxlog x) (minlog z)) slack))] |
| 180 | + (list (list (+ (- (maxlog x) (minlog z)) slack) 0))] |
169 | 181 |
|
170 | 182 | [(ival-acos) |
171 | 183 | ; maxlog(x) - log[1-x^2]/2 - minlog(z) |
|
177 | 189 | (get-slack) ; assumes that log[1-x^2]/2 is equal to slack |
178 | 190 | 0)) |
179 | 191 |
|
180 | | - (list (+ (- (maxlog x) (minlog z)) slack))] |
| 192 | + (list (list (+ (- (maxlog x) (minlog z)) slack) 0))] |
181 | 193 |
|
182 | 194 | [(ival-atan) |
183 | 195 | ; logspan(x) - min(|minlog(x)|, |maxlog(x)|) - minlog(z) |
184 | 196 | (define x (first srcs)) |
185 | | - (list (- (logspan x) (min (abs (minlog x)) (abs (maxlog x))) (minlog z)))] |
| 197 | + (list (list (- (logspan x) (min (abs (minlog x)) (abs (maxlog x))) (minlog z)) 0))] |
186 | 198 |
|
187 | 199 | [(ival-fmod ival-remainder) |
188 | 200 | ; x mod y = x - y*q, where q is rnd_down(x/y) |
|
198 | 210 | (get-slack) ; y crosses zero |
199 | 211 | 0)) |
200 | 212 |
|
201 | | - (list (- (maxlog x) (minlog z)) ; exponent per x |
202 | | - (+ (- (maxlog x) (minlog z)) slack))] ; exponent per y |
| 213 | + (list (list (- (maxlog x) (minlog z)) 0) ; bounds per x |
| 214 | + (list (+ (- (maxlog x) (minlog z)) slack) 0))] ; bounds per y |
203 | 215 |
|
204 | 216 | ; Currently log1p has a very poor approximation |
205 | 217 | [(ival-log1p) |
|
215 | 227 | (get-slack) ; if x in negative |
216 | 228 | 0)) |
217 | 229 |
|
218 | | - (list (+ (- (maxlog x) (minlog z)) slack))] |
| 230 | + (list (list (+ (- (maxlog x) (minlog z)) slack) 0))] |
219 | 231 |
|
220 | 232 | ; Currently expm1 has a very poor solution for negative values |
221 | 233 | [(ival-expm1) |
222 | 234 | ; log[Гexpm1] = log[x * e^x / expm1] <= max(1 + maxlog(x), 1 + maxlog(x) - minlog(z)) |
223 | 235 | (define x (first srcs)) |
224 | | - (list (max (+ 1 (maxlog x)) (+ 1 (- (maxlog x) (minlog z)))))] |
| 236 | + (list (list (max (+ 1 (maxlog x)) (+ 1 (- (maxlog x) (minlog z)))) 0))] |
225 | 237 |
|
226 | 238 | [(ival-atan2) |
227 | 239 | ; maxlog(x) + maxlog(y) - 2*max(minlog(x), minlog(y)) - minlog(z) |
228 | 240 | (define x (first srcs)) |
229 | 241 | (define y (second srcs)) |
230 | 242 |
|
231 | | - (make-list 2 (- (+ (maxlog x) (maxlog y)) (* 2 (max (minlog x) (minlog y))) (minlog z)))] |
| 243 | + (make-list 2 |
| 244 | + (list (- (+ (maxlog x) (maxlog y)) (* 2 (max (minlog x) (minlog y))) (minlog z)) 0))] |
232 | 245 |
|
233 | 246 | [(ival-tanh) |
234 | 247 | ; logspan(z) + logspan(x) |
235 | 248 | (define x (first srcs)) |
236 | | - (list (+ (logspan z) (logspan x)))] |
| 249 | + (list (list (+ (logspan z) (logspan x)) 0))] |
237 | 250 |
|
238 | 251 | [(ival-atanh) |
239 | 252 | ; log[Гarctanh] = maxlog(x) - log[(1-x^2)] - minlog(z) = 1 if x < 0.5, otherwise slack |
240 | 253 | ; ^^^^^^^ |
241 | 254 | ; a possible uncertainty |
242 | 255 | (define x (first srcs)) |
243 | | - (list (if (>= (maxlog x) 1) (get-slack) 1))] |
| 256 | + (list (list (if (>= (maxlog x) 1) (get-slack) 1) 0))] |
244 | 257 |
|
245 | 258 | [(ival-acosh) |
246 | 259 | ; log[Гacosh] = log[x / (sqrt(x-1) * sqrt(x+1) * acosh)] <= -minlog(z) + slack |
|
250 | 263 | (get-slack) |
251 | 264 | 0)) |
252 | 265 |
|
253 | | - (list (- slack z-exp))] |
| 266 | + (list (list (- slack z-exp) 0))] |
254 | 267 |
|
255 | 268 | [(ival-pow2) |
256 | 269 | ; same as multiplication |
257 | 270 | (define x (first srcs)) |
258 | | - (list (+ (logspan x) 1))] |
| 271 | + (list (list (+ (logspan x) 1) 0))] |
259 | 272 |
|
260 | 273 | ; TODO |
261 | | - [(ival-erfc ival-erf ival-lgamma ival-tgamma ival-asinh ival-logb) (list (get-slack))] |
| 274 | + [(ival-erfc ival-erf ival-lgamma ival-tgamma ival-asinh ival-logb) (list (list (get-slack) 0))] |
262 | 275 | ; TODO |
263 | | - [(ival-ceil ival-floor ival-rint ival-round ival-trunc) (list (get-slack))] |
| 276 | + [(ival-ceil ival-floor ival-rint ival-round ival-trunc) (list (list (get-slack) 0))] |
264 | 277 |
|
265 | | - [else (map (const 0) srcs)])) ; exponents for arguments |
| 278 | + [else (map (list (const 0) (const 0)) srcs)])) ; exponents for arguments |
0 commit comments