source: issm/trunk/src/c/shared/Random/randomgenerator.cpp@ 27035

Last change on this file since 27035 was 27035, checked in by Mathieu Morlighem, 3 years ago

merged trunk-jpl and trunk for revision 27033

  • Property svn:executable set to *
File size: 4.9 KB
Line 
1/*!\file: randomgenerator
2 * \brief random number generating functions
3 */
4
5#include <iostream>
6#include "./randomgenerator.h"
7#include <cmath>
8#include <chrono>
9
10#undef M_PI
11#define M_PI 3.141592653589793238462643
12
13namespace rnd{
14
15 /* Linear congruential engine */
16
17 linear_congruential_engine::linear_congruential_engine(){/*{{{*/
18
19 pseed = new unsigned int;
20 *pseed = std::chrono::steady_clock::now().time_since_epoch()/std::chrono::milliseconds(1);
21 a = 1103515245; // BSD Formula
22 c = 12345; // BSD Formula
23 m = 2147483648; // BSD Formula
24 return;
25 }/*}}}*/
26 linear_congruential_engine::linear_congruential_engine(unsigned int _a, unsigned int _b, unsigned int _m){/*{{{*/
27
28 pseed = new unsigned int;
29 *pseed = std::chrono::steady_clock::now().time_since_epoch()/std::chrono::milliseconds(1);
30 a = _a;
31 c = _b;
32 m = _m;
33 return;
34 }/*}}}*/
35 linear_congruential_engine::~linear_congruential_engine(){}
36
37 unsigned int linear_congruential_engine::get_m() { return m; }
38
39 void linear_congruential_engine::seed( int s ) {
40 if(s<0)
41 *pseed = std::chrono::steady_clock::now().time_since_epoch()/std::chrono::milliseconds(1);
42 else
43 *pseed = (unsigned) s;
44 }
45
46 unsigned int linear_congruential_engine::generator(){
47 *pseed = ( a * *pseed + c ) % m ;
48 return *pseed;
49 }
50
51 void linear_congruential_engine::free_resources(){
52 delete pseed;
53 return;
54 }
55
56 /* Uniform distribution */
57
58 uniform_distribution::uniform_distribution(){/*{{{*/
59 a = 0.0;
60 b = 1.0;
61 return;
62 }
63 /*}}}*/
64
65 uniform_distribution::uniform_distribution(double _a,double _b){/*{{{*/
66 a = _a;
67 b = _b;
68 return;
69 }
70 /*}}}*/
71
72 uniform_distribution::~uniform_distribution(){}
73
74 double uniform_distribution::generator(rnd::linear_congruential_engine random_engine) {
75 return (b-a)*(double) random_engine.generator()/ random_engine.get_m() + a;
76 }
77
78 /* Normal distribution */
79
80 normal_distribution::normal_distribution(){/*{{{*/
81 mean = 0;
82 sdev = 1.0;
83 return;
84 }
85 /*}}}*/
86
87 normal_distribution::normal_distribution(double m,double s){/*{{{*/
88 mean = m;
89 sdev = s;
90 return;
91 }
92 /*}}}*/
93
94 normal_distribution::~normal_distribution(){}
95
96 double normal_distribution::generator(rnd::linear_congruential_engine random_engine){/*{{{*/
97
98 rnd::uniform_distribution distribution;
99
100 double u1 = distribution.generator(random_engine);
101 double u2 = distribution.generator(random_engine);
102
103 double R = sqrt(-2*log(u1));
104 double theta = 2*M_PI*u2;
105
106 return mean + sdev * (R*cos(theta));
107
108 }
109 /*}}}*/
110
111 /* Log-Normal distribution */
112
113 lognormal_distribution::lognormal_distribution(){/*{{{*/
114 logmean = 0;
115 logsdev = 1.0;
116 return;
117 }
118 /*}}}*/
119
120 lognormal_distribution::lognormal_distribution(double m,double s){/*{{{*/
121 logmean = m;
122 logsdev = s;
123 return;
124 }
125 /*}}}*/
126
127 lognormal_distribution::~lognormal_distribution(){}
128
129 double lognormal_distribution::generator(rnd::linear_congruential_engine random_engine){/*{{{*/
130
131 rnd::normal_distribution distribution(logmean,logsdev);
132
133 return exp(distribution.generator(random_engine));
134
135 }
136 /*}}}*/
137
138 /* Chi-squared distribution */
139
140 chi_squared_distribution::chi_squared_distribution(){/*{{{*/
141 k = 1;
142 return;
143 }
144 /*}}}*/
145
146 chi_squared_distribution::chi_squared_distribution(unsigned int dof){/*{{{*/
147 k = dof;
148 return;
149 }
150 /*}}}*/
151
152 chi_squared_distribution::~chi_squared_distribution(){}
153
154 double chi_squared_distribution::generator(rnd::linear_congruential_engine random_engine){/*{{{*/
155
156 rnd::normal_distribution distribution;
157
158 double rand = 0;
159
160 for(int i=0;i<k;i++)
161 rand = rand + pow(distribution.generator(random_engine),2);
162
163 return rand;
164
165 }
166 /*}}}*/
167
168
169 /* Exponential distribution */
170
171 exponential_distribution::exponential_distribution(){/*{{{*/
172 lambda = 1.0;
173 return;
174 }
175 /*}}}*/
176
177 exponential_distribution::exponential_distribution(double scale){/*{{{*/
178 lambda = scale;
179 return;
180 }
181 /*}}}*/
182
183 exponential_distribution::~exponential_distribution(){}
184
185 double exponential_distribution::generator(rnd::linear_congruential_engine random_engine){/*{{{*/
186
187 rnd::uniform_distribution distribution;
188
189 return -1.0/lambda*log(1.0-distribution.generator(random_engine));
190
191 }
192 /*}}}*/
193
194 /* Student-t distribution */
195
196 student_t_distribution::student_t_distribution(){/*{{{*/
197 k = 1;
198 return;
199 }
200 /*}}}*/
201
202 student_t_distribution::student_t_distribution(unsigned int dof){/*{{{*/
203 k = dof;
204 return;
205 }
206 /*}}}*/
207
208 student_t_distribution::~student_t_distribution(){}
209
210 double student_t_distribution::generator(rnd::linear_congruential_engine random_engine){/*{{{*/
211
212 rnd::normal_distribution normal_distribution;
213 rnd::chi_squared_distribution chi_squared_distribution(k);
214
215 return normal_distribution.generator(random_engine)/sqrt(chi_squared_distribution.generator(random_engine)/k);
216
217 }
218 /*}}}*/
219
220}
Note: See TracBrowser for help on using the repository browser.