|
110 | 110 | * We hard code them here as rational numbers so the division gives them with |
111 | 111 | * full precision of the Real type. |
112 | 112 | * |
113 | | - * Unfortunately, that means that this code needs to be changed when switching |
114 | | - * to precision beyond quad-double. |
115 | | - * |
116 | 113 | * Each subsequent term has at most half the modulus of the previous term in |
117 | 114 | * series (1), respectively, series (3) at least after the first two dozen |
118 | 115 | * terms. The remainder of the series is thus bound by the current term and |
119 | | - * we can stop once the term is smaller than the epsilon of the Real type ( |
120 | | - * we are even adding a bit of safety margin, yielding safe_epsilon). |
| 116 | + * we can stop once the term is smaller than the epsilon of the Real type. |
121 | 117 | */ |
122 | 118 |
|
123 | 119 | #include "dilog.h" |
124 | 120 |
|
125 | 121 | SNAPPEA_NAMESPACE_BEGIN_SCOPE |
126 | 122 |
|
127 | | -static void initialize_safe_epsilon(void); |
128 | 123 | static void initialize_coefficients(void); |
129 | 124 |
|
130 | | -static Boolean safe_epsilon_initialized = FALSE; |
131 | | -static Real safe_epsilon; |
132 | 125 | #define NUMBER_OF_TERMS 210 |
133 | 126 |
|
134 | 127 | /* coefficients[i] stores the coefficient c_k with k = 3 + 2 * i |
@@ -166,64 +159,6 @@ const static Real bernoulli_fractions[17][3] = { |
166 | 159 | { 65443, -362903, 870 }, |
167 | 160 | { 8605, 1001259881, 14322 }, |
168 | 161 | { 25271, -305065927, 510 } }; |
169 | | - |
170 | | - |
171 | | -static |
172 | | -void initialize_safe_epsilon(void) |
173 | | -{ |
174 | | - /* determine what the epsilon of the Real type is |
175 | | - * and save it in safe_epsilon */ |
176 | | - Real number, s1, s2; |
177 | | - |
178 | | - /* Bail if already done */ |
179 | | - if (safe_epsilon_initialized) { |
180 | | - return; |
181 | | - } |
182 | | - number = ((Real) 4) / ((Real) 3); |
183 | | - |
184 | | - /* The test number. It is the floating point approximation |
185 | | - * of 4/3. |
186 | | - * We are determining whether our epsilon is small enough |
187 | | - * by making sure that adding 1 * epsilon or 2 * epsilon |
188 | | - * yields the same floating point number. |
189 | | - * |
190 | | - * Remark: If, for some strange reason, the floating point |
191 | | - * number is the result of number + epsilon rounded up, then |
192 | | - * number + epsilon would always be different from number, |
193 | | - * no matter how small epsilon. Thus we choose to compute |
194 | | - * s1 = number + epsilon and s2 = number + (2 * epsilon) |
195 | | - * and compare s1 and s2. Notice that |
196 | | - * number + (2 * epsilon) might differ from |
197 | | - * (number + epsilon) + epsilon. |
198 | | - * |
199 | | - * Remark: Quad doubles have 212 bits precision, but the |
200 | | - * exponents of the four doubles used in the four quad |
201 | | - * doubles do not need to be aligned. Thus, 1 + 2^-i |
202 | | - * can be represented exactly by a quad double even when |
203 | | - * i is much larger than 212. |
204 | | - * Thus using 1 as test number will fail. We instead use |
205 | | - * 4/3 because it is |
206 | | - * 1.0101010101010101010101010101.... in binary. |
207 | | - */ |
208 | | - |
209 | | - safe_epsilon = 1.0; |
210 | | - |
211 | | - do { |
212 | | - /* Half epsilon */ |
213 | | - safe_epsilon *= 0.5; |
214 | | - |
215 | | - /* Until we can't distinguish adding |
216 | | - * one or two epsilons to number */ |
217 | | - s1 = number + safe_epsilon; |
218 | | - s2 = number + (2.0 * safe_epsilon); |
219 | | - |
220 | | - } while (s1 != s2); |
221 | | - |
222 | | - /* 3-bits extra safety */ |
223 | | - safe_epsilon *= 0.125; |
224 | | - |
225 | | - safe_epsilon_initialized = TRUE; |
226 | | -} |
227 | 162 |
|
228 | 163 | static |
229 | 164 | void initialize_coefficients(void) |
@@ -306,7 +241,7 @@ Complex dilog_small(Complex z) |
306 | 241 | terms[i-1] = complex_div(z_power, denom); |
307 | 242 |
|
308 | 243 | /* Stop computing, desired precision is achieved */ |
309 | | - if ((i > 10) && complex_modulus(terms[i-1]) < safe_epsilon) |
| 244 | + if ((i > 10) && complex_modulus(terms[i-1]) < REAL_EPSILON) |
310 | 245 | break; |
311 | 246 |
|
312 | 247 | /* Stop computing, term number limit hit */ |
@@ -353,7 +288,7 @@ Complex dilog_near_one(Complex z) |
353 | 288 | terms[i] = complex_mult(coefficients[i], u_power); |
354 | 289 |
|
355 | 290 | /* Stop computing, desired precision is achieved */ |
356 | | - if ((i > 25) && (complex_modulus(terms[i]) < safe_epsilon)) |
| 291 | + if ((i > 25) && (complex_modulus(terms[i]) < REAL_EPSILON)) |
357 | 292 | break; |
358 | 293 |
|
359 | 294 | if (i >= NUMBER_OF_COEFFICIENTS - 1) |
@@ -412,9 +347,6 @@ Complex complex_volume_dilog(Complex z) |
412 | 347 | { |
413 | 348 | Real rsquare = complex_modulus_squared(z); /* |z|^2 */ |
414 | 349 |
|
415 | | - /* initialization */ |
416 | | - initialize_safe_epsilon(); |
417 | | - |
418 | 350 | /* |z| < 1/3 */ |
419 | 351 | if (rsquare < 1.0/9.0) { |
420 | 352 | return dilog_small(z); |
|
0 commit comments