SIMLIB/C++  3.07
random2.cc
Go to the documentation of this file.
1 /////////////////////////////////////////////////////////////////////////////
2 //! \file random2.cc Random number generators - transformations
3 //
4 // Copyright (c) 1991-2004 Petr Peringer
5 //
6 // This library is licensed under GNU Library GPL. See the file COPYING.
7 //
8 
9 //
10 // random number generators (dependent on Random())
11 //
12 
13 ////////////////////////////////////////////////////////////////////////////
14 // interface
15 //
16 
17 #include "simlib.h"
18 #include "internal.h"
19 
20 #include <cmath> // exp() floor() log() pow() sqrt()
21 
22 
23 ////////////////////////////////////////////////////////////////////////////
24 // implementation
25 //
26 
27 
28 namespace simlib3 {
29 
31 
32 ////////////////////////////////////////////////////////////////////////////
33 // _gam
34 //
35 static double _gam(double AK)
36 {
37  int K,i;
38  double FK,PROD,DG,G,W;
39 
40  FK = K = (int) floor(AK);
41  G = 0.0;
42  if (K>0)
43  {
44  PROD = 1.0;
45  for(i=1; i<=K; i++) PROD *= Random();
46  G = -log(PROD);
47  }
48 
49  DG = AK-FK;
50  if (DG <= 0.015) return (G);
51  if (DG >=0.935)
52  W=1.0;
53  else
54  {
55  double A,B,X,Y;
56  A = 1.0/DG;
57  B = 1.0/(1.0-DG);
58  do{
59  X = pow(Random(),A);
60  Y = pow(Random(),B+X);
61  }while (Y>1.0);
62  W = X/Y;
63  }
64  G += W*(-log(Random()));
65  return (G);
66 }
67 
68 ////////////////////////////////////////////////////////////////////////////
69 // Uniform - uniform random number generator
70 //
71 double Uniform(double l, double h)
72 {
73  if( l >= h ) SIMLIB_error(BadUniformParam);
74  return(l+(h-l)*Random());
75 }
76 
77 ////////////////////////////////////////////////////////////////////////////
78 // Normal(mi,sigma)
79 // mi = mean value
80 // sigma = std deviation? (smerodatna odchylka) ###
81 //
82 double Normal(double mi, double sigma)
83 {
84  int i;
85  double SUM = 0.0;
86  for (i=0; i<12; i++) SUM += Random();
87  return (SUM-6.0)*sigma + mi;
88 }
89 
90 ////////////////////////////////////////////////////////////////////////////
91 // Weibul
92 //
93 // TODO: check
94 double Weibul(double lambda, double alfa)
95 {
96  double R,W;
97 
98  if (lambda<=0.0 || alfa<=1.0) SIMLIB_error(WeibullError);
99 
100  while ((R=Random()) == 0 || R == 1) { /*empty*/ }
101  W= pow (-1.0/lambda*log(1.0-R), 1.0/alfa);
102  return (W);
103 }
104 
105 ////////////////////////////////////////////////////////////////////////////
106 // Erlang
107 //
108 // TODO: check
109 double Erlang(double alfa, int beta)
110 {
111  double ER = 1.0;
112  int i;
113  if (beta<1) SIMLIB_error(ErlangError);
114  for (i=0; i<beta; i++) ER *= Random();
115  return -alfa*log(ER);
116 }
117 
118 ////////////////////////////////////////////////////////////////////////////
119 // NegBin
120 //
121 int NegBin(double q, int k)
122 {
123  double IS,XLOGQ,R;
124  int i;
125 
126  if (k<=0 || q<=0) SIMLIB_error(NegBinError);
127 
128  IS = 0;
129  XLOGQ = log(q);
130  for (i=1; i<=k; i++)
131  {
132  while ((R=Random()) == 0) { /*empty*/ }
133  IS += log(R)/XLOGQ;
134  }
135  return int(IS);
136 }
137 
138 ////////////////////////////////////////////////////////////////////////////
139 // Gamma
140 //
141 double Gamma(double alfa, double beta)
142 {
143  double G;
144 
145  G = _gam(alfa)*beta;
146  return (G);
147 }
148 
149 ////////////////////////////////////////////////////////////////////////////
150 // Exponential(mv)
151 //
152 double Exponential(double mv)
153 {
154  double exp = -mv * std::log(1.0-Random());
155 // _Print("Exponential(%g),%g = %g\n", mv, r, exp);
156  return exp;
157 }
158 
159 
160 
161 ////////////////////////////////////////////////////////////////////////////
162 //
163 //
164 int NegBinM(double p, int m)
165 {
166  int i,ix;
167 
168  if (m<=0) SIMLIB_error(NegBinMError1);
169  if (p<0 || p>1) SIMLIB_error(NegBinMError2);
170  ix = i = 0;
171  do{
172  if (Random() <= p) ix++;
173  i++;
174  }while (i <= m);
175  return (ix);
176 }
177 
178 ////////////////////////////////////////////////////////////////////////////
179 // Beta
180 //
181 double Beta(double th, double fi, double min, double max)
182 {
183  double X;
184  X = _gam(th);
185  X = X/(X+_gam(fi));
186  X = X*(max-min)+min;
187  return (X);
188 }
189 
190 ////////////////////////////////////////////////////////////////////////////
191 // Triag(mod,min,max)
192 //
193 double Triag(double mod, double min, double max)
194 {
195  double RN,BMA,CMA,TR;
196 
197  RN=Random();
198  BMA=mod-min;
199  CMA=max-min;
200  if (RN<BMA/CMA)
201  TR=min+sqrt(BMA*CMA*RN);
202  else
203  TR=max-sqrt(CMA*(1.0-RN)*(max-mod));
204  return (TR);
205 }
206 
207 ////////////////////////////////////////////////////////////////////////////
208 // Log
209 //
210 double Logar(double mi, double delta)
211 {
212  double VA = Normal(mi, delta);
213  return exp(VA);
214 }
215 
216 ////////////////////////////////////////////////////////////////////////////
217 // Rayle(delta)
218 //
219 double Rayle(double delta)
220 {
221  double R;
222  while ((R=Random()) == 0) { /*empty*/ }
223  return delta * sqrt(-log(R));
224 }
225 
226 ////////////////////////////////////////////////////////////////////////////
227 // Poisson(double lambda)
228 //
229 int Poisson(double lambda)
230 {
231  double Y,X;
232  int PSSN = 0;
233  if (lambda<=0) SIMLIB_error(PoissonError);
234  if (lambda <= 9.0)
235  {
236  Y=exp(-lambda);
237  X=1.0;
238  do{
239  X *= Random();
240  if (X<Y) break;
241  PSSN++;
242  }while(1);
243  }
244  else
245  {
246  double sl=sqrt(lambda);
247  do
248  PSSN = (int) (Normal(lambda, sl) + 0.5); /* round ???### */
249  while (PSSN<0);
250  }
251  return PSSN;
252 }
253 
254 ////////////////////////////////////////////////////////////////////////////
255 // Geom(q)
256 //
257 int Geom(double q)
258 {
259  double X,R;
260 
261  if (q<=0) SIMLIB_error(GeomError);
262  while ((R=Random()) == 0) { /*empty*/ }
263  X = log(R)/log(q);
264  return int(X);
265 }
266 
267 ////////////////////////////////////////////////////////////////////////////
268 // HyperGeometric
269 //
270 int HyperGeom(double p, int n, int m)
271 {
272  int IX,i;
273  if (m <= 0) SIMLIB_error(HyperGeomError1);
274  if (p<0 || p>1) SIMLIB_error(HyperGeomError2);
275  IX=0;
276  for (i=1; i<=n; i++)
277  {
278  if (Random() > p)
279  p =m*p/(m-1);
280  else
281  {
282  IX++;
283  p=(m*p-1.0)/(m-1);
284  }
285  m--;
286  }
287  return (IX);
288 }
289 
290 ////////////////////////////////////////////////////////////////////////////
291 // Binom(n,theta)
292 // n = # of experiments (pocet pokusu)
293 // theta = probability
294 //
295 /*
296 int Binom(unsigned n, double theta)
297 {
298  int BNM;
299  double SUM,R,TT,x;
300  if (theta<0 || theta>1) SIMLIB_error(BinomError);
301  SUM = R = pow(1-theta,n);
302  TT = theta/(1-theta);
303  BNM = 0;
304  x = Random();
305  while(x-SUM > 0)
306  {
307  R *= (n-BNM)/(BNM+1)*TT;
308  SUM += R;
309  BNM++;
310  }
311  return (BNM);
312 }
313 */
314 
315 } // end
316 
static double _gam(double AK)
Definition: random2.cc:35
double Random()
base uniform generator (range 0-0.999999...) the default implementation is simple LCG 32bit ...
Definition: random1.cc:95
double Rayle(double delta)
Definition: random2.cc:219
void SIMLIB_error(const enum _ErrEnum N)
print error message and abort program
Definition: error.cc:38
double Exponential(double mv)
Exponential distribution generator.
Definition: random2.cc:152
int Poisson(double lambda)
Poisson distribution generator.
Definition: random2.cc:229
int NegBin(double q, int k)
Definition: random2.cc:121
double Weibul(double lambda, double alfa)
Weibul distribution generator.
Definition: random2.cc:94
double Triag(double mod, double min, double max)
Definition: random2.cc:193
double Beta(double th, double fi, double min, double max)
Beta distribution generator.
Definition: random2.cc:181
Implementation of class CalendarList interface is static - using global functions in SQS namespace...
Definition: algloop.cc:32
double max(double a, double b)
Definition: internal.h:286
double Normal(double mi, double sigma)
Gauss distribution generator.
Definition: random2.cc:82
double min(double a, double b)
Definition: internal.h:285
double Gamma(double alfa, double beta)
Gamma distribution generator.
Definition: random2.cc:141
Internal header file for SIMLIB/C++.
int HyperGeom(double p, int n, int m)
Definition: random2.cc:270
double Erlang(double alfa, int beta)
Erlang distribution generator.
Definition: random2.cc:109
Main SIMLIB/C++ interface.
double Uniform(double l, double h)
Uniform distribution generator.
Definition: random2.cc:71
SIMLIB_IMPLEMENTATION
Definition: algloop.cc:34
int NegBinM(double p, int m)
Definition: random2.cc:164
double Logar(double mi, double delta)
Definition: random2.cc:210
int Geom(double q)
Definition: random2.cc:257