su2hmc
Loading...
Searching...
No Matches
random.h File Reference

Header for random number configuration. More...

#include <math.h>
#include <par_mpi.h>
#include <sizes.h>
Include dependency graph for random.h:
This graph shows which files directly or indirectly include this file:

Go to the source code of this file.

Macros

#define RAN2
 
#define IM1   2147483563
 
#define IM2   2147483399
 
#define AM   (1.0/IM1)
 
#define IMM1   (IM1-1)
 
#define IA1   40014
 
#define IA2   40692
 
#define IQ1   53668
 
#define IQ2   52774
 
#define IR1   12211
 
#define IR2   3791
 
#define NTAB   32
 
#define NDIV   (1+IMM1/NTAB)
 
#define EPS   1.2e-7
 
#define RNMX   (1.0-EPS)
 

Functions

int ranset (long *seed)
 Dummy seed the ran2 generator.
 
int Par_ranset (long *seed, int iread)
 Uses the rank to get a new seed. Copying from the FORTRAN description here c create new seeds in range seed to 9*seed c having a range of 0*seed gave an unfortunate pattern c in the underlying value of ds(1) (it was always 10 times bigger c on the last processor). This does not appear to happen with 9.
 
double ran2 (long *idum)
 Generates uniformly distributed random double between zero and one as described in numerical recipes. It's also thread-safe for different seeds.
 
int Gauss_z (Complex *ps, unsigned int n, const Complex mu, const double sigma)
 Generates a vector of normally distributed random double precision complex numbers using the Box-Muller Method.
 
int Gauss_d (double *ps, unsigned int n, const double mu, const double sigma)
 Generates a vector of normally distributed random double precision numbers using the Box-Muller Method.
 
int Gauss_c (Complex_f *ps, unsigned int n, const Complex_f mu, const float sigma)
 Generates a vector of normally distributed random single precision complex numbers using the Box-Muller Method.
 
int Gauss_f (float *ps, unsigned int n, const float mu, const float sigma)
 Generates a vector of normally distributed random single precision numbers using the Box-Muller Method.
 
int Par_ranread (char *filename, double *ranval)
 Reads ps from a file Since this function is very similar to Par_sread, I'm not really going to comment it check there if you are confused about things.
 
double Par_granf ()
 Generates a random double which is then sent to the other ranks.
 
int ran_test ()
 Test Functions.
 

Variables

long seed
 RAN2 seed.
 

Detailed Description

Header for random number configuration.

Definition in file random.h.

Macro Definition Documentation

◆ AM

#define AM   (1.0/IM1)

Definition at line 234 of file random.h.

◆ EPS

#define EPS   1.2e-7

Definition at line 244 of file random.h.

◆ IA1

#define IA1   40014

Definition at line 236 of file random.h.

◆ IA2

#define IA2   40692

Definition at line 237 of file random.h.

◆ IM1

#define IM1   2147483563

Definition at line 232 of file random.h.

◆ IM2

#define IM2   2147483399

Definition at line 233 of file random.h.

◆ IMM1

#define IMM1   (IM1-1)

Definition at line 235 of file random.h.

◆ IQ1

#define IQ1   53668

Definition at line 238 of file random.h.

◆ IQ2

#define IQ2   52774

Definition at line 239 of file random.h.

◆ IR1

#define IR1   12211

Definition at line 240 of file random.h.

◆ IR2

#define IR2   3791

Definition at line 241 of file random.h.

◆ NDIV

#define NDIV   (1+IMM1/NTAB)

Definition at line 243 of file random.h.

◆ NTAB

#define NTAB   32

Definition at line 242 of file random.h.

◆ RAN2

#define RAN2

Definition at line 231 of file random.h.

◆ RNMX

#define RNMX   (1.0-EPS)

Definition at line 245 of file random.h.

Function Documentation

◆ Gauss_c()

int Gauss_c ( Complex_f * ps,
unsigned int n,
const Complex_f mu,
const float sigma )

Generates a vector of normally distributed random single precision complex numbers using the Box-Muller Method.

Parameters
psThe output array
nThe array length
mumean
sigmavariance
Returns
Zero on success integer error code otherwise

Definition at line 260 of file random.c.

260 {
261 /*
262 * @brief Generates a vector of normally distributed random single precision complex numbers using the Box-Muller Method
263 *
264 * @param ps: The output array
265 * @param n: The array length
266 * @param mu: mean
267 * @param sigma: variance
268 *
269 * @see ran2(), par_dcopy(), gsl_rng_uniform(), vdRngUniform()
270 *
271 * @return Zero on success integer error code otherwise
272 */
273 const char *funcname = "Gauss_z";
274 if(n<=0){
275 fprintf(stderr, "Error %i in %s: Array cannot have length %i.\nExiting...\n\n",
276 ARRAYLEN, funcname, n);
277#if(nproc>1)
278 MPI_Abort(comm,ARRAYLEN);
279#else
280 exit(ARRAYLEN);
281#endif
282 }
283#pragma unroll
284 for(int i=0;i<n;i++){
285 /* Marsaglia Method for fun
286 do{
287 u=sfmt_genrand_real1(sfmt);
288 v=sfmt_genrand_real1(sfmt);
289 r=u*u+v*v;
290 }while(0<r & r<1);
291 r=sqrt(r);
292 r=sqrt(-2.0*log(r)/r)*sigma;
293 ps[i] = mu+u*r + I*(mu+v*r);
294 */
295#ifdef __RANLUX__
296 float r =sigma*sqrt(-2*log(gsl_rng_uniform(ranlux_instd)));
297 float theta=2.0*M_PI*gsl_rng_uniform(ranlux_instd);
298#else
299 float r =sigma*sqrt(-2*log(ran2(&seed)));
300 float theta=2.0*M_PI*ran2(&seed);
301#endif
302 ps[i]=r*(cos(theta)+mu+sin(theta)*I)+mu;
303 }
304 return 0;
305}
#define M_PI
if not defined elsewhere
Definition random.c:41
double ran2(long *idum)
Generates uniformly distributed random double between zero and one as described in numerical recipes....
Definition random.c:440
long seed
RAN2 seed.
Definition random.c:27

References M_PI, ran2(), and seed.

Here is the call graph for this function:
Here is the caller graph for this function:

◆ Gauss_d()

int Gauss_d ( double * ps,
unsigned int n,
const double mu,
const double sigma )

Generates a vector of normally distributed random double precision numbers using the Box-Muller Method.

Parameters
psThe output array
nThe array length
mumean
sigmavariance
Returns
Zero on success integer error code otherwise

Definition at line 306 of file random.c.

306 {
307 /*
308 * @brief Generates a vector of normally distributed random double precision numbers using the Box-Muller Method
309 *
310 * @param ps: The output array
311 * @param n: The array length
312 * @param mu: mean
313 * @param sigma: variance
314 *
315 * @see ran2(), par_dcopy(), gsl_rng_uniform(), vdRngUniform()
316 *
317 * @return Zero on success integer error code otherwise
318 */
319 const char *funcname = "Gauss_z";
320 //The FORTRAN Code had two different Gauss Routines. gaussp having unit
321 //mean and variance and gauss0 where the variance would appear to be 1/sqrt(2)
322 //(Since we multiply by sqrt(-ln(r)) instead of sqrt(-2ln(r)) )
323 if(n<=0){
324 fprintf(stderr, "Error %i in %s: Array cannot have length %i.\nExiting...\n\n",
325 ARRAYLEN, funcname, n);
326#if(nproc>1)
327 MPI_Abort(comm,ARRAYLEN);
328#else
329 exit(ARRAYLEN);
330#endif
331 }
332 int i;
333 double r, u, v;
334 //If n is odd we calculate the last index seperately and the rest in pairs
335 if(n%2==1){
336 n--;
337#ifdef __RANLUX__
338 r=2.0*M_PI*gsl_rng_uniform(ranlux_instd);
339 ps[n]=sqrt(-2*log(gsl_rng_uniform(ranlux_instd)))*cos(r);
340#else
341 r=2.0*M_PI*ran2(&seed);
342 ps[n]=sqrt(-2*log(ran2(&seed)))*cos(r);
343#endif
344 }
345 for(i=0;i<n;i+=2){
346 /* Marsaglia Method for fun
347 do{
348 u=sfmt_genrand_real1(sfmt);
349 v=sfmt_genrand_real1(sfmt);
350 r=u*u+v*v;
351 }while(0<r & r<1);
352 r=sqrt(r);
353 r=sqrt(-2.0*log(r)/r)*sigma;
354 ps[i] = mu+u*r;
355 ps[i+1]=mu+v*r;
356 */
357#ifdef __RANLUX__
358 u=sqrt(-2*log(gsl_rng_uniform(ranlux_instd)))*sigma;
359 r=2.0*M_PI*gsl_rng_uniform(ranlux_instd);
360#else
361 u=sqrt(-2*log(ran2(&seed)))*sigma;
362 r=2.0*M_PI*ran2(&seed);
363#endif
364 ps[i]=u*cos(r)+mu;
365 ps[i+1]=u*sin(r)+mu;
366 }
367 return 0;
368}

References M_PI, ran2(), and seed.

Here is the call graph for this function:
Here is the caller graph for this function:

◆ Gauss_f()

int Gauss_f ( float * ps,
unsigned int n,
const float mu,
const float sigma )

Generates a vector of normally distributed random single precision numbers using the Box-Muller Method.

Parameters
psThe output array
nThe array length
mumean
sigmavariance
Returns
Zero on success integer error code otherwise

Definition at line 369 of file random.c.

369 {
370 /*
371 * @brief Generates a vector of normally distributed random single precision numbers using the Box-Muller Method
372 *
373 * @param ps: The output array
374 * @param n: The array length
375 * @param mu: mean
376 * @param sigma: variance
377 *
378 * @see ran2(), par_dcopy(), gsl_rng_uniform(), vdRngUniform()
379 *
380 * @return Zero on success integer error code otherwise
381 */
382 const char *funcname = "Gauss_z";
383 //The FORTRAN Code had two different Gauss Routines. gaussp having unit
384 //mean and variance and gauss0 where the variance would appear to be 1/sqrt(2)
385 //(Since we multiply by sqrt(-ln(r)) instead of sqrt(-2ln(r)) )
386 if(n<=0){
387 fprintf(stderr, "Error %i in %s: Array cannot have length %i.\nExiting...\n\n",
388 ARRAYLEN, funcname, n);
389#if(nproc>1)
390 MPI_Abort(comm,ARRAYLEN);
391#else
392 exit(ARRAYLEN);
393#endif
394 }
395 int i;
396 float r, u, v;
397 //If n is odd we calculate the last index seperately and the rest in pairs
398 if(n%2==1){
399 n--;
400#ifdef __RANLUX__
401 r=2.0*M_PI*gsl_rng_uniform(ranlux_instd);
402 ps[n]=sqrt(-2*log(gsl_rng_uniform(ranlux_instd)))*cos(r);
403#else
404 r=2.0*M_PI*ran2(&seed);
405 ps[n]=sqrt(-2*log(ran2(&seed)))*cos(r);
406#endif
407 }
408#ifdef __RANLUX__
409 r=2.0*M_PI*gsl_rng_uniform(ranlux_instd);
410 ps[n]=sqrt(-2*log(gsl_rng_uniform(ranlux_instd)))*cos(r);
411#else
412 r=2.0*M_PI*ran2(&seed);
413 ps[n]=sqrt(-2*log(ran2(&seed)))*cos(r);
414#endif
415 for(i=0;i<n;i+=2){
416 /* Marsaglia Method for fun
417 do{
418 u=sfmt_genrand_real1(sfmt);
419 v=sfmt_genrand_real1(sfmt);
420 r=u*u+v*v;
421 }while(0<r & r<1);
422 r=sqrt(r);
423 r=sqrt(-2.0*log(r)/r)*sigma;
424 ps[i] = mu+u*r;
425 ps[i+1]=mu+v*r;
426 */
427#ifdef __RANLUX__
428 u=sqrt(-2*log(gsl_rng_uniform(ranlux_instd)))*sigma;
429 r=2.0*M_PI*gsl_rng_uniform(ranlux_instd);
430#else
431 u=sqrt(-2*log(ran2(&seed)))*sigma;
432 r=2.0*M_PI*ran2(&seed);
433#endif
434 ps[i]=u*cos(r)+mu;
435 ps[i+1]=u*sin(r)+mu;
436 }
437 return 0;
438}

References M_PI, ran2(), and seed.

Here is the call graph for this function:

◆ Gauss_z()

int Gauss_z ( Complex * ps,
unsigned int n,
const Complex mu,
const double sigma )

Generates a vector of normally distributed random double precision complex numbers using the Box-Muller Method.

Parameters
psThe output array
nThe array length
mumean
sigmavariance
Returns
Zero on success integer error code otherwise

Definition at line 214 of file random.c.

214 {
215 /*
216 * @brief Generates a vector of normally distributed random double precision complex numbers using the Box-Muller Method
217 *
218 * @param ps: The output array
219 * @param n: The array length
220 * @param mu: mean
221 * @param sigma: variance
222 *
223 * @see ran2(), par_dcopy(), gsl_rng_uniform(), vdRngUniform()
224 *
225 * @return Zero on success integer error code otherwise
226 */
227 const char *funcname = "Gauss_z";
228 if(n<=0){
229 fprintf(stderr, "Error %i in %s: Array cannot have length %i.\nExiting...\n\n",
230 ARRAYLEN, funcname, n);
231#if(nproc>1)
232 MPI_Abort(comm,ARRAYLEN);
233#else
234 exit(ARRAYLEN);
235#endif
236 }
237#pragma unroll
238 for(int i=0;i<n;i++){
239 /* Marsaglia Method for fun
240 do{
241 u=sfmt_genrand_real1(sfmt);
242 v=sfmt_genrand_real1(sfmt);
243 r=u*u+v*v;
244 }while(0<r & r<1);
245 r=sqrt(r);
246 r=sqrt(-2.0*log(r)/r)*sigma;
247 ps[i] = mu+u*r + I*(mu+v*r);
248 */
249#ifdef __RANLUX__
250 double r =sigma*sqrt(-2*log(gsl_rng_uniform(ranlux_instd)));
251 double theta=2.0*M_PI*gsl_rng_uniform(ranlux_instd);
252#else
253 double r =sigma*sqrt(-2*log(ran2(&seed)));
254 double theta=2.0*M_PI*ran2(&seed);
255#endif
256 ps[i]=r*(cos(theta)+sin(theta)*I)+mu;
257 }
258 return 0;
259}

References M_PI, ran2(), and seed.

Here is the call graph for this function:

◆ Par_granf()

double Par_granf ( )

Generates a random double which is then sent to the other ranks.

Returns
the random number generated

Definition at line 190 of file random.c.

190 {
191 /*
192 * @brief Generates a random double which is then sent to the other ranks
193 *
194 * @see ran2(), par_dcopy(), gsl_rng_uniform(), vdRngUniform()
195 *
196 * @return the random number generated
197 */
198 const char *funcname = "Par_granf";
199 double ran_val=0;
200 if(!rank){
201#if (defined USE_RAN2||(!defined __INTEL_MKL__&&!defined __RANLUX__))
202 ran_val = ran2(&seed);
203#elif defined __RANLUX__
204 ran_val = gsl_rng_uniform(ranlux_instd);
205#else
206 vdRngUniform(VSL_RNG_METHOD_UNIFORM_STD_ACCURATE, stream, 1, &ran_val, 0,1);
207#endif
208 }
209#if(nproc>1)
210 Par_dcopy(&ran_val);
211#endif
212 return ran_val;
213}
int Par_dcopy(double *dval)
Broadcasts a double to the other processes.
int rank
The MPI rank.
Definition par_mpi.c:22

References Par_dcopy(), ran2(), rank, and seed.

Here is the call graph for this function:

◆ Par_ranread()

int Par_ranread ( char * filename,
double * ranval )

Reads ps from a file Since this function is very similar to Par_sread, I'm not really going to comment it check there if you are confused about things.

Parameters
filenameThe name of the file we're reading from
ranvalThe destination for the file's contents
Returns
Zero on success, integer error code otherwise

Definition at line 88 of file random.c.

88 {
89 /*
90 * @brief Reads ps from a file
91 * Since this function is very similar to Par_sread, I'm not really going to comment it
92 * check there if you are confused about things.
93 *
94 * @param *filename: The name of the file we're reading from
95 * @param ps: The destination for the file's contents
96 *
97 * @return Zero on success, integer error code otherwise
98 */
99 const char *funcname = "Par_psread";
100 FILE *dest;
101 if(!rank){
102 if(!(dest = fopen(filename, "rb"))){
103 fprintf(stderr, "Error %i in %s: Failed to open %s.\nExiting...\n\n", OPENERROR, funcname, filename);
104#if(nproc>1)
105 MPI_Abort(comm,OPENERROR);
106#else
107 exit(OPENERROR);
108#endif
109
110 }
111 fread(&ranval, sizeof(ranval), 1, dest);
112 fclose(dest);
113 }
114#if(nproc>1)
115 Par_dcopy(ranval);
116#endif
117 return 0;
118}

References Par_dcopy(), and rank.

Here is the call graph for this function:

◆ Par_ranset()

int Par_ranset ( long * seed,
int iread )

Uses the rank to get a new seed. Copying from the FORTRAN description here c create new seeds in range seed to 9*seed c having a range of 0*seed gave an unfortunate pattern c in the underlying value of ds(1) (it was always 10 times bigger c on the last processor). This does not appear to happen with 9.

Parameters
seedThe seed from the rank in question.
ireadDo we read from file or not. Don't remember why it's here as it's not used
Returns
Zero on success, integer error code otherwise

Definition at line 135 of file random.c.

171{
172 const char *funcname = "Par_ranset";
173 //If we're not using the master thread, we need to change the seed
174#ifdef _DEBUG
175 printf("Master seed: %i\t",*seed);
176#endif
177 if(rank)
178 *seed *= 1.0f+8.0f*(float)rank/(float)(size-1);
179#ifdef _DEBUG
180 printf("Rank: %i\tSeed %i\n",rank, *seed);
181#endif
182 //Next we set the seed using ranset
183 //This is one of the really weird FORTRAN 66-esque functions with ENTRY points, so good luck!
184#if (defined __INTEL_MKL__||defined __RANLUX__)
185 return ranset(seed);
186#else
187 return 0;
188#endif
189}
int size
The number of MPI ranks in total.
Definition par_mpi.c:22
int ranset(long *seed)
Dummy seed the ran2 generator.
Definition random.c:74

References rank, ranset(), seed, and size.

Here is the call graph for this function:
Here is the caller graph for this function:

◆ ran2()

double ran2 ( long * idum)

Generates uniformly distributed random double between zero and one as described in numerical recipes. It's also thread-safe for different seeds.

Parameters
idumPointer to the seed
Returns
The random double between zero and one

Definition at line 440 of file random.c.

440 {
441 /*
442 * @brief Generates uniformly distributed random double between zero and one as
443 * described in numerical recipes. It's also thread-safe for different seeds.
444 *
445 * @param idum: Pointer to the seed
446 *
447 * @return The random double between zero and one
448 *
449 */
450 long k;
451 int j;
452 static long idum2=123456789;
453 static long iy=0;
454 static long iv[NTAB];
456#pragma omp threadprivate(idum2, iy, iv)
457 //No worries
458 double temp;
459
460 if (*idum <= 0) {
461 if (-(*idum) < 1) *idum=1;
462 else *idum = -(*idum);
463 {
464 idum2=(*idum);
465
466 for(j=NTAB+7;j>=0;j--) {
467 k=(*idum)/IQ1;
468 *idum=IA1*(*idum-k*IQ1)-k*IR1;
469 if (*idum < 0) *idum += IM1;
470 if (j < NTAB)
471 iv[j] = *idum;
472 }
473 iy=iv[0];
474 }
475 }
476 k=(*idum)/IQ1;
477 *idum=IA1*(*idum-k*IQ1)-k*IR1;
478 if (*idum < 0) *idum += IM1;
479 k=idum2/IQ2;
480 idum2=IA2*(idum2-k*IQ2)-k*IR2;
481
482 if (idum2 < 0) idum2 += IM2; j=iy/NDIV;
483 iy=iv[j]-idum2;
484 iv[j] = *idum;
485 if (iy < 1) iy += IMM1;
486 if ((temp=AM*iy) > RNMX)
487 return RNMX;
488
489 else return temp;
490
491}
Here is the caller graph for this function:

◆ ranset()

int ranset ( long * seed)
inline

Dummy seed the ran2 generator.

Parameters
seedpointer to seed
Returns
0

Definition at line 74 of file random.c.

76{
77#ifdef __RANLUX__
78 ranlux_instd=gsl_rng_alloc(gsl_rng_ranlxd2);
79 gsl_rng_set(ranlux_instd,*seed);
80 return 0;
81#elif (defined __INTEL_MKL__&& !defined USE_RAN2)
82 vslNewStream( &stream, VSL_BRNG_MT19937, *seed );
83 return 0;
84#else
85 return 0;
86#endif
87}

References seed.

Here is the caller graph for this function:

Variable Documentation

◆ seed

long seed
extern

RAN2 seed.

Definition at line 27 of file random.c.