Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
Tetragramm
GitHub Repository: Tetragramm/opencv
Path: blob/master/3rdparty/openexr/Imath/ImathRandom.h
16337 views
1
///////////////////////////////////////////////////////////////////////////
2
//
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
//
33
///////////////////////////////////////////////////////////////////////////
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
261
Rand32::nextb ()
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
270
Rand32::nexti ()
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
304
Rand48::nextb ()
305
{
306
return Imath::nrand48 (_state) & 1;
307
}
308
309
310
inline long int
311
Rand48::nexti ()
312
{
313
return Imath::nrand48 (_state);
314
}
315
316
317
inline double
318
Rand48::nextf ()
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
399
400