FastJet 3.4.1
BasicRandom.hh
1// Simple random number generator class taken from nlojet++.
2// $Id$
3//
4// Copyright (C) 2002 Zoltan Nagy
5//
6// This program is free software; you can redistribute it and/or modify
7// it under the terms of the GNU General Public License as published by
8// the Free Software Foundation; either version 2 of the License, or
9// (at your option) any later version.
10//
11// This program is distributed in the hope that it will be useful,
12// but WITHOUT ANY WARRANTY; without even the implied warranty of
13// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14// GNU General Public License for more details.
15//
16// You should have received a copy of the GNU General Public License
17// along with this program; if not, write to the Free Software
18// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
19//
20// Changes compared to the original version
21// 2006-08: Some doxygen-style comments added by Gavin Salam
22// 2017-02: The operator() (size_type, pointer, std::vector<int> &);
23// members have been added to implement thread-safe access to the
24// generators
25//
26
27#ifndef __FASTJET_BASICRANDOM_HH__
28#define __FASTJET_BASICRANDOM_HH__ 1
29
30// Standard includes
31#include <iostream>
32#include <vector>
33#include <cassert>
34#include "fastjet/internal/base.hh"
35
36#include "fastjet/config.h"
37#ifdef FASTJET_HAVE_LIMITED_THREAD_SAFETY
38#include <mutex>
39#endif
40
41
42FASTJET_BEGIN_NAMESPACE // defined in fastjet/internal/base.hh
43
44/// \if internal_doc
45/// @ingroup internal
46/// \class BasicRandom
47/// Base class for random number generator of a generic value type
48/// \endif
49template<typename _Tp> class BasicRandom {
50public:
51 typedef _Tp value_type;
52 typedef unsigned int size_type;
53 typedef value_type* pointer;
54
55 // give pseudo random numbers
56 value_type operator() ();
57 void operator() (size_type, pointer);
58
59 // (re)initialize the random number generator
60 void randomize(void *);
61
62 // minimum and maximum values
63 static value_type min();
64 static value_type max();
65
66 // print the informations about the generator to the stream
67 void print_info(std::ostream& __os = std::cout);
68};
69
70// default random generator
71int __default_random_generator(int *__iseed);
72
73
74// specializations
75
76/// \if internal_doc
77/// @ingroup internal
78/// template specialization (int) for the BasicRandom template class.
79/// \endif
80template<>
81class BasicRandom<int>
82{
83public:
84 typedef int value_type;
85 typedef unsigned int size_type;
86 typedef value_type* pointer;
87
88 // constructors
89 explicit BasicRandom(int __s1 = 12345, int __s2 = 67890) {
90 _M_iseed[0] = __s1;
91 _M_iseed[1] = __s2;
92 }
93
94 // give pseudo random numbers
95 value_type operator() () {
96 return __default_random_generator(_M_iseed);
97 }
98
99 void operator() (size_type __n, pointer __res) {
100 for(size_type __i = 0; __i < __n; __i++)
101 __res[__i] = __default_random_generator(_M_iseed);
102 }
103
104 /// given a pointer __res to the beginning of an array, fill that array
105 /// with __n random numbers
106 ///
107 /// This now acquired an extra argument which allows to retreive the
108 /// set of seeds used for this generation.
109 void operator() (size_type __n, pointer __res, std::vector<int> & __iseed) {
110 // if we have (limited) thread safety, lock things
111#ifdef FASTJET_HAVE_LIMITED_THREAD_SAFETY
112 // is the lock here really necessary or would a spinlock do better?
113 std::lock_guard<std::mutex> guard(_multiple_number_generation_mutex);
114#endif
115 // get the seeds
116 get_status(__iseed);
117
118 // get the numbers
119 for(size_type __i = 0; __i < __n; __i++)
120 __res[__i] = __default_random_generator(_M_iseed);
121 }
122
123 // (re)initialize the random number generator
124 void randomize(void *__iseed) {
125 int *__new_seed = (int*) __iseed;
126 _M_iseed[0] = __new_seed[0];
127 _M_iseed[1] = __new_seed[1];
128 }
129
130 void set_status(const std::vector<int> & __iseed) {
131 assert(__iseed.size() >= 2);
132 _M_iseed[0] = __iseed[0];
133 _M_iseed[1] = __iseed[1];
134 }
135
136 void get_status(std::vector<int> & __iseed) {
137 __iseed.resize(2);
138 __iseed[0] = _M_iseed[0];
139 __iseed[1] = _M_iseed[1];
140 }
141
142 // minimum and maximum values
143 inline static value_type min() { return 0;}
144 inline static value_type max() { return 2147483647;}
145
146 // print the informations about the generator to the stream
147 void print_info(std::ostream& __os = std::cout) {
148 __os<<"BasicRandom<int> : "<<_M_iseed[0]<<", "<<_M_iseed[1]<<std::endl;
149 }
150
151private:
152 int _M_iseed[2];
153#ifdef FASTJET_HAVE_LIMITED_THREAD_SAFETY
154 static std::mutex _multiple_number_generation_mutex;
155#endif
156};
157
158
159/// \if internal_doc
160/// @ingroup internal
161/// template specialization (double) for the BasicRandom template class.
162/// \endif
163template<> class BasicRandom<double> {
164public:
165 typedef double value_type;
166 typedef unsigned int size_type;
167 typedef value_type* pointer;
168
169 /// constructor that takes two integers to specify the seed
170 explicit BasicRandom(int __s1 = 12345, int __s2 = 67890) {
171 _M_iseed[0] = __s1;
172 _M_iseed[1] = __s2;
173 }
174
175 /// return a single pseudorandom double number, in the range 0.0 to 1.0
176 /// (not sure whether this range is open or closed)
177 value_type operator() () {
178 return 4.6566128752457969241e-10*__default_random_generator(_M_iseed);
179 }
180
181 /// given a pointer __res to the beginning of an array, fill that array
182 /// with __n random numbers
183 void operator() (size_type __n, pointer __res) {
184 for(size_type __i = 0; __i < __n; __i++)
185 __res[__i] = this -> operator()();
186 }
187
188 /// given a pointer __res to the beginning of an array, fill that array
189 /// with __n random numbers
190 ///
191 /// This now acquired an extra argument which allows to retreive the
192 /// set of seeds used for this generation.
193 void operator() (size_type __n, pointer __res, std::vector<int> & __iseed) {
194 // if we have (limited) thread safety, lock things
195#ifdef FASTJET_HAVE_LIMITED_THREAD_SAFETY
196 // is the lock here really necessary or would a spinlock do better?
197 std::lock_guard<std::mutex> guard(_multiple_number_generation_mutex);
198#endif
199 // get the seeds
200 get_status(__iseed);
201
202 // get the numbers
203 for(size_type __i = 0; __i < __n; __i++)
204 __res[__i] = this -> operator()();
205 }
206
207 /// (re)initialize the random number generator from an array of seeds
208 void randomize(void *__iseed) {
209 int *__new_seed = (int*) __iseed;
210 _M_iseed[0] = __new_seed[0];
211 _M_iseed[1] = __new_seed[1];
212 }
213
214 void set_status(const std::vector<int> & __iseed) {
215 assert(__iseed.size() >= 2);
216 _M_iseed[0] = __iseed[0];
217 _M_iseed[1] = __iseed[1];
218 }
219
220 void get_status(std::vector<int> & __iseed) {
221 __iseed.resize(2);
222 __iseed[0] = _M_iseed[0];
223 __iseed[1] = _M_iseed[1];
224 }
225
226 /// minimum value returned by the generator
227 inline static value_type min() { return 0.0;}
228 /// maximum value returned by the generator
229 inline static value_type max() { return 1.0;}
230
231 /// print information about the generator to the stream
232 void print_info(std::ostream& __os = std::cout) {
233 __os<<"BasicRandom<double> : "<<_M_iseed[0]<<", "<<_M_iseed[1]<<std::endl;
234 }
235
236private:
237 int _M_iseed[2];
238#ifdef FASTJET_HAVE_LIMITED_THREAD_SAFETY
239 static std::mutex _multiple_number_generation_mutex;
240#endif
241};
242
243// globally defined random number generator
244extern BasicRandom<int> _G_random_int;
245extern BasicRandom<double> _G_random_double;
246
247
248FASTJET_END_NAMESPACE
249
250#endif // __FASTJET_BASICRANDOM_HH__
251
static value_type min()
minimum value returned by the generator
Definition: BasicRandom.hh:227
void randomize(void *__iseed)
(re)initialize the random number generator from an array of seeds
Definition: BasicRandom.hh:208
static value_type max()
maximum value returned by the generator
Definition: BasicRandom.hh:229
BasicRandom(int __s1=12345, int __s2=67890)
constructor that takes two integers to specify the seed
Definition: BasicRandom.hh:170
void print_info(std::ostream &__os=std::cout)
print information about the generator to the stream
Definition: BasicRandom.hh:232