1 
2 //
3 // This source file is part of appleseed.
4 // Visit https://appleseedhq.net/ for additional information and resources.
5 //
6 // This software is released under the MIT license.
7 //
8 // Copyright (c) 2010-2013 Francois Beaune, Jupiter Jazz Limited
9 // Copyright (c) 2014-2018 Francois Beaune, The appleseedhq Organization
10 //
11 // Permission is hereby granted, free of charge, to any person obtaining a copy
12 // of this software and associated documentation files (the "Software"), to deal
13 // in the Software without restriction, including without limitation the rights
14 // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
15 // copies of the Software, and to permit persons to whom the Software is
16 // furnished to do so, subject to the following conditions:
17 //
18 // The above copyright notice and this permission notice shall be included in
19 // all copies or substantial portions of the Software.
20 //
21 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
22 // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
23 // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
24 // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
25 // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
26 // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
27 // THE SOFTWARE.
28 //
29 
30 #pragma once
31 
32 // appleseed.foundation headers.
33 #include "foundation/math/scalar.h"
34 #include "foundation/platform/types.h"
35 
36 // Standard headers.
37 #include <cassert>
38 #include <cstddef>
39 #include <limits>
40 
41 namespace foundation
42 {
43 
44 //
45 // Distribution adapters.
46 //
47 // Interesting reference:
48 //
49 //   Uniform random floats: How to generate a double-precision floating-point number
50 //   in [0, 1] uniformly at random given a uniform random source of bits.
51 //   http://mumble.net/~campbell/tmp/random_real.c
52 //
53 
54 // Return a random number in the integer interval [0, 0x7FFFFFFF].
55 template <typename RNG> int32 rand_int31(RNG& rng);
56 
57 // Return a random number in the integer interval [min, max].
58 template <typename RNG> int32 rand_int1(RNG& rng, const int32 min, const int32 max);
59 
60 // Return a random number in the real interval [0,1].
61 template <typename RNG> float rand_float1(RNG& rng);
62 template <typename RNG> double rand_double1(RNG& rng);
63 template <typename T, typename RNG> T rand1(RNG& rng);
64 
65 // Return a random number in the real interval [min, max].
66 template <typename RNG> float rand_float1(RNG& rng, const float min, const float max);
67 template <typename RNG> double rand_double1(RNG& rng, const double min, const double max);
68 template <typename RNG> float rand1(RNG& rng, const float min, const float max);
69 template <typename RNG> double rand1(RNG& rng, const double min, const double max);
70 
71 // Return a random number in the real interval [0,1).
72 template <typename RNG> float rand_float2(RNG& rng);
73 template <typename RNG> double rand_double2(RNG& rng);
74 template <typename T, typename RNG> T rand2(RNG& rng);
75 
76 // Return a random number in the real interval [min, max).
77 template <typename RNG> float rand_float2(RNG& rng, const float min, const float max);
78 template <typename RNG> double rand_double2(RNG& rng, const double min, const double max);
79 template <typename RNG> float rand2(RNG& rng, const float min, const float max);
80 template <typename RNG> double rand2(RNG& rng, const double min, const double max);
81 
82 // Return a random number in the real interval (0,1).
83 template <typename RNG> float rand_float3(RNG& rng);
84 template <typename RNG> double rand_double3(RNG& rng);
85 template <typename T, typename RNG> T rand3(RNG& rng);
86 
87 // Return a random number in the real interval (min, max).
88 template <typename RNG> float rand_float3(RNG& rng, const float min, const float max);
89 template <typename RNG> double rand_double3(RNG& rng, const double min, const double max);
90 template <typename RNG> float rand3(RNG& rng, const float min, const float max);
91 template <typename RNG> double rand3(RNG& rng, const double min, const double max);
92 
93 // Return a random number in the real interval [0,1) with 53-bit resolution.
94 template <typename RNG> double rand_double2_res53(RNG& rng);
95 
96 
97 //
98 // Random vectors.
99 //
100 
101 // Return a random vector whose components are in the real interval [0,1].
102 template <typename VectorType, typename RNG>
103 VectorType rand_vector1(RNG& rng);
104 
105 // Return a random vector whose components are in the real interval [0,1).
106 template <typename VectorType, typename RNG>
107 VectorType rand_vector2(RNG& rng);
108 
109 // Return a random vector whose components are in the real interval (0,1).
110 template <typename VectorType, typename RNG>
111 VectorType rand_vector3(RNG& rng);
112 
113 
114 //
115 // Implementation.
116 //
117 
118 template <typename RNG>
rand_int31(RNG & rng)119 inline int32 rand_int31(RNG& rng)
120 {
121     const int32 result = static_cast<int32>(rng.rand_uint32() >> 1);
122 
123     assert(result >= 0);
124     assert(result <= 0x7FFFFFFFu);
125 
126     return result;
127 }
128 
129 template <typename RNG>
rand_int1(RNG & rng,const int32 min,const int32 max)130 inline int32 rand_int1(RNG& rng, const int32 min, const int32 max)
131 {
132     assert(min <= max);
133 
134     const double x =
135         rand_double2(
136             rng,
137             static_cast<double>(min),
138             static_cast<double>(max) + 1);
139 
140     const int32 result = truncate<int32>(x);
141 
142     assert(result >= min);
143     assert(result <= max);
144 
145     return result;
146 }
147 
148 template <typename RNG>
rand_float1(RNG & rng)149 inline float rand_float1(RNG& rng)
150 {
151     const float result = rng.rand_uint32() * (1.0f / 0xFFFFFFFFu);
152 
153     assert(result >= 0.0f);
154     assert(result <= 1.0f);
155 
156     return result;
157 }
158 
159 template <typename RNG>
rand_double1(RNG & rng)160 inline double rand_double1(RNG& rng)
161 {
162     const double result = rng.rand_uint32() * (1.0 / 0xFFFFFFFFu);
163 
164     assert(result >= 0.0);
165     assert(result <= 1.0);
166 
167     return result;
168 }
169 
170 template <typename T, typename RNG>
171 struct Rand1Helper;
172 
173 template <typename RNG>
174 struct Rand1Helper<float, RNG>
175 {
176     float operator()(RNG& rng) { return rand_float1(rng); }
177 };
178 
179 template <typename RNG>
180 struct Rand1Helper<double, RNG>
181 {
182     double operator()(RNG& rng) { return rand_double1(rng); }
183 };
184 
185 template <typename T, typename RNG>
186 inline T rand1(RNG& rng)
187 {
188     Rand1Helper<T, RNG> helper;
189     return helper(rng);
190 }
191 
192 template <typename RNG>
193 inline float rand_float1(RNG& rng, const float min, const float max)
194 {
195     assert(min <= max);
196 
197     const float result = lerp(min, max, rand_float1(rng));
198 
199     assert(result >= min);
200     assert(result <= max);
201 
202     return result;
203 }
204 
205 template <typename RNG>
206 inline double rand_double1(RNG& rng, const double min, const double max)
207 {
208     assert(min <= max);
209 
210     const double result = lerp(min, max, rand_double1(rng));
211 
212     assert(result >= min);
213     assert(result <= max);
214 
215     return result;
216 }
217 
218 template <typename RNG>
219 inline float rand1(RNG& rng, const float min, const float max)
220 {
221     return rand_float1(rng, min, max);
222 }
223 
224 template <typename RNG>
225 inline double rand1(RNG& rng, const double min, const double max)
226 {
227     return rand_double1(rng, min, max);
228 }
229 
230 template <typename RNG>
231 inline float rand_float2(RNG& rng)
232 {
233     const float result = rng.rand_uint32() * Rcp2Pow32<float>();
234 
235     assert(result >= 0.0f);
236     assert(result < 1.0f);
237 
238     return result;
239 }
240 
241 template <typename RNG>
242 inline double rand_double2(RNG& rng)
243 {
244     const double result = rng.rand_uint32() * Rcp2Pow32<double>();
245 
246     assert(result >= 0.0);
247     assert(result < 1.0);
248 
249     return result;
250 }
251 
252 template <typename T, typename RNG>
253 struct Rand2Helper;
254 
255 template <typename RNG>
256 struct Rand2Helper<float, RNG>
257 {
258     float operator()(RNG& rng) { return rand_float2(rng); }
259 };
260 
261 template <typename RNG>
262 struct Rand2Helper<double, RNG>
263 {
264     double operator()(RNG& rng) { return rand_double2(rng); }
265 };
266 
267 template <typename T, typename RNG>
268 inline T rand2(RNG& rng)
269 {
270     Rand2Helper<T, RNG> helper;
271     return helper(rng);
272 }
273 
274 template <typename RNG>
275 inline float rand_float2(RNG& rng, const float min, const float max)
276 {
277     assert(min <= max);
278 
279     const float result = lerp(min, max, rand_float2(rng));
280 
281     assert(result >= min);
282     assert(result < max);
283 
284     return result;
285 }
286 
287 template <typename RNG>
288 inline double rand_double2(RNG& rng, const double min, const double max)
289 {
290     assert(min <= max);
291 
292     const double result = lerp(min, max, rand_double2(rng));
293 
294     assert(result >= min);
295     assert(result < max);
296 
297     return result;
298 }
299 
300 template <typename RNG>
301 inline float rand2(RNG& rng, const float min, const float max)
302 {
303     return rand_float2(rng, min, max);
304 }
305 
306 template <typename RNG>
307 inline double rand2(RNG& rng, const double min, const double max)
308 {
309     return rand_double2(rng, min, max);
310 }
311 
312 template <typename RNG>
313 inline float rand_float3(RNG& rng)
314 {
315     const float result = rng.rand_uint32() * 2.3283060e-010f + std::numeric_limits<float>::epsilon();
316 
317     assert(result > 0.0f);
318     assert(result < 1.0f);
319 
320     return result;
321 }
322 
323 template <typename RNG>
324 inline double rand_double3(RNG& rng)
325 {
326     const double result = rng.rand_uint32() * 2.3283064370807963e-10 + std::numeric_limits<double>::epsilon();
327 
328     assert(result > 0.0);
329     assert(result < 1.0);
330 
331     return result;
332 }
333 
334 template <typename T, typename RNG>
335 struct Rand3Helper;
336 
337 template <typename RNG>
338 struct Rand3Helper<float, RNG>
339 {
340     float operator()(RNG& rng) { return rand_float3(rng); }
341 };
342 
343 template <typename RNG>
344 struct Rand3Helper<double, RNG>
345 {
346     double operator()(RNG& rng) { return rand_double3(rng); }
347 };
348 
349 template <typename T, typename RNG>
350 inline T rand3(RNG& rng)
351 {
352     Rand3Helper<T, RNG> helper;
353     return helper(rng);
354 }
355 
356 template <typename RNG>
357 inline float rand_float3(RNG& rng, const float min, const float max)
358 {
359     assert(min <= max);
360 
361     const float result = lerp(min, max, rand_float3(rng));
362 
363     assert(result > min);
364     assert(result < max);
365 
366     return result;
367 }
368 
369 template <typename RNG>
370 inline double rand_double3(RNG& rng, const double min, const double max)
371 {
372     assert(min <= max);
373 
374     const double result = lerp(min, max, rand_double3(rng));
375 
376     assert(result > min);
377     assert(result < max);
378 
379     return result;
380 }
381 
382 template <typename RNG>
383 inline float rand3(RNG& rng, const float min, const float max)
384 {
385     return rand_float3(rng, min, max);
386 }
387 
388 template <typename RNG>
389 inline double rand3(RNG& rng, const double min, const double max)
390 {
391     return rand_double3(rng, min, max);
392 }
393 
394 template <typename RNG>
395 inline double rand_double2_res53(RNG& rng)
396 {
397     const uint32 a = rng.rand_uint32() >> 5;
398     const uint32 b = rng.rand_uint32() >> 6;
399 
400     const double result = (a * 67108864.0 + b) * (1.0 / 9007199254740992.0);
401 
402     assert(result >= 0.0);
403     assert(result < 1.0);
404 
405     return result;
406 }
407 
408 template <typename VectorType, typename RNG>
409 inline VectorType rand_vector1(RNG& rng)
410 {
411     VectorType v;
412 
413     for (size_t i = 0; i < VectorType::Dimension; ++i)
414         v[i] = rand1<typename VectorType::ValueType>(rng);
415 
416     return v;
417 }
418 
419 template <typename VectorType, typename RNG>
420 inline VectorType rand_vector2(RNG& rng)
421 {
422     VectorType v;
423 
424     for (size_t i = 0; i < VectorType::Dimension; ++i)
425         v[i] = rand2<typename VectorType::ValueType>(rng);
426 
427     return v;
428 }
429 
430 template <typename VectorType, typename RNG>
431 inline VectorType rand_vector3(RNG& rng)
432 {
433     VectorType v;
434 
435     for (size_t i = 0; i < VectorType::Dimension; ++i)
436         v[i] = rand3<typename VectorType::ValueType>(rng);
437 
438     return v;
439 }
440 
441 }   // namespace foundation
442