bugfix for scrambled radical inverse function (noticed by Per Christensen, fix by Andrew Kensler)

metadata
Wenzel Jakob 2016-01-17 16:41:50 +01:00
parent 8d20ce4344
commit 649c00ae25
1 changed files with 7 additions and 36 deletions

View File

@ -106,6 +106,8 @@ Float scrambledRadicalInverse(int base, uint64_t i, uint16_t *perm) {
i /= base; i /= base;
} }
inverse += digit * perm[0] / (1 - radical);
return std::min(inverse, ONE_MINUS_EPS); return std::min(inverse, ONE_MINUS_EPS);
} }
@ -129,12 +131,11 @@ Float radicalInverseIncremental(int base, Float x) {
} }
/* Radical inverse: explicitly instantiated versions that permit important /* Radical inverse: explicitly instantiated versions that permit important
additional compiler optimizations. */ additional compiler optimizations.
#if 1 The code is designed to keep FP and integer math separate in the loop (to
avoid introducing unnecessary store-to-load dependencies on current
/* Tuned version that keeps FP and integer separate in the loop (to avoid introducing processor architectures) */
unnecessary store-to-load dependencies on current processor architectures) */
#define RINV(base) { \ #define RINV(base) { \
const Float radical = (Float) 1 / (Float) base; \ const Float radical = (Float) 1 / (Float) base; \
@ -162,39 +163,9 @@ Float radicalInverseIncremental(int base, Float x) {
factor *= radical; \ factor *= radical; \
index = next; \ index = next; \
} \ } \
inverse = (Float) value * factor; \ inverse = factor * ((Float) value + radical * perm[0] / (1 - radical)); \
} }
#else
/* Original versions */
#define RINV(base) { \
const Float radical = (Float) 1 / (Float) base; \
Float q = radical; \
while (index) { \
const uint64_t next = index / base; \
const uint32_t digit = (uint32_t) (index-next*base); /* Terrible code will be generated without this cast */ \
inverse += q * (Float) digit; \
q *= radical; \
index = next; \
} \
}
#define SCRAMBLED_RINV(base) { \
const Float radical = (Float) 1 / (Float) base; \
Float q = radical; \
while (index) { \
const uint64_t next = index / base; \
inverse += q * (Float) perm[index - next * base]; \
q *= radical; \
index = next; \
} \
}
#endif
Float radicalInverseFast(uint16_t baseIndex, uint64_t index) { Float radicalInverseFast(uint16_t baseIndex, uint64_t index) {
Float inverse = 0.0f; Float inverse = 0.0f;