CLHEP 2.4.6.4
C++ Class Library for High Energy Physics
Loading...
Searching...
No Matches
RandGaussZiggurat.cc
Go to the documentation of this file.
1//
2// -*- C++ -*-
3//
4// -----------------------------------------------------------------------
5// HEP Random
6// --- RandGaussZiggurat ---
7// class implementation file
8// -----------------------------------------------------------------------
9
10// =======================================================================
11
12#include "CLHEP/Random/defs.h"
13#include "CLHEP/Random/RandGaussZiggurat.h"
14#include "CLHEP/Units/PhysicalConstants.h"
15#include <iostream>
16#include <cmath> // for log()
17
18namespace CLHEP {
19
20CLHEP_THREAD_LOCAL unsigned long RandGaussZiggurat::kn[128], RandGaussZiggurat::ke[256];
22CLHEP_THREAD_LOCAL bool RandGaussZiggurat::ziggurat_is_init = false;
23
25
27}
28
29std::string RandGaussZiggurat::name() const
30{
31 return "RandGaussZiggurat";
32}
33
35{
36 const double rzm1 = 2147483648.0, rzm2 = 4294967296.;
37 double dn=3.442619855899,tn=dn,vn=9.91256303526217e-3, q;
38 double de=7.697117470131487, te=de, ve=3.949659822581572e-3;
39 int i;
40
41/* Set up tables for RNOR */
42 q=vn/exp(-.5*dn*dn);
43 kn[0]=(unsigned long)((dn/q)*rzm1);
44 kn[1]=0;
45
46 wn[0]=q/rzm1;
47 wn[127]=dn/rzm1;
48
49 fn[0]=1.;
50 fn[127]=exp(-.5*dn*dn);
51
52 for(i=126;i>=1;i--) {
53 dn=sqrt(-2.*log(vn/dn+exp(-.5*dn*dn)));
54 kn[i+1]=(unsigned long)((dn/tn)*rzm1);
55 tn=dn;
56 fn[i]=exp(-.5*dn*dn);
57 wn[i]=dn/rzm1;
58 }
59
60/* Set up tables for REXP */
61 q = ve/exp(-de);
62 ke[0]=(unsigned long)((de/q)*rzm2);
63 ke[1]=0;
64
65 we[0]=q/rzm2;
66 we[255]=de/rzm2;
67
68 fe[0]=1.;
69 fe[255]=exp(-de);
70
71 for(i=254;i>=1;i--) {
72 de=-log(ve/de+exp(-de));
73 ke[i+1]= (unsigned long)((de/te)*rzm2);
74 te=de;
75 fe[i]=exp(-de);
76 we[i]=de/rzm2;
77 }
79
80 //std::cout<<"Done RandGaussZiggurat::ziggurat_init()"<<std::endl;
81
82 return true;
83}
84
86{
88 const float r = 3.442620f; /* The start of the right tail */
89 float x, y;
90 unsigned long iz=hz&127;
91 for(;;)
92 {
93 x=hz*wn[iz]; /* iz==0, handles the base strip */
94 if(iz==0) {
95 do {
96 /* change to (1.0 - UNI) as argument to log(), because CLHEP generates [0,1),
97 while the original UNI generates (0,1] */
98 x=-log(1.0 - ziggurat_UNI(anEngine))*0.2904764; /* .2904764 is 1/r */
99 y=-log(1.0 - ziggurat_UNI(anEngine));
100 } while(y+y<x*x);
101 return (hz>0)? r+x : -r-x;
102 }
103 /* iz>0, handle the wedges of other strips */
104 if( fn[iz]+(1.0 - ziggurat_UNI(anEngine))*(fn[iz-1]-fn[iz]) < exp(-.5*x*x) ) return x;
105
106 /* initiate, try to exit for(;;) for loop*/
107 hz=(signed)ziggurat_SHR3(anEngine);
108 iz=hz&127;
109 if((unsigned long)std::abs(hz)<kn[iz]) return (hz*wn[iz]);
110 }
111}
112
115}
116
117double RandGaussZiggurat::operator()( double mean, double stdDev ) {
118 return ziggurat_RNOR(localEngine.get()) * stdDev + mean;
119}
120
121void RandGaussZiggurat::shootArray( const int size, float* vect, float mean, float stdDev )
122{
123 for (int i=0; i<size; ++i) {
124 vect[i] = shoot(mean,stdDev);
125 }
126}
127
128void RandGaussZiggurat::shootArray( const int size, double* vect, double mean, double stdDev )
129{
130 for (int i=0; i<size; ++i) {
131 vect[i] = shoot(mean,stdDev);
132 }
133}
134
135void RandGaussZiggurat::shootArray( HepRandomEngine* anEngine, const int size, float* vect, float mean, float stdDev )
136{
137 for (int i=0; i<size; ++i) {
138 vect[i] = shoot(anEngine,mean,stdDev);
139 }
140}
141
142void RandGaussZiggurat::shootArray( HepRandomEngine* anEngine, const int size, double* vect, double mean, double stdDev )
143{
144 for (int i=0; i<size; ++i) {
145 vect[i] = shoot(anEngine,mean,stdDev);
146 }
147}
148
149void RandGaussZiggurat::fireArray( const int size, float* vect)
150{
151 for (int i=0; i<size; ++i) {
152 vect[i] = fire( defaultMean, defaultStdDev );
153 }
154}
155
156void RandGaussZiggurat::fireArray( const int size, double* vect)
157{
158 for (int i=0; i<size; ++i) {
159 vect[i] = fire( defaultMean, defaultStdDev );
160 }
161}
162
163void RandGaussZiggurat::fireArray( const int size, float* vect, float mean, float stdDev )
164{
165 for (int i=0; i<size; ++i) {
166 vect[i] = fire( mean, stdDev );
167 }
168}
169
170void RandGaussZiggurat::fireArray( const int size, double* vect, double mean, double stdDev )
171{
172 for (int i=0; i<size; ++i) {
173 vect[i] = fire( mean, stdDev );
174 }
175}
176
177std::ostream & RandGaussZiggurat::put ( std::ostream & os ) const {
178 long pr=os.precision(20);
179 os << " " << name() << "\n";
180 RandGauss::put(os);
181 os.precision(pr);
182 return os;
183}
184
185std::istream & RandGaussZiggurat::get ( std::istream & is ) {
186 std::string inName;
187 is >> inName;
188 if (inName != name()) {
189 is.clear(std::ios::badbit | is.rdstate());
190 std::cerr << "Mismatch when expecting to read state of a "
191 << name() << " distribution\n"
192 << "Name found was " << inName
193 << "\nistream is left in the badbit state\n";
194 return is;
195 }
196 RandGauss::get(is);
197 return is;
198}
199
200} // namespace CLHEP
static void shootArray(const int size, float *vect, float mean=0.0, float stdDev=1.0)
static CLHEP_THREAD_LOCAL unsigned long ke[256]
std::istream & get(std::istream &is)
void fireArray(const int size, float *vect)
static float ziggurat_nfix(long hz, HepRandomEngine *anEngine)
static float ziggurat_UNI(HepRandomEngine *anEngine)
static CLHEP_THREAD_LOCAL float fn[128]
std::ostream & put(std::ostream &os) const
static float ziggurat_RNOR(HepRandomEngine *anEngine)
static CLHEP_THREAD_LOCAL unsigned long kn[128]
static CLHEP_THREAD_LOCAL float fe[256]
HepRandomEngine & engine()
static CLHEP_THREAD_LOCAL float we[256]
static unsigned long ziggurat_SHR3(HepRandomEngine *anEngine)
std::string name() const
static CLHEP_THREAD_LOCAL float wn[128]
static CLHEP_THREAD_LOCAL bool ziggurat_is_init
std::istream & get(std::istream &is)
Definition: RandGauss.cc:285
double defaultStdDev
Definition: RandGauss.h:154
std::ostream & put(std::ostream &os) const
Definition: RandGauss.cc:260
HepRandomEngine & engine()
Definition: RandGauss.cc:47
double defaultMean
Definition: RandGauss.h:153
std::shared_ptr< HepRandomEngine > localEngine
Definition: RandGauss.h:156