Mitsuba Renderer  0.5.0
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
qmc.h
Go to the documentation of this file.
1 /*
2  This file is part of Mitsuba, a physically based rendering system.
3 
4  Copyright (c) 2007-2014 by Wenzel Jakob and others.
5 
6  Mitsuba is free software; you can redistribute it and/or modify
7  it under the terms of the GNU General Public License Version 3
8  as published by the Free Software Foundation.
9 
10  Mitsuba is distributed in the hope that it will be useful,
11  but WITHOUT ANY WARRANTY; without even the implied warranty of
12  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13  GNU General Public License for more details.
14 
15  You should have received a copy of the GNU General Public License
16  along with this program. If not, see <http://www.gnu.org/licenses/>.
17 */
18 
19 #pragma once
20 #if !defined(__MITSUBA_CORE_QMC_H_)
21 #define __MITSUBA_CORE_QMC_H_
22 
23 #include <mitsuba/mitsuba.h>
24 
26 
27 /** \addtogroup libcore
28  * \addtogroup libpython
29  * @{
30  */
31 
32 // -----------------------------------------------------------------------
33 //! @{ \name Elementary Quasi-Monte Carlo number sequences
34 //
35 // Based on implementations by Leonhard Gruenschloss
36 // -----------------------------------------------------------------------
37 
38 static const size_t primeTableSize = 1024;
39 /// Table of the first 1024 prime numbers
40 extern const int MTS_EXPORT_CORE primeTable[primeTableSize];
41 
42 /// Van der Corput radical inverse in base 2 with single precision
43 inline float radicalInverse2Single(uint32_t n, uint32_t scramble = 0U) {
44  /* Efficiently reverse the bits in 'n' using binary operations */
45 #if (defined(__GNUC__) && (__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 2))) || defined(__clang__)
46  n = __builtin_bswap32(n);
47 #else
48  n = (n << 16) | (n >> 16);
49  n = ((n & 0x00ff00ff) << 8) | ((n & 0xff00ff00) >> 8);
50 #endif
51  n = ((n & 0x0f0f0f0f) << 4) | ((n & 0xf0f0f0f0) >> 4);
52  n = ((n & 0x33333333) << 2) | ((n & 0xcccccccc) >> 2);
53  n = ((n & 0x55555555) << 1) | ((n & 0xaaaaaaaa) >> 1);
54 
55  // Account for the available precision and scramble
56  n = (n >> (32 - 24)) ^ (scramble & ~-(1 << 24));
57 
58  return (float) n / (float) (1U << 24);
59 }
60 
61 /// Van der Corput radical inverse in base 2 with double precision
62 inline double radicalInverse2Double(uint64_t n, uint64_t scramble = 0ULL) {
63  /* Efficiently reverse the bits in 'n' using binary operations */
64 #if (defined(__GNUC__) && (__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 2))) || defined(__clang__)
65  n = __builtin_bswap64(n);
66 #else
67  n = (n << 32) | (n >> 32);
68  n = ((n & 0x0000ffff0000ffffULL) << 16) | ((n & 0xffff0000ffff0000ULL) >> 16);
69  n = ((n & 0x00ff00ff00ff00ffULL) << 8) | ((n & 0xff00ff00ff00ff00ULL) >> 8);
70 #endif
71  n = ((n & 0x0f0f0f0f0f0f0f0fULL) << 4) | ((n & 0xf0f0f0f0f0f0f0f0ULL) >> 4);
72  n = ((n & 0x3333333333333333ULL) << 2) | ((n & 0xccccccccccccccccULL) >> 2);
73  n = ((n & 0x5555555555555555ULL) << 1) | ((n & 0xaaaaaaaaaaaaaaaaULL) >> 1);
74 
75  // Account for the available precision and scramble
76  n = (n >> (64 - 53)) ^ (scramble & ~-(1LL << 53));
77 
78  return (double) n / (double) (1ULL << 53);
79 }
80 
81 /// Sobol' radical inverse in base 2 with single precision.
82 inline float sobol2Single(uint32_t n, uint32_t scramble = 0U) {
83  for (uint32_t v = 1U << 31; n != 0; n >>= 1, v ^= v >> 1)
84  if (n & 1)
85  scramble ^= v;
86  return (float) scramble / (float) (1ULL << 32);
87 }
88 
89 /// Sobol' radical inverse in base 2 with double precision.
90 inline double sobol2Double(uint64_t n, uint64_t scramble = 0ULL) {
91  scramble &= ~-(1LL << 53);
92  for (uint64_t v = 1ULL << 52; n != 0; n >>= 1, v ^= v >> 1)
93  if (n & 1)
94  scramble ^= v;
95  return (double) scramble / (double) (1ULL << 53);
96 }
97 
98 /// Generate an element from a (0, 2) sequence, single precision
99 inline Point2f sample02Single(uint32_t n, uint32_t scramble[2]) {
100  return Point2f(
101  radicalInverse2Single(n, scramble[0]),
102  sobol2Single(n, scramble[1])
103  );
104 }
105 
106 /// Generate an element from a (0, 2) sequence, double precision version
107 inline Point2d sample02Double(uint64_t n, uint64_t scramble[2]) {
108  return Point2d(
109  radicalInverse2Double(n, scramble[0]),
110  sobol2Double(n, scramble[1])
111  );
112 }
113 
114 /// Generate an element from a (0, 2) sequence (without scrambling)
115 inline Point2 sample02(size_t n) {
116  #if defined(SINGLE_PRECISION)
117  return Point2(
120  );
121  #else
122  return Point2(
123  radicalInverse2Double((uint64_t) n),
124  sobol2Double((uint64_t) n)
125  );
126  #endif
127 }
128 
129 /**
130  * \brief Generate fast and reasonably good pseudorandom numbers using the
131  * Tiny Encryption Algorithm (TEA) by David Wheeler and Roger Needham.
132  *
133  * For details, refer to "GPU Random Numbers via the Tiny Encryption Algorithm"
134  * by Fahad Zafar, Marc Olano, and Aaron Curtis.
135  *
136  * \param v0
137  * First input value to be encrypted (could be the sample index)
138  * \param v1
139  * Second input value to be encrypted (e.g. the requested random number dimension)
140  * \param rounds
141  * How many rounds should be executed? The default for random number
142  * generation is 4.
143  * \return
144  * A uniformly distributed 64-bit integer
145  */
146 inline uint64_t sampleTEA(uint32_t v0, uint32_t v1, int rounds = 4) {
147  uint32_t sum = 0;
148 
149  for (int i=0; i<rounds; ++i) {
150  sum += 0x9e3779b9;
151  v0 += ((v1 << 4) + 0xA341316C) ^ (v1 + sum) ^ ((v1 >> 5) + 0xC8013EA4);
152  v1 += ((v0 << 4) + 0xAD90777D) ^ (v0 + sum) ^ ((v0 >> 5) + 0x7E95761E);
153  }
154 
155  return ((uint64_t) v1 << 32) + v0;
156 }
157 
158 /**
159  * \brief Generate fast and reasonably good pseudorandom numbers using the
160  * Tiny Encryption Algorithm (TEA) by David Wheeler and Roger Needham.
161  *
162  * This function uses \ref sampleTEA to return single precision floating point
163  * numbers on the interval <tt>[0, 1)</tt>
164  *
165  * \param v0
166  * First input value to be encrypted (could be the sample index)
167  * \param v1
168  * Second input value to be encrypted (e.g. the requested random number dimension)
169  * \param rounds
170  * How many rounds should be executed? The default for random number
171  * generation is 4.
172  * \return
173  * A uniformly distributed floating point number on the interval <tt>[0, 1)</tt>
174  */
175 inline float sampleTEASingle(uint32_t v0, uint32_t v1, int rounds = 4) {
176  /* Trick from MTGP: generate an uniformly distributed
177  single precision number in [1,2) and subtract 1. */
178  union {
179  uint32_t u;
180  float f;
181  } x;
182  x.u = ((sampleTEA(v0, v1, rounds) & 0xFFFFFFFF) >> 9) | 0x3f800000UL;
183  return x.f - 1.0f;
184 }
185 
186 /**
187  * \brief Generate fast and reasonably good pseudorandom numbers using the
188  * Tiny Encryption Algorithm (TEA) by David Wheeler and Roger Needham.
189  *
190  * This function uses \ref sampleTEA to return single precision floating point
191  * numbers on the interval <tt>[0, 1)</tt>
192  *
193  * \param v0
194  * First input value to be encrypted (could be the sample index)
195  * \param v1
196  * Second input value to be encrypted (e.g. the requested random number dimension)
197  * \param rounds
198  * How many rounds should be executed? The default for random number
199  * generation is 4.
200  * \return
201  * A uniformly distributed floating point number on the interval <tt>[0, 1)</tt>
202  */
203 inline double sampleTEADouble(uint32_t v0, uint32_t v1, int rounds = 4) {
204  /* Trick from MTGP: generate an uniformly distributed
205  single precision number in [1,2) and subtract 1. */
206  union {
207  uint64_t u;
208  double f;
209  } x;
210  x.u = (sampleTEA(v0, v1, rounds) >> 12) | 0x3ff0000000000000ULL;
211  return x.f - 1.0;
212 }
213 
214 #if defined(SINGLE_PRECISION)
215 /// Alias to \ref sampleTEASingle or \ref sampleTEADouble based on compilation flags
216 inline Float sampleTEAFloat(uint32_t v0, uint32_t v1, int rounds = 4) {
217  return sampleTEASingle(v0, v1, rounds);
218 }
219 #else
220 /// Alias to \ref sampleTEASingle or \ref sampleTEADouble based on compilation flags
221 inline Float sampleTEAFloat(uint32_t v0, uint32_t v1, int rounds = 4) {
222  return sampleTEADouble(v0, v1, rounds);
223 }
224 #endif
225 
226 /**
227  * \brief Calculate the radical inverse function
228  *
229  * This function is used as a building block to construct Halton and
230  * Hammersley sequences. Roughly, it computes a b-ary representation
231  * of the input value \c index, mirrors it along the decimal
232  * point, and returns the resulting fractional value.
233  */
234 extern MTS_EXPORT_CORE Float radicalInverse(int base, uint64_t index);
235 
236 /**
237  * \brief Calculate a scrambled radical inverse function
238  *
239  * This function is used as a building block to construct permuted
240  * Halton and Hammersley sequence variants. It works like the normal
241  * radical inverse function \ref radicalInverse(), except that every digit
242  * is run through an extra scrambling permutation specified as array
243  * of size \c base.
244  *
245  * \remark This function is not available in the Python API
246  */
248  uint64_t index, uint16_t *perm);
249 
250 /**
251  * \brief Incrementally calculate the next Van Der Corput sequence
252  * value starting from a current entry \c x (wrt. a fixed base)
253  *
254  * Repeated evaluation eventually causes a loss of accuracy
255  */
257 
258 /**
259  * \brief Calculate a radical inverse function (fast version)
260  *
261  * This function works similarly to \ref radicalInverse, but is potentially much
262  * faster. Internally, it relies on optimized implementations of the radical inverse
263  * functions for the first 1024 prime number bases. For that reason, only works for
264  * such bases.
265  *
266  * \param baseIndex
267  * Prime number index starting at 0 (i.e. 3 would cause 7 to be
268  * used as the basis)
269  * \param index
270  * Sequence index
271  */
272 extern MTS_EXPORT_CORE Float radicalInverseFast(uint16_t baseIndex, uint64_t index);
273 
274 /**
275  * \brief Calculate a scrambled radical inverse function (fast version)
276  *
277  * This function is used as a building block to construct permuted
278  * Halton and Hammersley sequence variants. It works like the fast
279  * radical inverse function \ref radicalInverseFast(), except that every
280  * digit is run through an extra scrambling permutation.
281  *
282  * \remark This function is not available in the Python API
283  */
284 extern MTS_EXPORT_CORE Float scrambledRadicalInverseFast(uint16_t baseIndex,
285  uint64_t index, uint16_t *perm);
286 
287 //! @}
288 // -----------------------------------------------------------------------
289 
290 //! @}
291 
293 
294 #endif /* __MITSUBA_CORE_QMC_H_ */
Point2d sample02Double(uint64_t n, uint64_t scramble[2])
Generate an element from a (0, 2) sequence, double precision version.
Definition: qmc.h:107
float radicalInverse2Single(uint32_t n, uint32_t scramble=0U)
Van der Corput radical inverse in base 2 with single precision.
Definition: qmc.h:43
float sobol2Single(uint32_t n, uint32_t scramble=0U)
Sobol&#39; radical inverse in base 2 with single precision.
Definition: qmc.h:82
Float radicalInverseFast(uint16_t baseIndex, uint64_t index)
Calculate a radical inverse function (fast version)
float sampleTEASingle(uint32_t v0, uint32_t v1, int rounds=4)
Generate fast and reasonably good pseudorandom numbers using the Tiny Encryption Algorithm (TEA) by D...
Definition: qmc.h:175
TPoint2< float > Point2f
Definition: fwd.h:133
#define MTS_EXPORT_CORE
Definition: getopt.h:29
#define MTS_NAMESPACE_BEGIN
Definition: platform.h:137
double sobol2Double(uint64_t n, uint64_t scramble=0ULL)
Sobol&#39; radical inverse in base 2 with double precision.
Definition: qmc.h:90
Float scrambledRadicalInverse(int base, uint64_t index, uint16_t *perm)
Calculate a scrambled radical inverse function.
TPoint2< double > Point2d
Definition: fwd.h:134
TPoint2< Float > Point2
Definition: fwd.h:129
double sampleTEADouble(uint32_t v0, uint32_t v1, int rounds=4)
Generate fast and reasonably good pseudorandom numbers using the Tiny Encryption Algorithm (TEA) by D...
Definition: qmc.h:203
Float radicalInverseIncremental(int base, Float x)
Incrementally calculate the next Van Der Corput sequence value starting from a current entry x (wrt...
uint64_t sampleTEA(uint32_t v0, uint32_t v1, int rounds=4)
Generate fast and reasonably good pseudorandom numbers using the Tiny Encryption Algorithm (TEA) by D...
Definition: qmc.h:146
Definition: fwd.h:99
Float scrambledRadicalInverseFast(uint16_t baseIndex, uint64_t index, uint16_t *perm)
Calculate a scrambled radical inverse function (fast version)
double radicalInverse2Double(uint64_t n, uint64_t scramble=0ULL)
Van der Corput radical inverse in base 2 with double precision.
Definition: qmc.h:62
Point2 sample02(size_t n)
Generate an element from a (0, 2) sequence (without scrambling)
Definition: qmc.h:115
const int primeTable[primeTableSize]
Table of the first 1024 prime numbers.
Point2f sample02Single(uint32_t n, uint32_t scramble[2])
Generate an element from a (0, 2) sequence, single precision.
Definition: qmc.h:99
Float sampleTEAFloat(uint32_t v0, uint32_t v1, int rounds=4)
Alias to sampleTEASingle or sampleTEADouble based on compilation flags.
Definition: qmc.h:221
#define MTS_NAMESPACE_END
Definition: platform.h:138
Float radicalInverse(int base, uint64_t index)
Calculate the radical inverse function.