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