Logo ROOT  
Reference Guide
 
Loading...
Searching...
No Matches
GSLRndmEngines.cxx
Go to the documentation of this file.
1// @(#)root/mathmore:$Id$
2// Authors: L. Moneta, A. Zsenei 08/2005
3
4 /**********************************************************************
5 * *
6 * Copyright (c) 2004 ROOT Foundation, CERN/PH-SFT *
7 * *
8 * This library is free software; you can redistribute it and/or *
9 * modify it under the terms of the GNU General Public License *
10 * as published by the Free Software Foundation; either version 2 *
11 * of the License, or (at your option) any later version. *
12 * *
13 * This library is distributed in the hope that it will be useful, *
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of *
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU *
16 * General Public License for more details. *
17 * *
18 * You should have received a copy of the GNU General Public License *
19 * along with this library (see file COPYING); if not, write *
20 * to the Free Software Foundation, Inc., 59 Temple Place, Suite *
21 * 330, Boston, MA 02111-1307 USA, or contact the author. *
22 * *
23 **********************************************************************/
24
25// Header file for class GSLRandom
26//
27// Created by: moneta at Sun Nov 21 16:26:03 2004
28//
29// Last update: Sun Nov 21 16:26:03 2004
30//
31
32
33
34// need to be included later
35#include <ctime>
36#include <cassert>
37
38#include "gsl/gsl_linalg.h"
39#include "gsl/gsl_matrix.h"
40#include "gsl/gsl_rng.h"
41#include "gsl/gsl_randist.h"
42#include "gsl/gsl_vector.h"
43#include "gsl/gsl_version.h"
44
45#include "Math/GSLRndmEngines.h"
46#include "GSLRngWrapper.h"
47// for wrapping in GSL ROOT engines
48#include "GSLRngROOTWrapper.h"
49
50extern double gsl_ran_gaussian_acr( const gsl_rng * r, const double sigma);
51
52// gsl_multivarate_gaussian was added in GSL 2.2
53// For older GSL versions (e.g. Ubuntu 16.04 comes with GSL 2.1) we can add it here by hand
54// from: http://git.savannah.gnu.org/cgit/gsl.git/tree/randist/mvgauss.c?h=release-2-6&id=8f0165f5cb2ae02e386cd33ff10e47ffb46ea7da
55#if (GSL_MAJOR_VERSION == 1) || ((GSL_MAJOR_VERSION == 2) && (GSL_MINOR_VERSION < 2))
56#include <gsl/gsl_blas.h>
57extern int
58gsl_ran_multivariate_gaussian(const gsl_rng *r, const gsl_vector *mu, const gsl_matrix *L, gsl_vector *result)
59{
60 const size_t M = L->size1;
61 const size_t N = L->size2;
62
63 if (M != N) {
64 GSL_ERROR("requires square matrix", GSL_ENOTSQR);
65 } else if (mu->size != M) {
66 GSL_ERROR("incompatible dimension of mean vector with variance-covariance matrix", GSL_EBADLEN);
67 } else if (result->size != M) {
68 GSL_ERROR("incompatible dimension of result vector", GSL_EBADLEN);
69 } else {
70 size_t i;
71
72 for (i = 0; i < M; ++i)
73 gsl_vector_set(result, i, gsl_ran_ugaussian(r));
74
75 gsl_blas_dtrmv(CblasLower, CblasNoTrans, CblasNonUnit, L, result);
76 gsl_vector_add(result, mu);
77
78 return GSL_SUCCESS;
79 }
80}
81#endif
82
83namespace ROOT {
84namespace Math {
85
86
87 // default constructor (need to call set type later)
89 fRng(nullptr),
90 fCurTime(0)
91 { }
92
93 // constructor from external rng
94 // internal generator will be managed or not depending on
95 // how the GSLRngWrapper is created
97 fRng(new GSLRngWrapper(*rng) ),
98 fCurTime(0)
99 {}
100
101 // copy constructor
103 fRng(new GSLRngWrapper(*eng.fRng) ),
104 fCurTime(0)
105 {}
106
108 // destructor : call terminate if not yet called
109 if (fRng) Terminate();
110 }
111
112 // assignment operator
114 if (this == &eng) return *this;
115 if (fRng)
116 *fRng = *eng.fRng;
117 else
118 fRng = new GSLRngWrapper(*eng.fRng);
119 fCurTime = eng.fCurTime;
120 return *this;
121 }
122
123
125 // initialize the generator by allocating the GSL object
126 // if type was not passed create with default generator
127 if (!fRng) fRng = new GSLRngWrapper();
128 fRng->Allocate();
129 }
130
132 // terminate the generator by freeing the GSL object
133 if (!fRng) return;
134 fRng->Free();
135 delete fRng;
136 fRng = nullptr;
137 }
138
139
141 // generate random between 0 and 1.
142 // 0 is excluded
143 return gsl_rng_uniform_pos(fRng->Rng() );
144 }
145
146
147 unsigned long GSLRandomEngine::RndmInt(unsigned long max) const {
148 // generate a random integer number between 0 and MAX
149 return gsl_rng_uniform_int( fRng->Rng(), max );
150 }
151
152 unsigned long GSLRandomEngine::MinInt() const {
153 // return minimum integer value used in RndmInt
154 return gsl_rng_min( fRng->Rng() );
155 }
156
157 unsigned long GSLRandomEngine::MaxInt() const {
158 // return maximum integr value used in RndmInt
159 return gsl_rng_max( fRng->Rng() );
160 }
161
162 void GSLRandomEngine::RandomArray(double * begin, double * end ) const {
163 // generate array of randoms between 0 and 1. 0 is excluded
164 // specialization for double * (to be faster)
165 for ( double * itr = begin; itr != end; ++itr ) {
166 *itr = gsl_rng_uniform_pos(fRng->Rng() );
167 }
168 }
169
170 void GSLRandomEngine::SetSeed(unsigned int seed) const {
171 // set the seed, if = 0then the seed is set randomly using an std::rand()
172 // seeded with the current time. Be carefuk in case the current time is
173 // the same in consecutive calls
174 if (seed == 0) {
175 // use like in root (use time)
176 time_t curtime;
177 time(&curtime);
178 unsigned int ct = static_cast<unsigned int>(curtime);
179 if (ct != fCurTime) {
180 fCurTime = ct;
181 // set the seed for rand
182 srand(ct);
183 }
184 seed = rand();
185 }
186
187 assert(fRng);
188 gsl_rng_set(fRng->Rng(), seed );
189 }
190
191 std::string GSLRandomEngine::Name() const {
192 //////////////////////////////////////////////////////////////////////////
193
194 assert ( fRng != nullptr);
195 assert ( fRng->Rng() != nullptr );
196 return std::string( gsl_rng_name( fRng->Rng() ) );
197 }
198
199 unsigned int GSLRandomEngine::Size() const {
200 //////////////////////////////////////////////////////////////////////////
201
202 assert (fRng != nullptr);
203 return gsl_rng_size( fRng->Rng() );
204 }
205
206
207 // Random distributions
208
210 {
211 // Gaussian distribution. Use fast ziggurat algorithm implemented since GSL 1.8
212 return gsl_ran_gaussian_ziggurat( fRng->Rng(), sigma);
213 }
214
215 double GSLRandomEngine::Gaussian(double sigma) const
216 {
217 // Gaussian distribution. Use default Box-Muller method
218 return gsl_ran_gaussian( fRng->Rng(), sigma);
219 }
220
222 {
223 // Gaussian distribution. Use ratio method
224 return gsl_ran_gaussian_ratio_method( fRng->Rng(), sigma);
225 }
226
227
228 double GSLRandomEngine::GaussianTail(double a , double sigma) const
229 {
230 // Gaussian Tail distribution: eeturn values larger than a distributed
231 // according to the gaussian
232 return gsl_ran_gaussian_tail( fRng->Rng(), a, sigma);
233 }
234
235 void GSLRandomEngine::Gaussian2D(double sigmaX, double sigmaY, double rho, double &x, double &y) const
236 {
237 // Gaussian Bivariate distribution, with correlation coefficient rho
238 gsl_ran_bivariate_gaussian( fRng->Rng(), sigmaX, sigmaY, rho, &x, &y);
239 }
240
241 void GSLRandomEngine::GaussianND(size_t dim, const double *pars, const double *covmat, double *genpars, double * ldec) const
242 {
243 // Gaussian Multivariate distribution
244 // assume passed arrays are of correct dimensions
245 // use gsl_matrix_view to avoid copying the data and allocate the arrays
246 // covmat will return
247
248 bool allocateL = false;
249 if (!ldec) {
250 ldec = new double[dim*dim];
251 allocateL = true;
252 }
253
254 gsl_matrix_view L = gsl_matrix_view_array(ldec, dim, dim);
255 gsl_vector_const_view mu = gsl_vector_const_view_array(pars, dim);
256 gsl_vector_view x = gsl_vector_view_array(genpars, dim);
257
258 if (covmat) {
259 gsl_matrix_const_view A = gsl_matrix_const_view_array(covmat, dim, dim);
260 gsl_matrix_memcpy(&L.matrix, &A.matrix);
261#if ((GSL_MAJOR_VERSION >= 2) && (GSL_MINOR_VERSION > 2))
262 gsl_linalg_cholesky_decomp1(&L.matrix);
263#else
264 gsl_linalg_cholesky_decomp(&L.matrix);
265#endif
266 }
267 // if covMat is not provide we use directly L
268 gsl_ran_multivariate_gaussian(fRng->Rng(), &mu.vector, &L.matrix, &x.vector);
269 if (allocateL) {
270 delete [] ldec;
271 ldec = nullptr;
272 }
273 }
274
275 double GSLRandomEngine::Exponential(double mu) const
276 {
277 // Exponential distribution
278 return gsl_ran_exponential( fRng->Rng(), mu);
279 }
280
281 double GSLRandomEngine::Cauchy(double a) const
282 {
283 // Cauchy distribution
284 return gsl_ran_cauchy( fRng->Rng(), a);
285 }
286
288 {
289 // Landau distribution
290 return gsl_ran_landau( fRng->Rng());
291 }
292
293 double GSLRandomEngine::Beta(double a, double b) const
294 {
295 // Beta distribution
296 return gsl_ran_beta( fRng->Rng(), a, b);
297 }
298
299 double GSLRandomEngine::Gamma(double a, double b) const
300 {
301 // Gamma distribution
302 return gsl_ran_gamma( fRng->Rng(), a, b);
303 }
304
305 double GSLRandomEngine::LogNormal(double zeta, double sigma) const
306 {
307 // Log normal distribution
308 return gsl_ran_lognormal( fRng->Rng(), zeta, sigma);
309 }
310
311 double GSLRandomEngine::ChiSquare(double nu) const
312 {
313 // Chi square distribution
314 return gsl_ran_chisq( fRng->Rng(), nu);
315 }
316
317
318 double GSLRandomEngine::FDist(double nu1, double nu2) const
319 {
320 // F distribution
321 return gsl_ran_fdist( fRng->Rng(), nu1, nu2);
322 }
323
324 double GSLRandomEngine::tDist(double nu) const
325 {
326 // t distribution
327 return gsl_ran_tdist( fRng->Rng(), nu);
328 }
329
330 double GSLRandomEngine::Rayleigh(double sigma) const
331 {
332 // Rayleigh distribution
333 return gsl_ran_rayleigh( fRng->Rng(), sigma);
334 }
335
336 double GSLRandomEngine::Logistic(double a) const
337 {
338 // Logistic distribution
339 return gsl_ran_logistic( fRng->Rng(), a);
340 }
341
342 double GSLRandomEngine::Pareto(double a, double b) const
343 {
344 // Pareto distribution
345 return gsl_ran_pareto( fRng->Rng(), a, b);
346 }
347
348 void GSLRandomEngine::Dir2D(double &x, double &y) const
349 {
350 // generate random numbers in a 2D circle of radious 1
351 gsl_ran_dir_2d( fRng->Rng(), &x, &y);
352 }
353
354 void GSLRandomEngine::Dir3D(double &x, double &y, double &z) const
355 {
356 // generate random numbers in a 3D sphere of radious 1
357 gsl_ran_dir_3d( fRng->Rng(), &x, &y, &z);
358 }
359
360 unsigned int GSLRandomEngine::Poisson(double mu) const
361 {
362 // Poisson distribution
363 return gsl_ran_poisson( fRng->Rng(), mu);
364 }
365
366 unsigned int GSLRandomEngine::Binomial(double p, unsigned int n) const
367 {
368 // Binomial distribution
369 return gsl_ran_binomial( fRng->Rng(), p, n);
370 }
371
372 unsigned int GSLRandomEngine::NegativeBinomial(double p, double n) const
373 {
374 // Negative Binomial distribution
375 return gsl_ran_negative_binomial( fRng->Rng(), p, n);
376 }
377
378
379 std::vector<unsigned int> GSLRandomEngine::Multinomial( unsigned int ntot, const std::vector<double> & p ) const
380 {
381 // Multinomial distribution return vector of integers which sum is ntot
382 std::vector<unsigned int> ival( p.size());
383 gsl_ran_multinomial( fRng->Rng(), p.size(), ntot, &p.front(), &ival[0]);
384 return ival;
385 }
386
387
388
389 //----------------------------------------------------
390 // generators
391 //----------------------------------------------------
392
393 /////////////////////////////////////////////////////////////////////////////
394
396 {
397 SetType(new GSLRngWrapper(gsl_rng_mt19937));
398 Initialize();
399 }
400
401
402 // old ranlux - equivalent to TRandom1
404 {
405 SetType(new GSLRngWrapper(gsl_rng_ranlux) );
406 Initialize();
407 }
408
409 // second generation of Ranlux (single precision version - luxury 1)
411 {
412 SetType(new GSLRngWrapper(gsl_rng_ranlxs1) );
413 Initialize();
414 }
415
416 // second generation of Ranlux (single precision version - luxury 2)
418 {
419 SetType(new GSLRngWrapper(gsl_rng_ranlxs2) );
420 Initialize();
421 }
422
423 // double precision version - luxury 1
425 {
426 SetType(new GSLRngWrapper(gsl_rng_ranlxd1) );
427 Initialize();
428 }
429
430 // double precision version - luxury 2
432 {
433 SetType(new GSLRngWrapper(gsl_rng_ranlxd2) );
434 Initialize();
435 }
436
437 /////////////////////////////////////////////////////////////////////////////
438
440 {
441 SetType(new GSLRngWrapper(gsl_rng_taus2) );
442 Initialize();
443 }
444
445 /////////////////////////////////////////////////////////////////////////////
446
448 {
449 SetType(new GSLRngWrapper(gsl_rng_gfsr4) );
450 Initialize();
451 }
452
453 /////////////////////////////////////////////////////////////////////////////
454
456 {
457 SetType(new GSLRngWrapper(gsl_rng_cmrg) );
458 Initialize();
459 }
460
461 /////////////////////////////////////////////////////////////////////////////
462
464 {
465 SetType(new GSLRngWrapper(gsl_rng_mrg) );
466 Initialize();
467 }
468
469
470 /////////////////////////////////////////////////////////////////////////////
471
473 {
474 SetType(new GSLRngWrapper(gsl_rng_rand) );
475 Initialize();
476 }
477
478 /////////////////////////////////////////////////////////////////////////////
479
481 {
482 SetType(new GSLRngWrapper(gsl_rng_ranmar) );
483 Initialize();
484 }
485
486 /////////////////////////////////////////////////////////////////////////////
487
489 {
490 SetType(new GSLRngWrapper(gsl_rng_minstd) );
491 Initialize();
492 }
493
494
495 // for extra engines based on ROOT
497 {
499 Initialize(); // this creates the gsl_rng structure
500 // no real need to call CreateEngine since the underlined MIXMAX engine is created
501 // by calling GSLMixMaxWrapper::Seed(gsl_default_seed) that is called
502 // when gsl_rng is allocated (in Initialize)
504 }
506 // we need to explicitly delete the ROOT wrapper class
508 }
509
510} // namespace Math
511} // namespace ROOT
double gsl_ran_gaussian_acr(const gsl_rng *r, const double sigma)
const gsl_rng_type * gsl_rng_mixmax
#define b(i)
Definition RSha256.hxx:100
#define a(i)
Definition RSha256.hxx:99
#define N
winID h TVirtualViewer3D TVirtualGLPainter p
Option_t Option_t TPoint TPoint const char GetTextMagnitude GetFillStyle GetLineColor GetLineWidth GetMarkerStyle GetTextAlign GetTextColor GetTextSize void char Point_t Rectangle_t WindowAttributes_t Float_t r
Option_t Option_t TPoint TPoint const char GetTextMagnitude GetFillStyle GetLineColor GetLineWidth GetMarkerStyle GetTextAlign GetTextColor GetTextSize void char Point_t Rectangle_t WindowAttributes_t Float_t Float_t Float_t Int_t Int_t UInt_t UInt_t Rectangle_t result
GSLRandomEngine Base class for all GSL random engines, normally user instantiate the derived classes ...
double operator()() const
Generate a random number between ]0,1] 0 is excluded and 1 is included.
void Dir3D(double &x, double &y, double &z) const
generate random numbers in a 3D sphere of radious 1
void SetSeed(unsigned int seed) const
set the random generator seed
void Gaussian2D(double sigmaX, double sigmaY, double rho, double &x, double &y) const
Bivariate Gaussian distribution with correlation.
unsigned int Poisson(double mu) const
Poisson distribution.
double ChiSquare(double nu) const
Chi square distribution.
double FDist(double nu1, double nu2) const
F distribution.
GSLRngWrapper * Engine()
internal method to return the engine Used by class like GSLMCIntegrator to set the engine
double Gamma(double a, double b) const
Gamma distribution.
GSLRandomEngine()
default constructor.
double Exponential(double mu) const
Exponential distribution.
double GaussianTail(double a, double sigma) const
Gaussian Tail distribution.
double Rayleigh(double sigma) const
Rayleigh distribution.
std::vector< unsigned int > Multinomial(unsigned int ntot, const std::vector< double > &p) const
Multinomial distribution.
unsigned long MaxInt() const
return the maximum integer +1 a generator can handle
double Cauchy(double a) const
Cauchy distribution.
double GaussianZig(double sigma) const
Gaussian distribution - Ziggurat method.
unsigned long MinInt() const
return the minimum integer a generator can handle typically this value is 0
double Gaussian(double sigma) const
Gaussian distribution - default method is Box-Muller (polar method)
double Beta(double a, double b) const
Beta distribution.
double Landau() const
Landau distribution.
unsigned int NegativeBinomial(double p, double n) const
Negative Binomial distribution.
void RandomArray(Iterator begin, Iterator end) const
Generate an array of random numbers.
unsigned int Size() const
return the state size of generator
double Pareto(double a, double b) const
Pareto distribution.
double LogNormal(double zeta, double sigma) const
Log Normal distribution.
unsigned int Binomial(double p, unsigned int n) const
Binomial distribution.
void Dir2D(double &x, double &y) const
generate random numbers in a 2D circle of radious 1
void Terminate()
delete pointer to contained rng
void GaussianND(size_t dim, const double *pars, const double *covmat, double *genpars, double *lmat=nullptr) const
Multivariate Gaussian distribution.
std::string Name() const
return name of generator
double GaussianRatio(double sigma) const
Gaussian distribution - Ratio method.
double Logistic(double a) const
Logistic distribution.
unsigned long RndmInt(unsigned long max) const
Generate an integer number between [0,max-1] (including 0 and max-1) if max is larger than available ...
void SetType(GSLRngWrapper *r)
internal method used by the derived class to set the type of generators
void Initialize()
initialize the generator If no rng is present the default one based on Mersenne and Twister is create...
double tDist(double nu) const
t student distribution
GSLRandomEngine & operator=(const GSLRandomEngine &eng)
Assignment operator : make a deep copy of the contained GSL generator.
virtual ~GSLRandomEngine()
call Terminate()
GSLRngWrapper class to wrap gsl_rng structure.
const Double_t sigma
Double_t y[n]
Definition legend1.C:17
Double_t x[n]
Definition legend1.C:17
const Int_t n
Definition legend1.C:16
Namespace for new Math classes and functions.
This file contains a specialised ROOT message handler to test for diagnostic in unit tests.
static void FreeEngine(gsl_rng *r)
static void CreateEngine(gsl_rng *r)