SDDS ToolKit Programs and Libraries for C and Python
Loading...
Searching...
No Matches
drand.c File Reference

Detailed Description

Random number generation functions providing various distributions (uniform, Gaussian) and related utilities (seeding, ordering, etc.).

License
This file is distributed under the terms of the Software License Agreement found in the file LICENSE included with this distribution.
Author
M. Borland, C. Saunders, R. Soliday

Definition in file drand.c.

#include "mdb.h"
#include "mdb_thread.h"
#include <time.h>
#include <stdlib.h>
#include "f2c.h"

Go to the source code of this file.

Functions

double dlaran_ (integer *seed)
 Generates a random number using the DLARAN algorithm.
 
double dlaran_oag (integer *seed, long increment)
 Advance the DLARAN seed and return a random number.
 
void mdbmth_lock_rand (void)
 
void mdbmth_unlock_rand (void)
 
int mdbmth_rand_unlocked (void)
 
void mdbmth_srand_unlocked (unsigned int seed)
 
double mdbmth_rand_fraction_unlocked (void)
 
int mdbmth_locked_rand (void)
 
void mdbmth_locked_srand (unsigned int seed)
 
double mdbmth_locked_rand_fraction (void)
 
float drand (long dummy)
 Generate a uniform random float in [0,1].
 
double rdrand (double lo, double hi)
 Generate a uniform random double in [lo, hi].
 
void tseed ()
 
void r_theta_rand (double *r, double *theta, double r_min, double r_max)
 Generate a random point (r, θ) within an annulus defined by [r_min, r_max].
 
short inhibitRandomSeedPermutation (short state)
 Enable or disable permutation of seed bits for random number generators.
 
long permuteSeedBitOrder (long input0)
 Permute the bit order of a seed value to improve randomness.
 
double random_1 (long iseed)
 Generate a uniform random double in [0,1] using a custom seed initialization.
 
double random_2 (long iseed)
 Similar to random_1(), provides a separate random sequence with its own seed handling.
 
double random_3 (long iseed)
 Similar to random_2(), provides another independent random sequence.
 
double random_4 (long iseed)
 Similar to random_3(), provides another independent random sequence.
 
double random_5 (long iseed)
 Similar to random_4(), provides another independent random sequence.
 
double random_6 (long iseed)
 Similar to random_5(), provides another independent random sequence.
 
double gauss_rn (long iseed, double(*urandom)(long iseed1))
 Generate a Gaussian-distributed random number with mean 0 and sigma 1.
 
double gauss_rn_lim (double mean, double sigma, double limit_in_sigmas, double(*urandom)(long iseed))
 Generate a Gaussian-distributed random number with specified mean, sigma, and optional cutoff.
 
long convertSequenceToGaussianDistribution (double *data, long points, double limit)
 Convert a sequence of uniformly distributed [0,1] values into a Gaussian-distributed sequence.
 
int randomizeOrderCmp (const void *p1, const void *p2)
 
long randomizeOrder (char *ptr, long size, long length, long iseed, double(*urandom)(long iseed1))
 Randomize the order of an array of elements.
 
double random_oag (long iseed, long increment)
 Generate a uniform random double in [0,1] using a seed and increment, optimized for certain applications.
 
double gauss_rn_oag (long iseed, long increment, double(*urandom)(long iseed1, long increment))
 Generate a Gaussian-distributed random number using the random_oag approach.
 
double gauss_rn_lim_oag (double mean, double sigma, double limit_in_sigmas, long increment, double(*urandom)(long iseed, long increment))
 Generate a Gaussian-distributed random number with mean, sigma, and optional cutoff using oag RNG.
 

Function Documentation

◆ convertSequenceToGaussianDistribution()

long convertSequenceToGaussianDistribution ( double * data,
long points,
double limit )

Convert a sequence of uniformly distributed [0,1] values into a Gaussian-distributed sequence.

Uses the inverse error function (erf) to transform uniform data into Gaussian distributed data. Values that exceed the given limit are discarded.

Parameters
[in,out]dataArray of input values in [0,1] to be converted.
[in]pointsNumber of values in the array.
[in]limitUpper cutoff in standard deviations (if <= 0, no cutoff).
Returns
The number of successfully converted data points.

Definition at line 461 of file drand.c.

461 {
462 double u1, u2, z = 0;
463 long i, j;
464
465 if (!points)
466 return 0;
467 if (!data)
468 return 0;
469 for (i = j = 0; i < points; i++) {
470 u1 = 2 * (data[i] - 0.5);
471 if (u1 < 0)
472 u2 = -u1;
473 else
474 u2 = u1;
475#if defined(vxWorks) || defined(__rtems__)
476 fprintf(stderr, "erf function is not implemented on this architecture\n");
477 exit(1);
478#else
479 z = zeroNewton(erf, u2, 0.5, 1e-6, 500, 1e-12);
480#endif
481 data[j] = z * SQRT2;
482 if (limit <= 0 || data[j] < limit) {
483 if (u1 < 0)
484 data[j] = -data[j];
485 j++;
486 }
487 }
488 return j;
489}
double zeroNewton(double(*fn)(double x), double value, double x_i, double dx, long n_passes, double _zero)
Finds the zero of a function using Newton's method with numerical derivative computation.
Definition zeroNewton.c:33

◆ dlaran_()

double dlaran_ ( integer * iseed)
extern

Generates a random number using the DLARAN algorithm.

Parameters
iseedSeed array of four integers. Updated in place.
Returns
Uniform random number in the interval (0, 1).

Definition at line 34 of file dlaran.c.

34 {
35 /* System generated locals */
36 doublereal ret_val;
37
38 /* Local variables */
39 integer it1, it2, it3, it4;
40
41 /* Parameter adjustments */
42 /*--iseed;*/
43
44 /* Function Body */
45
46 /* -- LAPACK auxiliary routine (version 2.0) -- */
47 /* Univ. of Tennessee, Univ. of California Berkeley, NAG Ltd., */
48 /* Courant Institute, Argonne National Lab, and Rice University */
49 /* February 29, 1992 */
50
51 /* .. Array Arguments .. */
52 /* .. */
53
54 /* Purpose */
55 /* ======= */
56
57 /* DLARAN returns a random real number from a uniform (0,1) */
58 /* distribution. */
59
60 /* Arguments */
61 /* ========= */
62
63 /* ISEED (input/output) INTEGER array, dimension (4) */
64 /* On entry, the seed of the random number generator; the array
65*/
66 /* elements must be between 0 and 4095, and ISEED(4) must be */
67 /* odd. */
68 /* On exit, the seed is updated. */
69
70 /* Further Details */
71 /* =============== */
72
73 /* This routine uses a multiplicative congruential method with modulus */
74
75 /* 2**48 and multiplier 33952834046453 (see G.S.Fishman, */
76 /* 'Multiplicative congruential random number generators with modulus */
77 /* 2**b: an exhaustive analysis for b = 32 and a partial analysis for */
78 /* b = 48', Math. Comp. 189, pp 331-344, 1990). */
79
80 /* 48-bit integers are stored in 4 integer array elements with 12 bits */
81
82 /* per element. Hence the routine is portable across machines with */
83 /* integers of 32 bits or more. */
84
85 /* =====================================================================
86*/
87
88 /* .. Parameters .. */
89 /* .. */
90 /* .. Local Scalars .. */
91 /* .. */
92 /* .. Intrinsic Functions .. */
93 /* .. */
94 /* .. Executable Statements .. */
95
96 /* multiply the seed by the multiplier modulo 2**48 */
97
98 it4 = iseed[3] * 2549;
99 it3 = it4 / 4096;
100 it4 -= it3 << 12;
101 it3 = it3 + iseed[2] * 2549 + iseed[3] * 2508;
102 it2 = it3 / 4096;
103 it3 -= it2 << 12;
104 it2 = it2 + iseed[1] * 2549 + iseed[2] * 2508 + iseed[3] * 322;
105 it1 = it2 / 4096;
106 it2 -= it1 << 12;
107 it1 = it1 + iseed[0] * 2549 + iseed[1] * 2508 + iseed[2] * 322 + iseed[3] * 494;
108 it1 %= 4096;
109
110 /* return updated seed */
111
112 iseed[0] = it1;
113 iseed[1] = it2;
114 iseed[2] = it3;
115 iseed[3] = it4;
116
117 /* convert 48-bit integer to a real number in the interval (0,1) */
118
119 ret_val = ((doublereal)it1 + ((doublereal)it2 + ((doublereal)it3 + (doublereal)it4 * 2.44140625e-4) * 2.44140625e-4) * 2.44140625e-4) * 2.44140625e-4;
120 return ret_val;
121
122 /* End of DLARAN */
123
124} /* dlaran_ */

◆ dlaran_oag()

double dlaran_oag ( integer * iseed,
long increment )
extern

Advance the DLARAN seed and return a random number.

Parameters
iseedSeed array of four integers. Updated in place.
incrementNumber of times to update the seed before returning the new value.
Returns
Uniform random number in the interval (0, 1).

Definition at line 133 of file dlaran.c.

133 {
134 doublereal ret_val;
135
136 integer it1, it2, it3, it4, i;
137
138 if (increment < 1)
139 increment = 1;
140 for (i = 0; i < increment; i++) {
141 it4 = iseed[3] * 2549;
142 it3 = it4 / 4096;
143 it4 -= it3 << 12;
144 it3 = it3 + iseed[2] * 2549 + iseed[3] * 2508;
145 it2 = it3 / 4096;
146 it3 -= it2 << 12;
147 it2 = it2 + iseed[1] * 2549 + iseed[2] * 2508 + iseed[3] * 322;
148 it1 = it2 / 4096;
149 it2 -= it1 << 12;
150 it1 = it1 + iseed[0] * 2549 + iseed[1] * 2508 + iseed[2] * 322 + iseed[3] * 494;
151 it1 %= 4096;
152
153 iseed[0] = it1;
154 iseed[1] = it2;
155 iseed[2] = it3;
156 iseed[3] = it4;
157 }
158
159 ret_val = ((doublereal)it1 + ((doublereal)it2 + ((doublereal)it3 + (doublereal)it4 * 2.44140625e-4) * 2.44140625e-4) * 2.44140625e-4) * 2.44140625e-4;
160 return ret_val;
161}

◆ drand()

float drand ( long dummy)

Generate a uniform random float in [0,1].

Uses the standard C rand() function. The parameter dummy is unused.

Parameters
[in]dummyUnused parameter.
Returns
A random float in [0,1].

Definition at line 86 of file drand.c.

86 {
87 return (float)(mdbmth_locked_rand() / MAX_RAND_INT);
88}

◆ gauss_rn()

double gauss_rn ( long iseed,
double(* urandom )(long iseed1) )

Generate a Gaussian-distributed random number with mean 0 and sigma 1.

Uses the given uniform random generator urandom to produce Gaussian deviates via the Box–Muller transform.

Parameters
[in]iseedIf negative, re-initializes the uniform RNG.
[in]urandomPointer to a uniform random number generator function.
Returns
A Gaussian random deviate with mean 0 and sigma 1.

Definition at line 396 of file drand.c.

396 {
397 static MDB_THREAD_LOCAL long valueSaved = 0;
398 static MDB_THREAD_LOCAL double savedValue;
399 double urn1, urn2, sine, cosine, factor;
400
401 if (iseed < 0)
402 (*urandom)(iseed);
403 if (!valueSaved) {
404 urn1 = (*urandom)(0);
405 urn2 = (*urandom)(0);
406 factor = sqrt(-2 * log(urn1));
407 cosine = cos(PIx2 * urn2);
408 sine = sin(PIx2 * urn2);
409 savedValue = factor * cosine;
410 /* to use saved values, set this to 1 instead
411 * I've disabled this feature as it doesn't work properly with multiple
412 * urandom's.
413 */
414 valueSaved = 0;
415 return factor * sine;
416 } else {
417 valueSaved = 0;
418 return savedValue;
419 }
420}

◆ gauss_rn_lim()

double gauss_rn_lim ( double mean,
double sigma,
double limit_in_sigmas,
double(* urandom )(long iseed) )

Generate a Gaussian-distributed random number with specified mean, sigma, and optional cutoff.

If limit_in_sigmas > 0, values are regenerated until the deviate falls within ±limit_in_sigmas*sigma.

Parameters
[in]meanMean of the Gaussian distribution.
[in]sigmaStandard deviation of the Gaussian distribution.
[in]limit_in_sigmasCutoff in multiples of sigma (if <= 0, no cutoff).
[in]urandomPointer to a uniform random number generator function.
Returns
A Gaussian random deviate meeting the specified conditions.

Definition at line 433 of file drand.c.

437 {
438 double limit, value;
439
440 if (limit_in_sigmas <= 0)
441 return (mean + sigma * gauss_rn(0, urandom));
442
443 limit = limit_in_sigmas;
444 do {
445 value = gauss_rn(0, urandom);
446 } while (FABS(value) > limit);
447 return (sigma * value + mean);
448}
double gauss_rn(long iseed, double(*urandom)(long iseed1))
Generate a Gaussian-distributed random number with mean 0 and sigma 1.
Definition drand.c:396

◆ gauss_rn_lim_oag()

double gauss_rn_lim_oag ( double mean,
double sigma,
double limit_in_sigmas,
long increment,
double(* urandom )(long iseed, long increment) )

Generate a Gaussian-distributed random number with mean, sigma, and optional cutoff using oag RNG.

If limit_in_sigmas > 0, values are regenerated until they fall within the cutoff range.

Parameters
[in]meanMean of the Gaussian distribution.
[in]sigmaStandard deviation of the Gaussian distribution.
[in]limit_in_sigmasCutoff in multiples of sigma (if <= 0, no cutoff).
[in]incrementIncrement step for random number generation.
[in]urandomPointer to an oag-style uniform random number generator function.
Returns
A Gaussian random deviate meeting the specified conditions.

Definition at line 622 of file drand.c.

627 {
628 double limit, value;
629 long i;
630
631 if (limit_in_sigmas <= 0)
632 return (mean + sigma * gauss_rn_oag(0, increment, urandom));
633
634 limit = limit_in_sigmas;
635 i = 0;
636
637 do {
638 value = gauss_rn_oag(0, 1, urandom);
639 if (FABS(value) <= limit)
640 i++;
641 } while ((FABS(value) > limit) || (i < increment));
642
643 return (sigma * value + mean);
644}
double gauss_rn_oag(long iseed, long increment, double(*urandom)(long iseed1, long increment))
Generate a Gaussian-distributed random number using the random_oag approach.
Definition drand.c:597

◆ gauss_rn_oag()

double gauss_rn_oag ( long iseed,
long increment,
double(* urandom )(long iseed1, long increment) )

Generate a Gaussian-distributed random number using the random_oag approach.

Uses a modified Box–Muller method to generate Gaussian deviates from the urandom function provided.

Parameters
[in]iseedSeed for initialization if negative.
[in]incrementIncrement step for random number generation.
[in]urandomPointer to an oag-style uniform random number generator function.
Returns
A Gaussian random deviate with mean 0 and sigma 1.

Definition at line 597 of file drand.c.

597 {
598 double urn1, urn2, sine, factor;
599
600 if (increment < 1)
601 increment = 1;
602 increment = ((increment - 1) * 2) + 1;
603 urn1 = (*urandom)(iseed, increment);
604 urn2 = (*urandom)(0, 1);
605 factor = sqrt(-2 * log(urn1));
606 sine = sin(PIx2 * urn2);
607 return factor * sine;
608}

◆ inhibitRandomSeedPermutation()

short inhibitRandomSeedPermutation ( short state)

Enable or disable permutation of seed bits for random number generators.

If state >= 0, sets the inhibitPermute flag. Otherwise, returns the current state without changing it.

Parameters
[in]stateNew state for inhibition (0 = no inhibition, 1 = inhibited).
Returns
The current state of the inhibitPermute flag.

Definition at line 139 of file drand.c.

139 {
140 short currentState;
141
142 mdb_thread_lock(&inhibitPermuteLock);
143 if (state >= 0)
144 inhibitPermute = state;
145 currentState = inhibitPermute;
146 mdb_thread_unlock(&inhibitPermuteLock);
147 return currentState;
148}

◆ mdbmth_lock_rand()

void mdbmth_lock_rand ( void )

Definition at line 36 of file drand.c.

36 {
37 mdb_thread_lock(&rand_lock);
38}

◆ mdbmth_locked_rand()

int mdbmth_locked_rand ( void )

Definition at line 56 of file drand.c.

56 {
57 int value;
58 mdbmth_lock_rand();
59 value = mdbmth_rand_unlocked();
60 mdbmth_unlock_rand();
61 return value;
62}

◆ mdbmth_locked_rand_fraction()

double mdbmth_locked_rand_fraction ( void )

Definition at line 70 of file drand.c.

70 {
71 double value;
72 mdbmth_lock_rand();
73 value = mdbmth_rand_fraction_unlocked();
74 mdbmth_unlock_rand();
75 return value;
76}

◆ mdbmth_locked_srand()

void mdbmth_locked_srand ( unsigned int seed)

Definition at line 64 of file drand.c.

64 {
65 mdbmth_lock_rand();
66 mdbmth_srand_unlocked(seed);
67 mdbmth_unlock_rand();
68}

◆ mdbmth_rand_fraction_unlocked()

double mdbmth_rand_fraction_unlocked ( void )

Definition at line 52 of file drand.c.

52 {
53 return (double)mdbmth_rand_unlocked() / ((double)RAND_MAX + 1.0);
54}

◆ mdbmth_rand_unlocked()

int mdbmth_rand_unlocked ( void )

Definition at line 44 of file drand.c.

44 {
45 return rand();
46}

◆ mdbmth_srand_unlocked()

void mdbmth_srand_unlocked ( unsigned int seed)

Definition at line 48 of file drand.c.

48 {
49 srand(seed);
50}

◆ mdbmth_unlock_rand()

void mdbmth_unlock_rand ( void )

Definition at line 40 of file drand.c.

40 {
41 mdb_thread_unlock(&rand_lock);
42}

◆ permuteSeedBitOrder()

long permuteSeedBitOrder ( long input0)

Permute the bit order of a seed value to improve randomness.

Applies a permutation of the seed bits to avoid predictable patterns. If inhibition is enabled, returns the original input.

Parameters
[in]input0The seed value to permute.
Returns
The permuted seed value.

Definition at line 159 of file drand.c.

159 {
160 long offset = input0 % 1000;
161 long newValue;
162 long i;
163 short inhibit;
164 unsigned long input;
165 unsigned long bitMask[32] = {
166 0x00000001UL,
167 0x00000002UL,
168 0x00000004UL,
169 0x00000008UL,
170 0x00000010UL,
171 0x00000020UL,
172 0x00000040UL,
173 0x00000080UL,
174 0x00000100UL,
175 0x00000200UL,
176 0x00000400UL,
177 0x00000800UL,
178 0x00001000UL,
179 0x00002000UL,
180 0x00004000UL,
181 0x00008000UL,
182 0x00010000UL,
183 0x00020000UL,
184 0x00040000UL,
185 0x00080000UL,
186 0x00100000UL,
187 0x00200000UL,
188 0x00400000UL,
189 0x00800000UL,
190 0x01000000UL,
191 0x02000000UL,
192 0x04000000UL,
193 0x08000000UL,
194 0x10000000UL,
195 0x20000000UL,
196 0x40000000UL,
197 0x08000000UL,
198 };
199
200 mdb_thread_lock(&inhibitPermuteLock);
201 inhibit = inhibitPermute;
202 mdb_thread_unlock(&inhibitPermuteLock);
203 if (inhibit)
204 return input0;
205
206 input = input0;
207 newValue = 0;
208 for (i = 0; i < 31; i++) {
209 newValue += (input & bitMask[i]) ? bitMask[(i + offset) % 31] : 0;
210 }
211 if (newValue == input0) {
212 offset += 1;
213 newValue = 0;
214 for (i = 0; i < 31; i++) {
215 newValue += (input & bitMask[i]) ? bitMask[(i + offset) % 31] : 0;
216 }
217 }
218 return newValue;
219}

◆ r_theta_rand()

void r_theta_rand ( double * r,
double * theta,
double r_min,
double r_max )

Generate a random point (r, θ) within an annulus defined by [r_min, r_max].

The angle θ is chosen uniformly in [0, 2π), and r is chosen so that the area distribution is uniform.

Parameters
[out]rPointer to store the generated radius.
[out]thetaPointer to store the generated angle in radians.
[in]r_minThe inner radius of the annulus.
[in]r_maxThe outer radius of the annulus.

Definition at line 120 of file drand.c.

120 {
121 double area, sqr_r_min;
122
123 *theta = rdrand(0.0, PIx2);
124 sqr_r_min = sqr(r_min);
125 area = rdrand(0.0, sqr(r_max) - sqr_r_min);
126 *r = sqrt(area + sqr_r_min);
127}
double rdrand(double lo, double hi)
Generate a uniform random double in [lo, hi].
Definition drand.c:97

◆ random_1()

double random_1 ( long iseed)

Generate a uniform random double in [0,1] using a custom seed initialization.

Initializes the random number generator if needed, and then produces a double in [0,1]. Negative iseed values are used to re-initialize the sequence.

Parameters
[in]iseedSeed for initialization if negative, otherwise ignored after first call.
Returns
A random double in [0,1].

Definition at line 230 of file drand.c.

230 {
231 static MDB_THREAD_LOCAL short initialized = 0;
232 static MDB_THREAD_LOCAL integer seed[4] = {0, 0, 0, 0};
233
234 if (!initialized || iseed < 0) {
235 if (iseed < 0)
236 iseed = -iseed;
237 iseed = permuteSeedBitOrder(iseed);
238 random_2(-(iseed + 2));
239 random_3(-(iseed + 4));
240 random_4(-(iseed + 6));
241 random_5(-(iseed + 8));
242 random_6(-(iseed + 10));
243 iseed = (iseed / 2) * 2 + 1;
244 seed[3] = (iseed & 4095);
245 seed[2] = (iseed >>= 12) & 4095;
246 seed[1] = (iseed >>= 12) & 4095;
247 seed[0] = (iseed >>= 12) & 4095;
248 initialized = 1;
249 }
250 if (!initialized)
251 bomb("random_1 not properly initialized", NULL);
252
253 return dlaran_(seed);
254}
void bomb(char *error, char *usage)
Reports error messages to the terminal and aborts the program.
Definition bomb.c:26
double random_5(long iseed)
Similar to random_4(), provides another independent random sequence.
Definition drand.c:340
long permuteSeedBitOrder(long input0)
Permute the bit order of a seed value to improve randomness.
Definition drand.c:159
double random_6(long iseed)
Similar to random_5(), provides another independent random sequence.
Definition drand.c:366
double random_3(long iseed)
Similar to random_2(), provides another independent random sequence.
Definition drand.c:288
double random_4(long iseed)
Similar to random_3(), provides another independent random sequence.
Definition drand.c:314
double random_2(long iseed)
Similar to random_1(), provides a separate random sequence with its own seed handling.
Definition drand.c:262
double dlaran_(integer *seed)
Generates a random number using the DLARAN algorithm.
Definition dlaran.c:34

◆ random_2()

double random_2 ( long iseed)

Similar to random_1(), provides a separate random sequence with its own seed handling.

Parameters
[in]iseedSeed for initialization if negative.
Returns
A random double in [0,1].

Definition at line 262 of file drand.c.

262 {
263 static MDB_THREAD_LOCAL short initialized = 0;
264 static MDB_THREAD_LOCAL integer seed[4] = {0, 0, 0, 0};
265
266 if (!initialized || iseed < 0) {
267 if (iseed < 0)
268 iseed = -iseed;
269 iseed = permuteSeedBitOrder(iseed);
270 seed[3] = ((iseed & 4095) / 2) * 2 + 1;
271 seed[2] = (iseed >>= 12) & 4095;
272 seed[1] = (iseed >>= 12) & 4095;
273 seed[0] = (iseed >>= 12) & 4095;
274 initialized = 1;
275 }
276 if (!initialized)
277 bomb("random_2 not properly initialized", NULL);
278
279 return dlaran_(seed);
280}

◆ random_3()

double random_3 ( long iseed)

Similar to random_2(), provides another independent random sequence.

Parameters
[in]iseedSeed for initialization if negative.
Returns
A random double in [0,1].

Definition at line 288 of file drand.c.

288 {
289 static MDB_THREAD_LOCAL short initialized = 0;
290 static MDB_THREAD_LOCAL integer seed[4] = {0, 0, 0, 0};
291
292 if (!initialized || iseed < 0) {
293 if (iseed < 0)
294 iseed = -iseed;
295 iseed = permuteSeedBitOrder(iseed);
296 seed[3] = ((iseed & 4095) / 2) * 2 + 1;
297 seed[2] = (iseed >>= 12) & 4095;
298 seed[1] = (iseed >>= 12) & 4095;
299 seed[0] = (iseed >>= 12) & 4095;
300 initialized = 1;
301 }
302 if (!initialized)
303 bomb("random_3 not properly initialized", NULL);
304
305 return dlaran_(seed);
306}

◆ random_4()

double random_4 ( long iseed)

Similar to random_3(), provides another independent random sequence.

Parameters
[in]iseedSeed for initialization if negative.
Returns
A random double in [0,1].

Definition at line 314 of file drand.c.

314 {
315 static MDB_THREAD_LOCAL short initialized = 0;
316 static MDB_THREAD_LOCAL integer seed[4] = {0, 0, 0, 0};
317
318 if (!initialized || iseed < 0) {
319 if (iseed < 0)
320 iseed = -iseed;
321 iseed = permuteSeedBitOrder(iseed);
322 seed[3] = ((iseed & 4095) / 2) * 2 + 1;
323 seed[2] = (iseed >>= 12) & 4095;
324 seed[1] = (iseed >>= 12) & 4095;
325 seed[0] = (iseed >>= 12) & 4095;
326 initialized = 1;
327 }
328 if (!initialized)
329 bomb("random_4 not properly initialized", NULL);
330
331 return dlaran_(seed);
332}

◆ random_5()

double random_5 ( long iseed)

Similar to random_4(), provides another independent random sequence.

Parameters
[in]iseedSeed for initialization if negative.
Returns
A random double in [0,1].

Definition at line 340 of file drand.c.

340 {
341 static MDB_THREAD_LOCAL short initialized = 0;
342 static MDB_THREAD_LOCAL integer seed[4] = {0, 0, 0, 0};
343
344 if (!initialized || iseed < 0) {
345 if (iseed < 0)
346 iseed = -iseed;
347 iseed = permuteSeedBitOrder(iseed);
348 seed[3] = ((iseed & 4095) / 2) * 2 + 1;
349 seed[2] = (iseed >>= 12) & 4095;
350 seed[1] = (iseed >>= 12) & 4095;
351 seed[0] = (iseed >>= 12) & 4095;
352 initialized = 1;
353 }
354 if (!initialized)
355 bomb("random_5 not properly initialized", NULL);
356
357 return dlaran_(seed);
358}

◆ random_6()

double random_6 ( long iseed)

Similar to random_5(), provides another independent random sequence.

Parameters
[in]iseedSeed for initialization if negative.
Returns
A random double in [0,1].

Definition at line 366 of file drand.c.

366 {
367 static MDB_THREAD_LOCAL short initialized = 0;
368 static MDB_THREAD_LOCAL integer seed[4] = {0, 0, 0, 0};
369
370 if (!initialized || iseed < 0) {
371 if (iseed < 0)
372 iseed = -iseed;
373 iseed = permuteSeedBitOrder(iseed);
374 seed[3] = ((iseed & 4095) / 2) * 2 + 1;
375 seed[2] = (iseed >>= 12) & 4095;
376 seed[1] = (iseed >>= 12) & 4095;
377 seed[0] = (iseed >>= 12) & 4095;
378 initialized = 1;
379 }
380 if (!initialized)
381 bomb("random_6 not properly initialized", NULL);
382
383 return dlaran_(seed);
384}

◆ random_oag()

double random_oag ( long iseed,
long increment )

Generate a uniform random double in [0,1] using a seed and increment, optimized for certain applications.

Uses a custom random number generator implemented in Fortran (dlaran_oag).

Parameters
[in]iseedSeed for initialization if negative.
[in]incrementIncrement to apply for each call.
Returns
A random double in [0,1].

Definition at line 566 of file drand.c.

566 {
567 static MDB_THREAD_LOCAL short initialized = 0;
568 static MDB_THREAD_LOCAL integer seed[4] = {0, 0, 0, 0};
569
570 if (!initialized || iseed < 0) {
571 if (iseed < 0)
572 iseed = -iseed;
573 seed[3] = ((iseed & 4095) / 2) * 2 + 1;
574 seed[2] = (iseed >>= 12) & 4095;
575 seed[1] = (iseed >>= 12) & 4095;
576 seed[0] = (iseed >>= 12) & 4095;
577 initialized = 1;
578 }
579 if (!initialized) {
580 fprintf(stderr, "random_oag not properly initialized\n");
581 exit(1);
582 }
583
584 return dlaran_oag(seed, increment);
585}
double dlaran_oag(integer *seed, long increment)
Advance the DLARAN seed and return a random number.
Definition dlaran.c:133

◆ randomizeOrder()

long randomizeOrder ( char * ptr,
long size,
long length,
long iseed,
double(* urandom )(long iseed1) )

Randomize the order of an array of elements.

Shuffles the elements of an array using a provided uniform random generator.

Parameters
[in,out]ptrPointer to the array to randomize.
[in]sizeSize of each element in bytes.
[in]lengthNumber of elements in the array.
[in]iseedSeed for initialization if negative.
[in]urandomPointer to a uniform random number generator function.
Returns
Non-zero if successful, zero otherwise.

Definition at line 520 of file drand.c.

520 {
522 long i;
523 if (length < 2)
524 return 1;
525 if (!ptr)
526 return 0;
527 if (!(rh = malloc(sizeof(*rh) * length)))
528 return 0;
529 if (!urandom) {
530 free(rh);
531 return 0;
532 }
533 for (i = 0; i < length; i++)
534 rh[i].buffer = NULL;
535 if (iseed < 0)
536 (*urandom)(iseed);
537 for (i = 0; i < length; i++) {
538 if (!(rh[i].buffer = malloc(size))) {
539 while (i-- > 0)
540 free(rh[i].buffer);
541 free(rh);
542 return 0;
543 }
544 memcpy(rh[i].buffer, ptr + i * size, size);
545 rh[i].randomValue = (*urandom)(0);
546 }
547 qsort((void *)rh, length, sizeof(*rh), randomizeOrderCmp);
548
549 for (i = 0; i < length; i++) {
550 memcpy(ptr + i * size, rh[i].buffer, size);
551 free(rh[i].buffer);
552 }
553 free(rh);
554 return 1;
555}

◆ randomizeOrderCmp()

int randomizeOrderCmp ( const void * p1,
const void * p2 )

Definition at line 496 of file drand.c.

496 {
497 RANDOMIZATION_HOLDER *rh1, *rh2;
498 double diff;
499 rh1 = (RANDOMIZATION_HOLDER *)p1;
500 rh2 = (RANDOMIZATION_HOLDER *)p2;
501 if ((diff = rh1->randomValue - rh2->randomValue) > 0)
502 return 1;
503 if (diff < 0)
504 return -1;
505 return 0;
506}

◆ rdrand()

double rdrand ( double lo,
double hi )

Generate a uniform random double in [lo, hi].

Parameters
[in]loThe lower bound of the range.
[in]hiThe upper bound of the range.
Returns
A random double in [lo, hi].

Definition at line 97 of file drand.c.

98{
99 return (lo + ((hi - lo) * mdbmth_locked_rand()) / MAX_RAND_INT);
100}

◆ tseed()

void tseed ( )

Definition at line 106 of file drand.c.

106 {
107 mdbmth_locked_srand((unsigned int)time(NULL));
108}