ASCOT5
Loading...
Searching...
No Matches
random.c
Go to the documentation of this file.
1
5#if defined(RANDOM_MKL)
6
7#include <mkl_vsl.h>
8#include "random.h"
9
10void random_mkl_init(random_data* rdata, int seed) {
11 vslNewStream(&rdata->r, RANDOM_MKL_RNG, seed);
12}
13
14double random_mkl_uniform(random_data* rdata) {
15 double r;
16 vdRngUniform(VSL_RNG_METHOD_UNIFORM_STD, rdata->r, 1, &r, 0.0, 1.0);
17 return r;
18}
19
20double random_mkl_normal(random_data* rdata) {
21 double r;
22 vdRngGaussian(VSL_RNG_METHOD_GAUSSIAN_BOXMULLER, rdata->r, 1, &r, 0.0, 1.0);
23 return r;
24}
25
26void random_mkl_uniform_simd(random_data* rdata, int n, double* r) {
27 vdRngUniform(VSL_RNG_METHOD_UNIFORM_STD, rdata->r, n, r, 0.0, 1.0);
28}
29
30void random_mkl_normal_simd(random_data* rdata, int n, double* r) {
31 vdRngGaussian(VSL_RNG_METHOD_GAUSSIAN_BOXMULLER2, rdata->r, n, r, 0.0, 1.0);
32}
33
34
35#elif defined(RANDOM_GSL)
36
37#include <gsl/gsl_rng.h>
38#include "random.h"
39
40void random_gsl_init(random_data* rdata, int seed) {
41 rdata->r = gsl_rng_alloc(gsl_rng_mt19937);
42 gsl_rng_set(rdata->r, seed);
43}
44
45double random_gsl_uniform(random_data* rdata) {
46 return gsl_rng_uniform(rdata->r);
47}
48
49double random_gsl_normal(random_data* rdata) {
50 return gsl_ran_gaussian(rdata->r, 1.0);
51}
52
53void random_gsl_uniform_simd(random_data* rdata, int n, double* r) {
54 #pragma omp simd
55 for(int i = 0; i < n; i++) {
56 r[i] = gsl_rng_uniform(rdata->r);
57 }
58}
59
60void random_gsl_normal_simd(random_data* rdata, int n, double* r) {
61 #pragma omp simd
62 for(int i = 0; i < n; i++) {
63 r[i] = gsl_ran_gaussian(rdata->r, 1.0);
64 }
65}
66
67
68#elif defined(RANDOM_LCG)
69
70#include <stdint.h>
71#include <math.h>
72#include "ascot5.h"
73#include "consts.h"
74#include "random.h"
75
76void random_lcg_init(random_data* rdata, uint64_t seed) {
77 rdata->r = seed;
78}
79
80uint64_t random_lcg_integer(random_data* rdata) {
81 /* parameters from https://nuclear.llnl.gov/CNP/rng/rngman/node4.html */
82 uint64_t a = 2862933555777941757;
83 uint64_t b = 3037000493;
84 rdata->r = (a * rdata->r + b);
85 return rdata->r;
86}
87
88double random_lcg_uniform(random_data* rdata) {
89 double r;
90 random_lcg_uniform_simd(rdata, 1, &r);
91 return r;
92}
93
94double random_lcg_normal(random_data* rdata) {
95 double r;
96 random_lcg_normal_simd(rdata, 1, &r);
97 return r;
98}
99
100void random_lcg_uniform_simd(random_data* rdata, int n, double* r) {
101#ifndef GPU
102 #pragma omp simd
103#endif
104 for(int i = 0; i < n; i++) {
105 r[i] = (double) random_lcg_integer(rdata) / UINT64_MAX;
106 }
107}
108
109void random_lcg_normal_simd(random_data* rdata, int n, double* r) {
110 double x1, x2, w; /* Helper variables */
111 int isEven = (n+1) % 2; /* Indicates if even number of random numbers are
112 requested */
113
114#if A5_CCOL_USE_GEOBM == 1
115 /* The geometric form */
116 GPU_PARALLEL_LOOP_ALL_LEVELS
117 for(int i = 0; i < n; i=i+2) {
118 random_data* ri = random_lcg_state_at(rdata, i);
119 w = 2.0;
120 while( w >= 1.0 ) {
121 x1 = 2*random_lcg_uniform(ri)-1;
122 x2 = 2*random_lcg_uniform(ri)-1;
123 w = x1*x1 + x2*x2;
124 }
125
126 w = sqrt( (-2 * log( w ) ) / w );
127 r[i] = x1 * w;
128 if((i < n-2) || (isEven > 0)) {
129 r[i+1] = x2 * w;
130 }
131 }
132#else
133 /* The common form */
134 double s;
135 GPU_PARALLEL_LOOP_ALL_LEVELS
136 for(int i = 0; i < n; i=i+2) {
137 random_data* ri = random_lcg_state_at(rdata, i);
138 x1 = random_lcg_uniform(ri);
139 x2 = random_lcg_uniform(ri);
140 w = sqrt(-2*log(x1));
141 s = cos(CONST_2PI*x2);
142 r[i] = w*s;
143 if((i < n-2) || (isEven > 0) ) {
144 if(x2 < 0.5) {
145 r[i+1] = w*sqrt(1-s*s);
146 }
147 else {
148 r[i+1] = -w*sqrt(1-s*s);
149 }
150 }
151 }
152#endif
153}
154
155#else /* No RNG lib defined, use drand48 */
156
157#include <stdlib.h>
158#include <math.h>
159#include "ascot5.h"
160#include "consts.h"
161#include "random.h"
162
169 double r;
171 return r;
172}
173
182void random_drand48_uniform_simd(int n, double* r) {
183 #pragma omp simd
184 for(int i = 0; i < n; i++) {
185 r[i] = drand48();
186 }
187}
188
197void random_drand48_normal_simd(int n, double* r) {
198 double x1, x2, w; /* Helper variables */
199 int isEven = (n+1) % 2; /* Indicates if even number of random numbers
200 are requested */
201
202#if A5_CCOL_USE_GEOBM == 1
203 /* The geometric form */
204 #pragma omp simd
205 for(int i = 0; i < n; i=i+2) {
206 w = 2.0;
207 while( w >= 1.0 ) {
208 x1 = 2*drand48()-1;
209 x2 = 2*drand48()-1;
210 w = x1*x1 + x2*x2;
211 }
212
213 w = sqrt( (-2 * log( w ) ) / w );
214 r[i] = x1 * w;
215 if((i < n-2) || (isEven > 0)) {
216 r[i+1] = x2 * w;
217 }
218 }
219#else
220 /* The common form */
221 double s;
222 #pragma omp simd
223 for(int i = 0; i < n; i=i+2) {
224 x1 = drand48(rdata);
225 x2 = drand48(rdata);
226 w = sqrt(-2*log(x1));
227 s = cos(CONST_2PI*x2);
228 r[i] = w*s;
229 if((i < n-2) || (isEven > 0) ) {
230 if(x2 < 0.5) {
231 r[i+1] = w*sqrt(1-s*s);
232 }
233 else {
234 r[i+1] = -w*sqrt(1-s*s);
235 }
236 }
237 }
238#endif
239}
240
241#endif
random_data rdata
Definition afsi.c:26
Main header file for ASCOT5.
Header file containing physical and mathematical constants.
#define CONST_2PI
2*pi
Definition consts.h:14
Header file for math.c.
void random_drand48_uniform_simd(int n, double *r)
Vectorised sampling from uniform distribution.
Definition random.c:182
double random_drand48_normal()
Initialize random generator which uses the linear congruential algorithm and 48-bit integer arithmeti...
Definition random.c:168
void random_drand48_normal_simd(int n, double *r)
Vectorised sampling from normal distribution.
Definition random.c:197
Header file for random.c.
void * random_data
Definition random.h:100