Geant4 10.7.0
Toolkit for the simulation of the passage of particles through matter
Loading...
Searching...
No Matches
RandExpZiggurat.h
Go to the documentation of this file.
1/*
2Code adapted from:
3http://www.jstatsoft.org/v05/i08/
4
5
6Original disclaimer:
7
8The ziggurat method for RNOR and REXP
9Combine the code below with the main program in which you want
10normal or exponential variates. Then use of RNOR in any expression
11will provide a standard normal variate with mean zero, variance 1,
12while use of REXP in any expression will provide an exponential variate
13with density exp(-x),x>0.
14Before using RNOR or REXP in your main, insert a command such as
15zigset(86947731 );
16with your own choice of seed value>0, rather than 86947731.
17(If you do not invoke zigset(...) you will get all zeros for RNOR and REXP.)
18For details of the method, see Marsaglia and Tsang, "The ziggurat method
19for generating random variables", Journ. Statistical Software.
20
21*/
22
23#ifndef RandExpZiggurat_h
24#define RandExpZiggurat_h 1
25
26#include "CLHEP/Random/Random.h"
29
30namespace CLHEP {
31
32/**
33 * @author ATLAS
34 * @ingroup random
35 */
36class RandExpZiggurat : public HepRandom {
37
38public:
39
40 inline RandExpZiggurat ( HepRandomEngine& anEngine, double mean=1.0 );
41 inline RandExpZiggurat ( HepRandomEngine* anEngine, double mean=1.0 );
42 // These constructors should be used to instantiate a RandExpZiggurat
43 // distribution object defining a local engine for it.
44 // The static generator will be skipped using the non-static methods
45 // defined below.
46 // If the engine is passed by pointer the corresponding engine object
47 // will be deleted by the RandExpZiggurat destructor.
48 // If the engine is passed by reference the corresponding engine object
49 // will not be deleted by the RandExpZiggurat destructor.
50
51 virtual ~RandExpZiggurat();
52 // Destructor
53
54 // Static methods to shoot random values using the static generator
55
56 static float shoot() {return shoot(HepRandom::getTheEngine());}
57 static float shoot( float mean ) {return shoot(HepRandom::getTheEngine(),mean);}
58
59 /* ENGINE IS INTRINSIC FLOAT
60 static double shoot() {return shoot(HepRandom::getTheEngine());}
61 static double shoot( double mean ) {return shoot(HepRandom::getTheEngine(),mean);}
62 */
63
64 static void shootArray ( const int size, float* vect, float mean=1.0 );
65 static void shootArray ( const int size, double* vect, double mean=1.0 );
66
67 // Static methods to shoot random values using a given engine
68 // by-passing the static generator.
69
70 static inline float shoot( HepRandomEngine* anEngine ) {return ziggurat_REXP(anEngine);}
71 static inline float shoot( HepRandomEngine* anEngine, float mean ) {return shoot(anEngine)*mean;}
72
73 /* ENGINE IS INTRINSIC FLOAT
74 static inline double shoot( HepRandomEngine* anEngine ) {return ziggurat_REXP(anEngine);}
75
76 static inline double shoot( HepRandomEngine* anEngine, double mean ) {return shoot(anEngine)*mean;}
77 */
78
79 static void shootArray ( HepRandomEngine* anEngine, const int size, float* vect, float mean=1.0 );
80 static void shootArray ( HepRandomEngine* anEngine, const int size, double* vect, double mean=1.0 );
81
82 // Methods using the localEngine to shoot random values, by-passing
83 // the static generator.
84
85 inline float fire() {return fire(float(defaultMean));}
86 inline float fire( float mean ) {return ziggurat_REXP(localEngine.get())*mean;}
87
88 /* ENGINE IS INTRINSIC FLOAT
89 inline double fire() {return fire(defaultMean);}
90 inline double fire( double mean ) {return ziggurat_REXP(localEngine.get())*mean;}
91 */
92
93 void fireArray ( const int size, float* vect );
94 void fireArray ( const int size, double* vect );
95 void fireArray ( const int size, float* vect, float mean );
96 void fireArray ( const int size, double* vect, double mean );
97
98 virtual double operator()();
99 inline float operator()( float mean ) {return fire( mean );}
100
101 // Save and restore to/from streams
102
103 std::ostream & put ( std::ostream & os ) const;
104 std::istream & get ( std::istream & is );
105
106 std::string name() const;
108
109 static std::string distributionName() {return "RandExpZiggurat";}
110 // Provides the name of this distribution class
111
112 static bool ziggurat_init();
113protected:
114 //////////////////////////
115 // Ziggurat Original code:
116 //////////////////////////
117 //static unsigned long jz,jsr=123456789;
118 //
119 //#define SHR3 (jz=jsr, jsr^=(jsr<<13), jsr^=(jsr>>17), jsr^=(jsr<<5),jz+jsr)
120 //#define UNI (.5 + (signed) SHR3*.2328306e-9)
121 //#define IUNI SHR3
122 //
123 //static long hz;
124 //static unsigned long iz, kn[128], ke[256];
125 //static float wn[128],fn[128], we[256],fe[256];
126 //
127 //#define RNOR (hz=SHR3, iz=hz&127, (fabs(hz)<kn[iz])? hz*wn[iz] : nfix())
128 //#define REXP (jz=SHR3, iz=jz&255, ( jz <ke[iz])? jz*we[iz] : efix())
129
130 static CLHEP_THREAD_LOCAL unsigned long kn[128], ke[256];
131 static CLHEP_THREAD_LOCAL float wn[128],fn[128], we[256],fe[256];
132
134
135 static inline unsigned long ziggurat_SHR3(HepRandomEngine* anEngine) {return (unsigned int)(*anEngine);}
136 static inline float ziggurat_UNI(HepRandomEngine* anEngine) {return float(anEngine->flat());}
137 static inline float ziggurat_REXP(HepRandomEngine* anEngine) {
139 unsigned long jz=ziggurat_SHR3(anEngine);
140 unsigned long iz=jz&255;
141 return (jz<ke[iz]) ? jz*we[iz] : ziggurat_efix(jz,anEngine);
142 }
143 static float ziggurat_efix(unsigned long jz,HepRandomEngine* anEngine);
144
145private:
146
147 // Private copy constructor. Defining it here disallows use.
149
150 std::shared_ptr<HepRandomEngine> localEngine;
151 double defaultMean;
152};
153
154} // namespace CLHEP
155
156namespace CLHEP {
157
158inline RandExpZiggurat::RandExpZiggurat(HepRandomEngine & anEngine, double mean ) : localEngine(&anEngine, do_nothing_deleter()), defaultMean(mean)
159{
160}
161
162inline RandExpZiggurat::RandExpZiggurat(HepRandomEngine * anEngine, double mean ) : localEngine(anEngine), defaultMean(mean)
163{
164}
165
166} // namespace CLHEP
167
168#endif
virtual double flat()=0
static HepRandomEngine * getTheEngine()
Definition: Random.cc:268
float fire(float mean)
static CLHEP_THREAD_LOCAL float fn[128]
static float shoot(float mean)
static float ziggurat_REXP(HepRandomEngine *anEngine)
static unsigned long ziggurat_SHR3(HepRandomEngine *anEngine)
static CLHEP_THREAD_LOCAL unsigned long ke[256]
static void shootArray(const int size, float *vect, float mean=1.0)
static CLHEP_THREAD_LOCAL float fe[256]
HepRandomEngine & engine()
static float ziggurat_efix(unsigned long jz, HepRandomEngine *anEngine)
float operator()(float mean)
std::istream & get(std::istream &is)
static float shoot(HepRandomEngine *anEngine)
static CLHEP_THREAD_LOCAL float wn[128]
RandExpZiggurat(HepRandomEngine &anEngine, double mean=1.0)
virtual double operator()()
static float shoot(HepRandomEngine *anEngine, float mean)
static CLHEP_THREAD_LOCAL float we[256]
static CLHEP_THREAD_LOCAL unsigned long kn[128]
std::string name() const
static std::string distributionName()
void fireArray(const int size, float *vect)
static float ziggurat_UNI(HepRandomEngine *anEngine)
static CLHEP_THREAD_LOCAL bool ziggurat_is_init
std::ostream & put(std::ostream &os) const
Definition: DoubConv.h:17
#define CLHEP_THREAD_LOCAL
Definition: thread_local.h:13