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

Last change on this file since 26744 was 26656, checked in by vverjans, 3 years ago

CHG: Fix memory leak issues from randomgenerator

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