Rumba C++ SDK
ImathRandom.h
Go to the documentation of this file.
1 //
3 // Copyright (c) 2002, Industrial Light & Magic, a division of Lucas
4 // Digital Ltd. LLC
5 //
6 // All rights reserved.
7 //
8 // Redistribution and use in source and binary forms, with or without
9 // modification, are permitted provided that the following conditions are
10 // met:
11 // * Redistributions of source code must retain the above copyright
12 // notice, this list of conditions and the following disclaimer.
13 // * Redistributions in binary form must reproduce the above
14 // copyright notice, this list of conditions and the following disclaimer
15 // in the documentation and/or other materials provided with the
16 // distribution.
17 // * Neither the name of Industrial Light & Magic nor the names of
18 // its contributors may be used to endorse or promote products derived
19 // from this software without specific prior written permission.
20 //
21 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
22 // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
23 // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
24 // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
25 // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
26 // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
27 // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
28 // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
29 // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
30 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
31 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
32 //
34 
35 
36 #ifndef INCLUDED_IMATHRANDOM_H
37 #define INCLUDED_IMATHRANDOM_H
38 
39 //-----------------------------------------------------------------------------
40 //
41 // Generators for uniformly distributed pseudo-random numbers and
42 // functions that use those generators to generate numbers with
43 // non-uniform distributions:
44 //
45 // class Rand32
46 // class Rand48
47 // solidSphereRand()
48 // hollowSphereRand()
49 // gaussRand()
50 // gaussSphereRand()
51 //
52 // Note: class Rand48() calls erand48() and nrand48(), which are not
53 // available on all operating systems. For compatibility we include
54 // our own versions of erand48() and nrand48(). Our functions have
55 // been reverse-engineered from the corresponding Unix/Linux man page.
56 //
57 //-----------------------------------------------------------------------------
58 
59 #include <stdlib.h>
60 #include <math.h>
61 
62 namespace Imath {
63 
64 //-----------------------------------------------
65 // Fast random-number generator that generates
66 // a uniformly distributed sequence with a period
67 // length of 2^32.
68 //-----------------------------------------------
69 
70 class Rand32
71 {
72  public:
73 
74  //------------
75  // Constructor
76  //------------
77 
78  Rand32 (unsigned long int seed = 0);
79 
80 
81  //--------------------------------
82  // Re-initialize with a given seed
83  //--------------------------------
84 
85  void init (unsigned long int seed);
86 
87 
88  //----------------------------------------------------------
89  // Get the next value in the sequence (range: [false, true])
90  //----------------------------------------------------------
91 
92  bool nextb ();
93 
94 
95  //---------------------------------------------------------------
96  // Get the next value in the sequence (range: [0 ... 0xffffffff])
97  //---------------------------------------------------------------
98 
99  unsigned long int nexti ();
100 
101 
102  //------------------------------------------------------
103  // Get the next value in the sequence (range: [0 ... 1[)
104  //------------------------------------------------------
105 
106  float nextf ();
107 
108 
109  //-------------------------------------------------------------------
110  // Get the next value in the sequence (range [rangeMin ... rangeMax[)
111  //-------------------------------------------------------------------
112 
113  float nextf (float rangeMin, float rangeMax);
114 
115 
116  private:
117 
118  void next ();
119 
120  unsigned long int _state;
121 };
122 
123 
124 //--------------------------------------------------------
125 // Random-number generator based on the C Standard Library
126 // functions erand48(), nrand48() & company; generates a
127 // uniformly distributed sequence.
128 //--------------------------------------------------------
129 
130 class Rand48
131 {
132  public:
133 
134  //------------
135  // Constructor
136  //------------
137 
138  Rand48 (unsigned long int seed = 0);
139 
140 
141  //--------------------------------
142  // Re-initialize with a given seed
143  //--------------------------------
144 
145  void init (unsigned long int seed);
146 
147 
148  //----------------------------------------------------------
149  // Get the next value in the sequence (range: [false, true])
150  //----------------------------------------------------------
151 
152  bool nextb ();
153 
154 
155  //---------------------------------------------------------------
156  // Get the next value in the sequence (range: [0 ... 0x7fffffff])
157  //---------------------------------------------------------------
158 
159  long int nexti ();
160 
161 
162  //------------------------------------------------------
163  // Get the next value in the sequence (range: [0 ... 1[)
164  //------------------------------------------------------
165 
166  double nextf ();
167 
168 
169  //-------------------------------------------------------------------
170  // Get the next value in the sequence (range [rangeMin ... rangeMax[)
171  //-------------------------------------------------------------------
172 
173  double nextf (double rangeMin, double rangeMax);
174 
175 
176  private:
177 
178  unsigned short int _state[3];
179 };
180 
181 
182 //------------------------------------------------------------
183 // Return random points uniformly distributed in a sphere with
184 // radius 1 around the origin (distance from origin <= 1).
185 //------------------------------------------------------------
186 
187 template <class Vec, class Rand>
188 Vec
189 solidSphereRand (Rand &rand);
190 
191 
192 //-------------------------------------------------------------
193 // Return random points uniformly distributed on the surface of
194 // a sphere with radius 1 around the origin.
195 //-------------------------------------------------------------
196 
197 template <class Vec, class Rand>
198 Vec
199 hollowSphereRand (Rand &rand);
200 
201 
202 //-----------------------------------------------
203 // Return random numbers with a normal (Gaussian)
204 // distribution with zero mean and unit variance.
205 //-----------------------------------------------
206 
207 template <class Rand>
208 float
209 gaussRand (Rand &rand);
210 
211 
212 //----------------------------------------------------
213 // Return random points whose distance from the origin
214 // has a normal (Gaussian) distribution with zero mean
215 // and unit variance.
216 //----------------------------------------------------
217 
218 template <class Vec, class Rand>
219 Vec
220 gaussSphereRand (Rand &rand);
221 
222 
223 //---------------------------------
224 // erand48(), nrand48() and friends
225 //---------------------------------
226 
227 double erand48 (unsigned short state[3]);
228 double drand48 ();
229 long int nrand48 (unsigned short state[3]);
230 long int lrand48 ();
231 void srand48 (long int seed);
232 
233 
234 //---------------
235 // Implementation
236 //---------------
237 
238 
239 inline void
240 Rand32::init (unsigned long int seed)
241 {
242  _state = (seed * 0xa5a573a5L) ^ 0x5a5a5a5aL;
243 }
244 
245 
246 inline
247 Rand32::Rand32 (unsigned long int seed)
248 {
249  init (seed);
250 }
251 
252 
253 inline void
254 Rand32::next ()
255 {
256  _state = 1664525L * _state + 1013904223L;
257 }
258 
259 
260 inline bool
262 {
263  next ();
264  // Return the 31st (most significant) bit, by and-ing with 2 ^ 31.
265  return !!(_state & 2147483648UL);
266 }
267 
268 
269 inline unsigned long int
271 {
272  next ();
273  return _state & 0xffffffff;
274 }
275 
276 
277 inline float
278 Rand32::nextf (float rangeMin, float rangeMax)
279 {
280  float f = nextf();
281  return rangeMin * (1 - f) + rangeMax * f;
282 }
283 
284 
285 inline void
286 Rand48::init (unsigned long int seed)
287 {
288  seed = (seed * 0xa5a573a5L) ^ 0x5a5a5a5aL;
289 
290  _state[0] = (unsigned short int) (seed & 0xFFFF);
291  _state[1] = (unsigned short int) ((seed >> 16) & 0xFFFF);
292  _state[2] = (unsigned short int) (seed & 0xFFFF);
293 }
294 
295 
296 inline
297 Rand48::Rand48 (unsigned long int seed)
298 {
299  init (seed);
300 }
301 
302 
303 inline bool
305 {
306  return Imath::nrand48 (_state) & 1;
307 }
308 
309 
310 inline long int
312 {
313  return Imath::nrand48 (_state);
314 }
315 
316 
317 inline double
319 {
320  return Imath::erand48 (_state);
321 }
322 
323 
324 inline double
325 Rand48::nextf (double rangeMin, double rangeMax)
326 {
327  double f = nextf();
328  return rangeMin * (1 - f) + rangeMax * f;
329 }
330 
331 
332 template <class Vec, class Rand>
333 Vec
334 solidSphereRand (Rand &rand)
335 {
336  Vec v;
337 
338  do
339  {
340  for (unsigned int i = 0; i < Vec::dimensions(); i++)
341  v[i] = (typename Vec::BaseType) rand.nextf (-1, 1);
342  }
343  while (v.length2() > 1);
344 
345  return v;
346 }
347 
348 
349 template <class Vec, class Rand>
350 Vec
351 hollowSphereRand (Rand &rand)
352 {
353  Vec v;
354  typename Vec::BaseType length;
355 
356  do
357  {
358  for (unsigned int i = 0; i < Vec::dimensions(); i++)
359  v[i] = (typename Vec::BaseType) rand.nextf (-1, 1);
360 
361  length = v.length();
362  }
363  while (length > 1 || length == 0);
364 
365  return v / length;
366 }
367 
368 
369 template <class Rand>
370 float
371 gaussRand (Rand &rand)
372 {
373  float x; // Note: to avoid numerical problems with very small
374  float y; // numbers, we make these variables singe-precision
375  float length2; // floats, but later we call the double-precision log()
376  // and sqrt() functions instead of logf() and sqrtf().
377  do
378  {
379  x = float (rand.nextf (-1, 1));
380  y = float (rand.nextf (-1, 1));
381  length2 = x * x + y * y;
382  }
383  while (length2 >= 1 || length2 == 0);
384 
385  return x * sqrt (-2 * log (double (length2)) / length2);
386 }
387 
388 
389 template <class Vec, class Rand>
390 Vec
391 gaussSphereRand (Rand &rand)
392 {
393  return hollowSphereRand <Vec> (rand) * gaussRand (rand);
394 }
395 
396 } // namespace Imath
397 
398 #endif
bool nextb()
Definition: ImathRandom.h:261
long int lrand48()
Definition: ImathRandom.cpp:156
Definition: ImathRandom.h:70
Vec hollowSphereRand(Rand &rand)
Definition: ImathRandom.h:351
Vec gaussSphereRand(Rand &rand)
Definition: ImathRandom.h:391
float nextf()
Definition: ImathRandom.cpp:172
void srand48(long int seed)
Definition: ImathRandom.cpp:163
double erand48(unsigned short state[3])
Definition: ImathRandom.cpp:103
double nextf()
Definition: ImathRandom.h:318
Vec solidSphereRand(Rand &rand)
Definition: ImathRandom.h:334
unsigned long int nexti()
Definition: ImathRandom.h:270
Definition: ImathRandom.h:130
float gaussRand(Rand &rand)
Definition: ImathRandom.h:371
long int nexti()
Definition: ImathRandom.h:311
void init(unsigned long int seed)
Definition: ImathRandom.h:286
Rand32(unsigned long int seed=0)
Definition: ImathRandom.h:247
Rand48(unsigned long int seed=0)
Definition: ImathRandom.h:297
bool nextb()
Definition: ImathRandom.h:304
long int nrand48(unsigned short state[3])
Definition: ImathRandom.cpp:142
Definition: ImathBox.h:67
double drand48()
Definition: ImathRandom.cpp:135
void init(unsigned long int seed)
Definition: ImathRandom.h:240