TPCCLIB
Loading...
Searching...
No Matches
gaussdev.c File Reference

Functions for creating random numbers. More...

#include "tpcclibConfig.h"
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <math.h>
#include <sys/time.h>
#include <time.h>
#include <string.h>
#include "tpcextensions.h"
#include "tpcrand.h"

Go to the source code of this file.

Functions

unsigned int drandSeed (short int seed)
 Make and optionally set the seed for rand(), drand, drandRange, and drandGaussian().
double drand ()
int drandRange (unsigned int nr, double *d, double low, double up, int type)
double drandGaussian ()
 Get pseudo-random number with normal (Gaussian) distribution with mean 0 and SD 1.
double drandExponential (double mean)
 Get pseudo-random number with exponential distribution.

Detailed Description

Functions for creating random numbers.

Definition in file gaussdev.c.

Function Documentation

◆ drand()

double drand ( )

Alternative function to rand() which returns a double precision floating point number in the range of [0,1] with uniform distribution.

Precondition
Uses rand(), therefore set seed for a new series of pseudo-random numbers; to produce truly random numbers (not just pseudo-random), do srand(time(0)) before calling this function. If no seed is set, then value 1 is used as default seed by rand().
See also
mertwiRandomDouble1, drandRange, drandSeed
Author
Vesa Oikonen
Returns
Random double value in the range [0,1].

Definition at line 66 of file gaussdev.c.

67{
68 double d, s;
69 s=1.0/(1.0+RAND_MAX);
70 do {
71 d = ( ( s*rand() + rand() )*s + rand() ) * s;
72 } while(d>=1.0);
73 return d;
74}

Referenced by drandExponential(), drandGaussian(), drandRange(), nloptPowellBrent(), and nloptRandomPoint().

◆ drandExponential()

double drandExponential ( double mean)

Get pseudo-random number with exponential distribution.

Precondition
Set seed for a new series of pseudo-random numbers; to produce truly random numbers (not just pseudo-random), do srand(time(0)) before calling this function. If no seed is set, then value 1 is used as default seed by rand().
See also
mertwiRandomExponential, drandRange, drandSeed
Returns
Returns the random non-negative double value with exponential distribution and given mean.
Parameters
meanMean of the exponential distribution.

Definition at line 178 of file gaussdev.c.

181 {
182 double r;
183 do {
184 r=drand();
185 } while(r==0.0);
186 return(-mean*log(r));
187}
double drand()
Definition gaussdev.c:66

Referenced by nloptIATGO().

◆ drandGaussian()

double drandGaussian ( )

Get pseudo-random number with normal (Gaussian) distribution with mean 0 and SD 1.

Applies the polar form of Box-Müller transform to produce pseudo-random numbers with Gaussian (normal) distribution which has a zero mean and standard deviation of one.

Box GEP, Muller ME. A note on the generation of random normal deviates. Annals of Mathematical Statistics, Volume 29, Issue 2, 1958, 610-611. Available from JSTOR https://www.jstor.org/

Precondition
Set seed for a new series of pseudo-random numbers; to produce truly random numbers (not just pseudo-random), do srand(time(0)) before calling this function. If no seed is set, then value 1 is used as default seed by rand().
See also
mertwiRandomGaussian, drandRange, drandSeed
Returns
Returns the pseudo-random double value with normal distribution with zero mean and standard deviation 1.

Definition at line 144 of file gaussdev.c.

145{
146 static int ready=0;
147 static double dev;
148 double fac, rsq, a, b;
149
150 /* If we don't have deviate already, then we'll have to make one */
151 if(!ready) {
152 do {
153 a = 2.*drand() - 1.0;
154 b = 2.*drand() - 1.0;
155 rsq = a*a + b*b;
156 } while (rsq>1.0 || rsq==0.0);
157
158 fac = sqrt(-2.0*log(rsq)/rsq);
159 dev=a*fac; ready=1;
160 return(b*fac);
161 } else { /* dev is ready so return it */
162 ready=0;
163 return(dev);
164 }
165}

Referenced by nloptGaussianPoint().

◆ drandRange()

int drandRange ( unsigned int nr,
double * d,
double low,
double up,
int type )

Fill the given double array with random numbers with uniform distribution between the specified limits.

With uniform distribution, the SD=(up-low)/sqrt(12), and CV=(up-low)/(sqrt(3)*(low+up)).

Precondition
Set seed for a new series of pseudo-random numbers; to produce truly random numbers (not just pseudo-random), do srand(time(0)) before calling this function. If no seed is set, then value 1 is used as default seed by rand().
See also
mertwiRandomBetween, drand, drandSeed
Author
Vesa Oikonen
Returns
0 when successful, otherwise <> 0.
Parameters
nrNr of values in double array.
dPointer to pre-allocated double array.
lowLower limit for random values.
upUpper limit for random values.
typeDistribution: 0=even, 1=square-root transformation.

Definition at line 90 of file gaussdev.c.

101 {
102 unsigned int i;
103 double dif, v, stl, stu;
104
105 if(nr<1) return 0;
106 if(d==NULL || type<0 || type>1) return 1;
107
108 dif=up-low; if(dif<0.0) return 2;
109 if(dif==0.0) {
110 for(i=0; i<nr; i++) d[i]=low;
111 return 0;
112 }
113
114 if(type==0) {
115 for(i=0; i<nr; i++) d[i] = drand()*dif + low;
116 } else if(type==1) {
117 stl=copysign(sqrt(fabs(low)),low); if(!isnormal(stl)) stl=0.0;
118 stu=copysign(sqrt(fabs(up)), up); if(!isnormal(stu)) stu=0.0;
119 dif=stu-stl;
120 for(i=0; i<nr; i++) {v=drand()*dif+stl; d[i]=copysign(v*v, v);}
121 }
122
123 return 0;
124}

◆ drandSeed()

unsigned int drandSeed ( short int seed)

Make and optionally set the seed for rand(), drand, drandRange, and drandGaussian().

Uses microseconds from the computer clock and process ID to reduce the chance of getting the same seed for simultaneously executing program threads and instances.

See also
mertwiSeed64
Returns
Returns the seed for srand().
Parameters
seedAlso sets seed with srand (1) or not (0).

Definition at line 27 of file gaussdev.c.

30 {
31 unsigned int li;
32#if defined HAVE_TIMESPEC_GET
33 struct timespec ts;
34 timespec_get(&ts, TIME_UTC);
35 //li=(unsigned int)ts.tv_sec+(unsigned int)ts.tv_nsec+(unsigned int)getpid();
36 li=((ts.tv_sec % 10000)*523 ^ ts.tv_nsec*10) ^ ((getpid() % 1000)*983);
37#elif defined HAVE_CLOCK_GETTIME
38 struct timespec ts;
39 clock_gettime(CLOCK_REALTIME, &ts);
40 //li=(unsigned int)ts.tv_sec+(unsigned int)ts.tv_nsec+(unsigned int)getpid();
41 li=((ts.tv_sec % 10000)*523 ^ ts.tv_nsec*10) ^ ((getpid() % 1000)*983);
42#elif defined HAVE_GETTIMEOFDAY
43 struct timeval tv;
44 gettimeofday(&tv, 0);
45 li=((tv.tv_sec % 10000)*523 ^ tv.tv_usec*13) ^ ((getpid() % 1000)*983);
46#else
47 li=(unsigned int)time(NULL)+(unsigned int)getpid();
48#endif
49 li+=(unsigned int)rand();
50 if(seed) srand(li);
51 return(li);
52}