StRoot  1
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Groups Pages
RandFlat.h
1 /***************************************************************************
2  *
3  * $Id: RandFlat.h,v 1.2 1999/09/02 11:35:25 ullrich Exp $
4  *
5  * Author: Gabriele Cosmo - Created: 5th September 1995
6  * modified for SCL bl
7  ***************************************************************************
8  *
9  * Description:
10  * RandFlat.h,v 1.4 1997/08/12 00:38:41
11  * -----------------------------------------------------------------------
12  * HEP Random
13  * --- RandFlat ---
14  * class header file
15  * -----------------------------------------------------------------------
16  * This file is part of Geant4 (simulation toolkit for HEP).
17  *
18  * Class defining methods for shooting flat random numbers, double or
19  * integers.
20  * It provides also static methods to fill with double flat values arrays
21  * of specified size.
22  * Default boundaries ]0.1[ for operator()().
23  *
24  ***************************************************************************
25  *
26  * $Log: RandFlat.h,v $
27  * Revision 1.2 1999/09/02 11:35:25 ullrich
28  * Changed order of data member to avoid warnings on Linux
29  *
30  * Revision 1.1 1999/01/30 03:59:00 fisyak
31  * Root Version of StarClassLibrary
32  *
33  * Revision 1.1 1999/01/23 00:27:37 ullrich
34  * Initial Revision
35  *
36  **************************************************************************/
37 #ifndef RandFlat_h
38 #define RandFlat_h 1
39 
40 #include "Random.h"
41 
42 class RandFlat : public HepRandom {
43 
44 public:
45 
46  inline RandFlat ( HepRandomEngine& anEngine );
47  inline RandFlat ( HepRandomEngine* anEngine );
48  // These constructors should be used to instantiate a RandFlat
49  // distribution object defining a local engine for it.
50  // The static generator will be skeeped using the non-static methods
51  // defined below.
52  // If the engine is passed by pointer the corresponding engine object
53  // will be deleted by the RandFlat destructor.
54  // If the engine is passed by reference the corresponding engine object
55  // will not be deleted by the RandFlat destructor.
56 
57  virtual ~RandFlat();
58  // Destructor
59 
60  // Static methods to shoot random values using the static generator
61 
62  static inline HepDouble shoot();
63  static inline HepDouble shoot( HepDouble width );
64  static inline HepDouble shoot( HepDouble a, HepDouble b );
65 
66  static inline long shootInt( long n );
67  static inline long shootInt( long m, long n );
68 
69  static inline HepInt shootBit();
70 
71  static inline void shootArray ( const HepInt size, HepDouble* vect );
72 #ifndef ST_NO_TEMPLATE_DEF_ARGS
73  static inline void shootArray (vector<HepDouble>&);
74 #else
75  static inline void shootArray (vector<HepDouble, allocator<HepDouble> >&);
76 #endif
77  static void shootArray ( const HepInt size, HepDouble* vect,
78  HepDouble lx, HepDouble dx );
79 #ifndef ST_NO_TEMPLATE_DEF_ARGS
80  static void shootArray ( vector<HepDouble>&, HepDouble, HepDouble );
81 #else
82  static void shootArray ( vector<HepDouble, allocator<HepDouble> >&,
83  HepDouble, HepDouble );
84 #endif
85  // Static methods to shoot random values using a given engine
86  // by-passing the static generator.
87 
88  static inline HepDouble shoot ( HepRandomEngine* anEngine );
89 
90  static inline HepDouble shoot( HepRandomEngine* anEngine, HepDouble width );
91 
92  static inline HepDouble shoot( HepRandomEngine* anEngine,
93  HepDouble a, HepDouble b );
94  static inline long shootInt( HepRandomEngine* anEngine, long n );
95 
96  static inline long shootInt( HepRandomEngine* anEngine, long m, long n );
97 
98  static inline HepInt shootBit( HepRandomEngine* );
99 
100  static inline void shootArray ( HepRandomEngine* anEngine,
101  const HepInt size, HepDouble* vect );
102 #ifndef ST_NO_TEMPLATE_DEF_ARGS
103  static inline void shootArray ( HepRandomEngine*, vector<HepDouble>& );
104 #else
105  static inline void shootArray ( HepRandomEngine*, vector<HepDouble,allocator<HepDouble> >& );
106 #endif
107 
108  static void shootArray ( HepRandomEngine* anEngine,
109  const HepInt size, HepDouble* vect,
110  HepDouble lx, HepDouble dx );
111 #ifndef ST_NO_TEMPLATE_DEF_ARGS
112  static void shootArray ( HepRandomEngine*,
113  vector<HepDouble>&,
114  HepDouble, HepDouble );
115 #else
116 static void shootArray ( HepRandomEngine*,
117  vector<HepDouble,allocator<HepDouble> >&,
118  HepDouble, HepDouble );
119 #endif
120  // Methods using the localEngine to shoot random values, by-passing
121  // the static generator.
122 
123  inline HepDouble fire();
124 
125  inline HepDouble fire( HepDouble width );
126 
127  inline HepDouble fire( HepDouble a, HepDouble b );
128 
129  inline long fireInt( long n );
130 
131  inline long fireInt( long m, long n );
132 
133  inline HepInt fireBit();
134 
135  inline void fireArray (const HepInt size, HepDouble* vect);
136 #ifndef ST_NO_TEMPLATE_DEF_ARGS
137  inline void fireArray (vector<HepDouble>&);
138 #else
139  inline void fireArray (vector<HepDouble,allocator<HepDouble> >&);
140 #endif
141 
142  void fireArray (const HepInt size, HepDouble* vect,
143  HepDouble lx, HepDouble dx);
144 #ifndef ST_NO_TEMPLATE_DEF_ARGS
145  void fireArray (vector<HepDouble>&, HepDouble, HepDouble);
146 #else
147  void fireArray (vector<HepDouble,allocator<HepDouble> >&, HepDouble, HepDouble);
148 #endif
149  HepDouble operator()();
150 
151 private:
152 
153  // ShootBits generates an integer random number,
154  // which is used by fireBit().
155  // The number is stored in randomInt and firstUnusedBit
156 
157  inline void fireBits();
158  static inline void shootBits();
159  static inline void shootBits(HepRandomEngine*);
160 
161  // In MSB, the most significant bit of the integer random number
162  // generated by ShootBits() is set.
163  // Note:
164  // the number of significant bits must be chosen so that
165  // - an unsigned long can hold it
166  // - and it should be less than the number of bits returned
167  // by Shoot() which are not affected by precision problems
168  // on _each_ architecture.
169  // (Aim: the random generators should be machine-independent).
170 
171  HepRandomEngine* localEngine;
172  HepBoolean deleteEngine;
173 
174  unsigned long randomInt;
175  unsigned long firstUnusedBit;
176 
177  static const HepInt MSBBits;
178  static const unsigned long MSB;
179 
180  static unsigned long staticRandomInt;
181  static unsigned long staticFirstUnusedBit;
182 };
183 
184 inline RandFlat::RandFlat(HepRandomEngine & anEngine)
185 : localEngine(&anEngine), deleteEngine(false), firstUnusedBit(0) {}
186 
187 inline RandFlat::RandFlat(HepRandomEngine * anEngine)
188 : localEngine(anEngine), deleteEngine(true), firstUnusedBit(0) {}
189 
190 inline HepDouble RandFlat::shoot() {
191  return HepRandom::getTheGenerator()->flat();
192 }
193 
194 inline HepDouble RandFlat::shoot(HepDouble a, HepDouble b) {
195  return (b-a)* shoot() + a;
196 }
197 
198 inline HepDouble RandFlat::shoot(HepDouble width) {
199  return width * shoot();
200 }
201 
202 inline long RandFlat::shootInt(long n) {
203  return long(shoot()*HepDouble(n));
204 }
205 
206 inline long RandFlat::shootInt(long m, long n) {
207  return long(shoot()*HepDouble(n-m)) + m;
208 }
209 
210 inline void RandFlat::shootArray(const HepInt size, HepDouble* vect) {
211  HepRandom::getTheGenerator()->flatArray(size,vect);
212 }
213 
214 #ifndef ST_NO_TEMPLATE_DEF_ARGS
215 inline void RandFlat::shootArray(vector<HepDouble>& vec)
216 #else
217 inline void RandFlat::shootArray(vector<HepDouble,allocator<HepDouble> >& vec)
218 #endif
219 {
220  HepRandom::getTheGenerator()->flatArray(vec);
221 }
222 
223 inline void RandFlat::shootBits() {
224  const HepDouble factor= 2.0*MSB; // this should fit into a double!
225  staticFirstUnusedBit= MSB;
226  staticRandomInt= (unsigned long)(factor*shoot());
227 }
228 
229 inline HepInt RandFlat::shootBit() {
230  if (staticFirstUnusedBit==0)
231  shootBits();
232  unsigned long temp= staticFirstUnusedBit&staticRandomInt;
233  staticFirstUnusedBit>>= 1;
234  return temp!=0;
235 }
236 
237 //---------------------
238 
239 inline HepDouble RandFlat::shoot(HepRandomEngine* anEngine) {
240  return anEngine->flat();
241 }
242 
243 
244 inline HepDouble RandFlat::shoot(HepRandomEngine* anEngine,
245  HepDouble a, HepDouble b) {
246  return (b-a)* anEngine->flat() + a;
247 }
248 
249 inline HepDouble RandFlat::shoot(HepRandomEngine* anEngine,
250  HepDouble width) {
251  return width * anEngine->flat();
252 }
253 
254 inline long RandFlat::shootInt(HepRandomEngine* anEngine,
255  long n) {
256  return long(anEngine->flat()*HepDouble(n));
257 }
258 
259 inline long RandFlat::shootInt(HepRandomEngine* anEngine,
260  long m, long n) {
261  return long(HepDouble(n-m)*anEngine->flat()) + m;
262 }
263 
264 inline void RandFlat::shootArray(HepRandomEngine* anEngine,
265  const HepInt size, HepDouble* vect) {
266  anEngine->flatArray(size,vect);
267 }
268 
269 #ifndef ST_NO_TEMPLATE_DEF_ARGS
270 inline void RandFlat::shootArray(HepRandomEngine* anEngine,
271  vector<HepDouble>& vec)
272 #else
273 inline void RandFlat::shootArray(HepRandomEngine* anEngine,
274  vector<HepDouble,allocator<HepDouble> >& vec)
275 #endif
276 {
277  anEngine->flatArray(vec);
278 }
279 
280 inline void RandFlat::shootBits(HepRandomEngine* engine) {
281  const HepDouble factor= 2.0*MSB; // this should fit into a double!
282  staticFirstUnusedBit= MSB;
283  staticRandomInt= (unsigned long)(factor*shoot(engine));
284 }
285 
286 inline HepInt RandFlat::shootBit(HepRandomEngine* engine) {
287  if (staticFirstUnusedBit==0)
288  shootBits(engine);
289  unsigned long temp= staticFirstUnusedBit&staticRandomInt;
290  staticFirstUnusedBit>>= 1;
291  return temp!=0;
292 }
293 
294 //---------------------
295 
296 inline HepDouble RandFlat::fire() {
297  return localEngine->flat();
298 }
299 
300 inline HepDouble RandFlat::fire(HepDouble a, HepDouble b) {
301  return (b-a)* fire() + a;
302 }
303 
304 inline HepDouble RandFlat::fire(HepDouble width) {
305  return width * fire();
306 }
307 
308 inline long RandFlat::fireInt(long n) {
309  return long(fire()*HepDouble(n));
310 }
311 
312 inline long RandFlat::fireInt(long m, long n) {
313  return long(fire()*HepDouble(n-m)) + m;
314 }
315 
316 inline void RandFlat::fireArray(const HepInt size, HepDouble* vect) {
317  flatArray(localEngine,size,vect);
318 }
319 
320 #ifndef ST_NO_TEMPLATE_DEF_ARGS
321 inline void RandFlat::fireArray(vector<HepDouble>&vec)
322 #else
323 inline void RandFlat::fireArray(vector<HepDouble,allocator<HepDouble> >&vec)
324 #endif
325 {
326  flatArray(localEngine,vec);
327 }
328 
329 inline void RandFlat::fireBits() {
330  const HepDouble factor= 2.0*MSB; // this should fit into a HepDouble!
331  firstUnusedBit= MSB;
332  randomInt= (unsigned long)(factor*fire());
333 }
334 
335 inline HepInt RandFlat::fireBit() {
336  if (firstUnusedBit==0)
337  fireBits();
338  unsigned long temp= firstUnusedBit&randomInt;
339  firstUnusedBit>>= 1;
340  return temp!=0;
341 }
342 #endif