Skip to content

Commit a122748

Browse files
committed
Using REAL_EPSILON instead of computing it in dilog.
1 parent 922415e commit a122748

2 files changed

Lines changed: 4 additions & 71 deletions

File tree

  • src/snappy/extensions

src/snappy/extensions/Orb/kernel/headers/precision/double/real_type.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,5 +29,6 @@ SNAPPEA_NAMESPACE_END_SCOPE
2929
#define Real_from_string(x) (atof((char *)x))
3030

3131
#define REAL_MAX DBL_MAX
32+
#define REAL_EPSILON DBL_EPSILON
3233

3334
#endif

src/snappy/extensions/SnapPy/kernel/addl_code/dilog.c

Lines changed: 3 additions & 71 deletions
Original file line numberDiff line numberDiff line change
@@ -110,25 +110,18 @@
110110
* We hard code them here as rational numbers so the division gives them with
111111
* full precision of the Real type.
112112
*
113-
* Unfortunately, that means that this code needs to be changed when switching
114-
* to precision beyond quad-double.
115-
*
116113
* Each subsequent term has at most half the modulus of the previous term in
117114
* series (1), respectively, series (3) at least after the first two dozen
118115
* 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.
121117
*/
122118

123119
#include "dilog.h"
124120

125121
SNAPPEA_NAMESPACE_BEGIN_SCOPE
126122

127-
static void initialize_safe_epsilon(void);
128123
static void initialize_coefficients(void);
129124

130-
static Boolean safe_epsilon_initialized = FALSE;
131-
static Real safe_epsilon;
132125
#define NUMBER_OF_TERMS 210
133126

134127
/* coefficients[i] stores the coefficient c_k with k = 3 + 2 * i
@@ -166,64 +159,6 @@ const static Real bernoulli_fractions[17][3] = {
166159
{ 65443, -362903, 870 },
167160
{ 8605, 1001259881, 14322 },
168161
{ 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-
}
227162

228163
static
229164
void initialize_coefficients(void)
@@ -306,7 +241,7 @@ Complex dilog_small(Complex z)
306241
terms[i-1] = complex_div(z_power, denom);
307242

308243
/* 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)
310245
break;
311246

312247
/* Stop computing, term number limit hit */
@@ -353,7 +288,7 @@ Complex dilog_near_one(Complex z)
353288
terms[i] = complex_mult(coefficients[i], u_power);
354289

355290
/* 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))
357292
break;
358293

359294
if (i >= NUMBER_OF_COEFFICIENTS - 1)
@@ -412,9 +347,6 @@ Complex complex_volume_dilog(Complex z)
412347
{
413348
Real rsquare = complex_modulus_squared(z); /* |z|^2 */
414349

415-
/* initialization */
416-
initialize_safe_epsilon();
417-
418350
/* |z| < 1/3 */
419351
if (rsquare < 1.0/9.0) {
420352
return dilog_small(z);

0 commit comments

Comments
 (0)