SDDS ToolKit Programs and Libraries for C and Python
Loading...
Searching...
No Matches
drand.c
Go to the documentation of this file.
1/**
2 * @file drand.c
3 * @brief Random number generation functions providing various distributions
4 * (uniform, Gaussian) and related utilities (seeding, ordering, etc.).
5 *
6 * @copyright
7 * - (c) 2002 The University of Chicago, as Operator of Argonne National Laboratory.
8 * - (c) 2002 The Regents of the University of California, as Operator of Los Alamos National Laboratory.
9 *
10 * @license
11 * This file is distributed under the terms of the Software License Agreement
12 * found in the file LICENSE included with this distribution.
13 *
14 * @author M. Borland, C. Saunders, R. Soliday
15 */
16
17#include "mdb.h"
18#include "mdb_thread.h"
19#include <time.h>
20#include <stdlib.h>
21
22#if defined(_WIN32)
23# if _MSC_VER <= 1600
24# include "fdlibm.h"
25# endif
26#endif
27#include "f2c.h"
28
29extern double dlaran_(integer *seed);
30extern double dlaran_oag(integer *seed, long increment);
31
32#define MAX_RAND_INT (1.0 * RAND_MAX)
33
34static MDB_THREAD_LOCK rand_lock = MDB_THREAD_LOCK_INITIALIZER;
35
36void mdbmth_lock_rand(void) {
37 mdb_thread_lock(&rand_lock);
38}
39
40void mdbmth_unlock_rand(void) {
41 mdb_thread_unlock(&rand_lock);
42}
43
44int mdbmth_rand_unlocked(void) {
45 return rand();
46}
47
48void mdbmth_srand_unlocked(unsigned int seed) {
49 srand(seed);
50}
51
52double mdbmth_rand_fraction_unlocked(void) {
53 return (double)mdbmth_rand_unlocked() / ((double)RAND_MAX + 1.0);
54}
55
56int mdbmth_locked_rand(void) {
57 int value;
58 mdbmth_lock_rand();
59 value = mdbmth_rand_unlocked();
60 mdbmth_unlock_rand();
61 return value;
62}
63
64void mdbmth_locked_srand(unsigned int seed) {
65 mdbmth_lock_rand();
66 mdbmth_srand_unlocked(seed);
67 mdbmth_unlock_rand();
68}
69
70double mdbmth_locked_rand_fraction(void) {
71 double value;
72 mdbmth_lock_rand();
73 value = mdbmth_rand_fraction_unlocked();
74 mdbmth_unlock_rand();
75 return value;
76}
77
78/**
79 * @brief Generate a uniform random float in [0,1].
80 *
81 * Uses the standard C rand() function. The parameter `dummy` is unused.
82 *
83 * @param[in] dummy Unused parameter.
84 * @return A random float in [0,1].
85 */
86float drand(long dummy) {
87 return (float)(mdbmth_locked_rand() / MAX_RAND_INT);
88}
89
90/**
91 * @brief Generate a uniform random double in [lo, hi].
92 *
93 * @param[in] lo The lower bound of the range.
94 * @param[in] hi The upper bound of the range.
95 * @return A random double in [lo, hi].
96 */
97double rdrand(lo, hi) double lo, hi;
98{
99 return (lo + ((hi - lo) * mdbmth_locked_rand()) / MAX_RAND_INT);
100}
101
102/* routine: tseed()
103 * purpose: seed rand() with clock time
104 */
105
106void tseed() {
107 mdbmth_locked_srand((unsigned int)time(NULL));
108}
109
110/**
111 * @brief Generate a random point (r, θ) within an annulus defined by [r_min, r_max].
112 *
113 * The angle θ is chosen uniformly in [0, 2π), and r is chosen so that the area distribution is uniform.
114 *
115 * @param[out] r Pointer to store the generated radius.
116 * @param[out] theta Pointer to store the generated angle in radians.
117 * @param[in] r_min The inner radius of the annulus.
118 * @param[in] r_max The outer radius of the annulus.
119 */
120void r_theta_rand(double *r, double *theta, double r_min, double r_max) {
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}
128
129static short inhibitPermute = 0;
130static MDB_THREAD_LOCK inhibitPermuteLock = MDB_THREAD_LOCK_INITIALIZER;
131/**
132 * @brief Enable or disable permutation of seed bits for random number generators.
133 *
134 * If state >= 0, sets the inhibitPermute flag. Otherwise, returns the current state without changing it.
135 *
136 * @param[in] state New state for inhibition (0 = no inhibition, 1 = inhibited).
137 * @return The current state of the inhibitPermute flag.
138 */
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}
149
150/**
151 * @brief Permute the bit order of a seed value to improve randomness.
152 *
153 * Applies a permutation of the seed bits to avoid predictable patterns.
154 * If inhibition is enabled, returns the original input.
155 *
156 * @param[in] input0 The seed value to permute.
157 * @return The permuted seed value.
158 */
159long permuteSeedBitOrder(long input0) {
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}
220
221/**
222 * @brief Generate a uniform random double in [0,1] using a custom seed initialization.
223 *
224 * Initializes the random number generator if needed, and then produces a double in [0,1].
225 * Negative iseed values are used to re-initialize the sequence.
226 *
227 * @param[in] iseed Seed for initialization if negative, otherwise ignored after first call.
228 * @return A random double in [0,1].
229 */
230double random_1(long iseed) {
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}
255
256/**
257 * @brief Similar to random_1(), provides a separate random sequence with its own seed handling.
258 *
259 * @param[in] iseed Seed for initialization if negative.
260 * @return A random double in [0,1].
261 */
262double random_2(long iseed) {
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}
281
282/**
283 * @brief Similar to random_2(), provides another independent random sequence.
284 *
285 * @param[in] iseed Seed for initialization if negative.
286 * @return A random double in [0,1].
287 */
288double random_3(long iseed) {
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}
307
308/**
309 * @brief Similar to random_3(), provides another independent random sequence.
310 *
311 * @param[in] iseed Seed for initialization if negative.
312 * @return A random double in [0,1].
313 */
314double random_4(long iseed) {
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}
333
334/**
335 * @brief Similar to random_4(), provides another independent random sequence.
336 *
337 * @param[in] iseed Seed for initialization if negative.
338 * @return A random double in [0,1].
339 */
340double random_5(long iseed) {
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}
359
360/**
361 * @brief Similar to random_5(), provides another independent random sequence.
362 *
363 * @param[in] iseed Seed for initialization if negative.
364 * @return A random double in [0,1].
365 */
366double random_6(long iseed) {
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}
385
386/**
387 * @brief Generate a Gaussian-distributed random number with mean 0 and sigma 1.
388 *
389 * Uses the given uniform random generator `urandom` to produce Gaussian deviates
390 * via the Box–Muller transform.
391 *
392 * @param[in] iseed If negative, re-initializes the uniform RNG.
393 * @param[in] urandom Pointer to a uniform random number generator function.
394 * @return A Gaussian random deviate with mean 0 and sigma 1.
395 */
396double gauss_rn(long iseed, double (*urandom)(long iseed1)) {
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}
421
422/**
423 * @brief Generate a Gaussian-distributed random number with specified mean, sigma, and optional cutoff.
424 *
425 * If limit_in_sigmas > 0, values are regenerated until the deviate falls within ±limit_in_sigmas*sigma.
426 *
427 * @param[in] mean Mean of the Gaussian distribution.
428 * @param[in] sigma Standard deviation of the Gaussian distribution.
429 * @param[in] limit_in_sigmas Cutoff in multiples of sigma (if <= 0, no cutoff).
430 * @param[in] urandom Pointer to a uniform random number generator function.
431 * @return A Gaussian random deviate meeting the specified conditions.
432 */
434 double mean, double sigma,
435 double limit_in_sigmas, /* if <= 0, ignored. Otherwise, the distribution is
436 * cut off at +/-limit_in_sigmas*sigma from the mean */
437 double (*urandom)(long iseed)) {
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}
449
450/**
451 * @brief Convert a sequence of uniformly distributed [0,1] values into a Gaussian-distributed sequence.
452 *
453 * Uses the inverse error function (erf) to transform uniform data into Gaussian distributed data.
454 * Values that exceed the given limit are discarded.
455 *
456 * @param[in,out] data Array of input values in [0,1] to be converted.
457 * @param[in] points Number of values in the array.
458 * @param[in] limit Upper cutoff in standard deviations (if <= 0, no cutoff).
459 * @return The number of successfully converted data points.
460 */
461long convertSequenceToGaussianDistribution(double *data, long points, double limit) {
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}
490
491typedef struct {
492 char *buffer;
493 double randomValue;
495
496int randomizeOrderCmp(const void *p1, const void *p2) {
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}
507
508/**
509 * @brief Randomize the order of an array of elements.
510 *
511 * Shuffles the elements of an array using a provided uniform random generator.
512 *
513 * @param[in,out] ptr Pointer to the array to randomize.
514 * @param[in] size Size of each element in bytes.
515 * @param[in] length Number of elements in the array.
516 * @param[in] iseed Seed for initialization if negative.
517 * @param[in] urandom Pointer to a uniform random number generator function.
518 * @return Non-zero if successful, zero otherwise.
519 */
520long randomizeOrder(char *ptr, long size, long length, long iseed, double (*urandom)(long iseed1)) {
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}
556
557/**
558 * @brief Generate a uniform random double in [0,1] using a seed and increment, optimized for certain applications.
559 *
560 * Uses a custom random number generator implemented in Fortran (dlaran_oag).
561 *
562 * @param[in] iseed Seed for initialization if negative.
563 * @param[in] increment Increment to apply for each call.
564 * @return A random double in [0,1].
565 */
566double random_oag(long iseed, long increment) {
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}
586
587/**
588 * @brief Generate a Gaussian-distributed random number using the `random_oag` approach.
589 *
590 * Uses a modified Box–Muller method to generate Gaussian deviates from the `urandom` function provided.
591 *
592 * @param[in] iseed Seed for initialization if negative.
593 * @param[in] increment Increment step for random number generation.
594 * @param[in] urandom Pointer to an `oag`-style uniform random number generator function.
595 * @return A Gaussian random deviate with mean 0 and sigma 1.
596 */
597double gauss_rn_oag(long iseed, long increment, double (*urandom)(long iseed1, long increment)) {
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}
609
610/**
611 * @brief Generate a Gaussian-distributed random number with mean, sigma, and optional cutoff using `oag` RNG.
612 *
613 * If limit_in_sigmas > 0, values are regenerated until they fall within the cutoff range.
614 *
615 * @param[in] mean Mean of the Gaussian distribution.
616 * @param[in] sigma Standard deviation of the Gaussian distribution.
617 * @param[in] limit_in_sigmas Cutoff in multiples of sigma (if <= 0, no cutoff).
618 * @param[in] increment Increment step for random number generation.
619 * @param[in] urandom Pointer to an `oag`-style uniform random number generator function.
620 * @return A Gaussian random deviate meeting the specified conditions.
621 */
623 double mean, double sigma,
624 double limit_in_sigmas, /* if <= 0, ignored. Otherwise, the distribution is
625 * cut off at +/-limit_in_sigmas*sigma from the mean */
626 long increment,
627 double (*urandom)(long iseed, long increment)) {
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}
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_1(long iseed)
Generate a uniform random double in [0,1] using a custom seed initialization.
Definition drand.c:230
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
double random_6(long iseed)
Similar to random_5(), provides another independent random sequence.
Definition drand.c:366
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].
Definition drand.c:120
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.
Definition drand.c:622
float drand(long dummy)
Generate a uniform random float in [0,1].
Definition drand.c:86
long convertSequenceToGaussianDistribution(double *data, long points, double limit)
Convert a sequence of uniformly distributed [0,1] values into a Gaussian-distributed sequence.
Definition drand.c:461
short inhibitRandomSeedPermutation(short state)
Enable or disable permutation of seed bits for random number generators.
Definition drand.c:139
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
double random_oag(long iseed, long increment)
Generate a uniform random double in [0,1] using a seed and increment, optimized for certain applicati...
Definition drand.c:566
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
long randomizeOrder(char *ptr, long size, long length, long iseed, double(*urandom)(long iseed1))
Randomize the order of an array of elements.
Definition drand.c:520
double rdrand(double lo, double hi)
Generate a uniform random double in [lo, hi].
Definition drand.c:97
double dlaran_oag(integer *seed, long increment)
Advance the DLARAN seed and return a random number.
Definition dlaran.c:133
double random_2(long iseed)
Similar to random_1(), provides a separate random sequence with its own seed handling.
Definition drand.c:262
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.
Definition drand.c:433
double dlaran_(integer *seed)
Generates a random number using the DLARAN algorithm.
Definition dlaran.c:34
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