HDK
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
ImathRandom.h
Go to the documentation of this file.
1 //
2 // SPDX-License-Identifier: BSD-3-Clause
3 // Copyright Contributors to the OpenEXR Project.
4 //
5 
6 //
7 // Generators for uniformly distributed pseudo-random numbers and
8 // functions that use those generators to generate numbers with
9 // non-uniform distributions
10 //
11 // Note: class Rand48() calls erand48() and nrand48(), which are not
12 // available on all operating systems. For compatibility we include
13 // our own versions of erand48() and nrand48(). Our functions
14 // have been reverse-engineered from the corresponding Unix/Linux
15 // man page.
16 //
17 
18 #ifndef INCLUDED_IMATHRANDOM_H
19 #define INCLUDED_IMATHRANDOM_H
20 
21 #include "ImathExport.h"
22 #include "ImathNamespace.h"
23 
24 #include <math.h>
25 #include <stdlib.h>
26 
27 IMATH_INTERNAL_NAMESPACE_HEADER_ENTER
28 
29 /// Fast random-number generator that generates
30 /// a uniformly distributed sequence with a period
31 /// length of 2^32.
32 class Rand32
33 {
34 public:
35  /// Constructor, given a seed
36  IMATH_HOSTDEVICE Rand32 (unsigned long int seed = 0);
37 
38  /// Re-initialize with a given seed
39  IMATH_HOSTDEVICE void init (unsigned long int seed);
40 
41  /// Get the next value in the sequence (range: [false, true])
42  IMATH_HOSTDEVICE bool nextb ();
43 
44  /// Get the next value in the sequence (range: [0 ... 0xffffffff])
45  IMATH_HOSTDEVICE unsigned long int nexti ();
46 
47  /// Get the next value in the sequence (range: [0 ... 1[)
49 
50  /// Get the next value in the sequence (range [rangeMin ... rangeMax[)
51  IMATH_HOSTDEVICE float nextf (float rangeMin, float rangeMax);
52 
53 private:
54  IMATH_HOSTDEVICE void next ();
55 
56  unsigned long int _state;
57 };
58 
59 /// Random-number generator based on the C Standard Library
60 /// functions erand48(), nrand48() & company; generates a
61 /// uniformly distributed sequence.
62 class Rand48
63 {
64 public:
65  /// Constructor
66  IMATH_HOSTDEVICE Rand48 (unsigned long int seed = 0);
67 
68  /// Re-initialize with a given seed
69  IMATH_HOSTDEVICE void init (unsigned long int seed);
70 
71  /// Get the next value in the sequence (range: [false, true])
72  IMATH_HOSTDEVICE bool nextb ();
73 
74  /// Get the next value in the sequence (range: [0 ... 0x7fffffff])
75  IMATH_HOSTDEVICE long int nexti ();
76 
77  /// Get the next value in the sequence (range: [0 ... 1[)
78  IMATH_HOSTDEVICE double nextf ();
79 
80  /// Get the next value in the sequence (range [rangeMin ... rangeMax[)
81  IMATH_HOSTDEVICE double nextf (double rangeMin, double rangeMax);
82 
83 private:
84  unsigned short int _state[3];
85 };
86 
87 /// Return random points uniformly distributed in a sphere with
88 /// radius 1 around the origin (distance from origin <= 1).
89 template <class Vec, class Rand>
90 IMATH_HOSTDEVICE Vec solidSphereRand (Rand& rand);
91 
92 /// Return random points uniformly distributed on the surface of
93 /// a sphere with radius 1 around the origin.
94 template <class Vec, class Rand>
95 IMATH_HOSTDEVICE Vec hollowSphereRand (Rand& rand);
96 
97 /// Return random numbers with a normal (Gaussian)
98 /// distribution with zero mean and unit variance.
99 template <class Rand> IMATH_HOSTDEVICE float gaussRand (Rand& rand);
100 
101 /// Return random points whose distance from the origin
102 /// has a normal (Gaussian) distribution with zero mean
103 /// and unit variance.
104 template <class Vec, class Rand>
105 IMATH_HOSTDEVICE Vec gaussSphereRand (Rand& rand);
106 
107 //---------------------------------
108 // erand48(), nrand48() and friends
109 //---------------------------------
110 
111 /// @cond Doxygen_Suppress
112 IMATH_HOSTDEVICE IMATH_EXPORT double erand48 (unsigned short state[3]);
114 IMATH_HOSTDEVICE IMATH_EXPORT long int nrand48 (unsigned short state[3]);
115 IMATH_HOSTDEVICE IMATH_EXPORT long int lrand48 ();
116 IMATH_HOSTDEVICE IMATH_EXPORT void srand48 (long int seed);
117 /// @endcond
118 
119 //---------------
120 // Implementation
121 //---------------
122 
123 IMATH_HOSTDEVICE inline void
124 Rand32::init (unsigned long int seed)
125 {
126  _state = (seed * 0xa5a573a5L) ^ 0x5a5a5a5aL;
127 }
128 
129 IMATH_HOSTDEVICE inline Rand32::Rand32 (unsigned long int seed)
130 {
131  init (seed);
132 }
133 
134 IMATH_HOSTDEVICE inline void
135 Rand32::next ()
136 {
137  _state = 1664525L * _state + 1013904223L;
138 }
139 
140 IMATH_HOSTDEVICE inline bool
142 {
143  next ();
144  // Return the 31st (most significant) bit, by and-ing with 2 ^ 31.
145  return !!(_state & 2147483648UL);
146 }
147 
148 IMATH_HOSTDEVICE inline unsigned long int
150 {
151  next ();
152  return _state & 0xffffffff;
153 }
154 
155 IMATH_HOSTDEVICE inline float
156 Rand32::nextf (float rangeMin, float rangeMax)
157 {
158  float f = nextf ();
159  return rangeMin * (1 - f) + rangeMax * f;
160 }
161 
162 IMATH_HOSTDEVICE inline void
163 Rand48::init (unsigned long int seed)
164 {
165  seed = (seed * 0xa5a573a5L) ^ 0x5a5a5a5aL;
166 
167  _state[0] = (unsigned short int) (seed & 0xFFFF);
168  _state[1] = (unsigned short int) ((seed >> 16) & 0xFFFF);
169  _state[2] = (unsigned short int) (seed & 0xFFFF);
170 }
171 
172 IMATH_HOSTDEVICE inline Rand48::Rand48 (unsigned long int seed)
173 {
174  init (seed);
175 }
176 
177 IMATH_HOSTDEVICE inline bool
179 {
180  return nrand48 (_state) & 1;
181 }
182 
183 IMATH_HOSTDEVICE inline long int
185 {
186  return nrand48 (_state);
187 }
188 
189 IMATH_HOSTDEVICE inline double
191 {
192  return erand48 (_state);
193 }
194 
195 IMATH_HOSTDEVICE inline double
196 Rand48::nextf (double rangeMin, double rangeMax)
197 {
198  double f = nextf ();
199  return rangeMin * (1 - f) + rangeMax * f;
200 }
201 
202 template <class Vec, class Rand>
204 solidSphereRand (Rand& rand)
205 {
206  Vec v;
207 
208  do
209  {
210  for (unsigned int i = 0; i < Vec::dimensions (); i++)
211  v[i] = (typename Vec::BaseType) rand.nextf (-1, 1);
212  } while (v.length2 () > 1);
213 
214  return v;
215 }
216 
217 template <class Vec, class Rand>
219 hollowSphereRand (Rand& rand)
220 {
221  Vec v;
222  typename Vec::BaseType length;
223 
224  do
225  {
226  for (unsigned int i = 0; i < Vec::dimensions (); i++)
227  v[i] = (typename Vec::BaseType) rand.nextf (-1, 1);
228 
229  length = v.length ();
230  } while (length > 1 || length == 0);
231 
232  return v / length;
233 }
234 
235 template <class Rand>
236 IMATH_HOSTDEVICE float
237 gaussRand (Rand& rand)
238 {
239  float x; // Note: to avoid numerical problems with very small
240  float y; // numbers, we make these variables singe-precision
241  float length2; // floats, but later we call the double-precision log()
242  // and sqrt() functions instead of logf() and sqrtf().
243  do
244  {
245  x = float (rand.nextf (-1, 1));
246  y = float (rand.nextf (-1, 1));
247  length2 = x * x + y * y;
248  } while (length2 >= 1 || length2 == 0);
249 
250  return x * sqrt (-2 * log (double (length2)) / length2);
251 }
252 
253 template <class Vec, class Rand>
255 gaussSphereRand (Rand& rand)
256 {
257  return hollowSphereRand<Vec> (rand) * gaussRand (rand);
258 }
259 
260 IMATH_INTERNAL_NAMESPACE_HEADER_EXIT
261 
262 #endif // INCLUDED_IMATHRANDOM_H
typedef int(APIENTRYP RE_PFNGLXSWAPINTERVALSGIPROC)(int)
IMATH_HOSTDEVICE Vec gaussSphereRand(Rand &rand)
Definition: ImathRandom.h:255
const GLdouble * v
Definition: glcorearb.h:837
vfloat4 sqrt(const vfloat4 &a)
Definition: simd.h:7694
GLuint GLsizei GLsizei * length
Definition: glcorearb.h:795
GLint y
Definition: glcorearb.h:103
IMATH_HOSTDEVICE void init(unsigned long int seed)
Re-initialize with a given seed.
Definition: ImathRandom.h:124
#define IMATH_HOSTDEVICE
Definition: ImathConfig.h:108
IMATH_HOSTDEVICE long int nexti()
Get the next value in the sequence (range: [0 ... 0x7fffffff])
Definition: ImathRandom.h:184
GLfloat f
Definition: glcorearb.h:1926
#define srand48(X)
Definition: SYS_Math.h:224
IMATH_HOSTDEVICE unsigned long int nexti()
Get the next value in the sequence (range: [0 ... 0xffffffff])
Definition: ImathRandom.h:149
IMATH_HOSTDEVICE float gaussRand(Rand &rand)
Definition: ImathRandom.h:237
IMATH_HOSTDEVICE Rand32(unsigned long int seed=0)
Constructor, given a seed.
Definition: ImathRandom.h:129
IMATH_HOSTDEVICE bool nextb()
Get the next value in the sequence (range: [false, true])
Definition: ImathRandom.h:141
IMATH_HOSTDEVICE bool nextb()
Get the next value in the sequence (range: [false, true])
Definition: ImathRandom.h:178
IMATH_HOSTDEVICE void init(unsigned long int seed)
Re-initialize with a given seed.
Definition: ImathRandom.h:163
GLint GLenum GLint x
Definition: glcorearb.h:409
#define IMATH_EXPORT
Definition: ImathExport.h:47
IMATH_HOSTDEVICE Vec hollowSphereRand(Rand &rand)
Definition: ImathRandom.h:219
IMATH_HOSTDEVICE IMATH_EXPORT float nextf()
Get the next value in the sequence (range: [0 ... 1[)
IMATH_NAMESPACE::V2f IMATH_NAMESPACE::Box2i std::string this attribute is obsolete as of OpenEXR v3 float
IMATH_HOSTDEVICE Vec solidSphereRand(Rand &rand)
Definition: ImathRandom.h:204
OIIO_FORCEINLINE T log(const T &v)
Definition: simd.h:7905
IMATH_HOSTDEVICE double nextf()
Get the next value in the sequence (range: [0 ... 1[)
Definition: ImathRandom.h:190
state
Definition: core.h:2289
IMATH_HOSTDEVICE Rand48(unsigned long int seed=0)
Constructor.
Definition: ImathRandom.h:172
#define drand48(X)
Definition: SYS_Math.h:225