1 #include "CLHEP/Random/RandGaussZiggurat.h"
2 #include "CLHEP/Units/PhysicalConstants.h"
8 CLHEP_THREAD_LOCAL
unsigned long RandGaussZiggurat::kn[128], RandGaussZiggurat::ke[256];
9 CLHEP_THREAD_LOCAL
float RandGaussZiggurat::wn[128],RandGaussZiggurat::fn[128],RandGaussZiggurat::we[256],
RandGaussZiggurat::fe[256];
10 CLHEP_THREAD_LOCAL
bool RandGaussZiggurat::ziggurat_is_init =
false;
14 RandGaussZiggurat::~RandGaussZiggurat() {
19 return "RandGaussZiggurat";
22 bool RandGaussZiggurat::ziggurat_init()
24 const double rzm1 = 2147483648.0, rzm2 = 4294967296.;
25 double dn=3.442619855899,tn=dn,vn=9.91256303526217e-3, q;
26 double de=7.697117470131487, te=de, ve=3.949659822581572e-3;
30 q=vn/std::exp(-.5*dn*dn);
31 kn[0]=(
unsigned long)((dn/q)*rzm1);
38 fn[127]=std::exp(-.5*dn*dn);
41 dn=std::sqrt(-2.*std::log(vn/dn+std::exp(-.5*dn*dn)));
42 kn[i+1]=(
unsigned long)((dn/tn)*rzm1);
44 fn[i]=std::exp(-.5*dn*dn);
50 ke[0]=(
unsigned long)((de/q)*rzm2);
57 fe[255]=std::exp(-de);
60 de=-std::log(ve/de+std::exp(-de));
61 ke[i+1]= (
unsigned long)((de/te)*rzm2);
66 ziggurat_is_init=
true;
73 float RandGaussZiggurat::ziggurat_nfix(
long hz,HepRandomEngine* anEngine)
75 if(!ziggurat_is_init) ziggurat_init();
76 const float r = 3.442620f;
78 unsigned long iz=hz&127;
86 x=-std::log(1.0 - ziggurat_UNI(anEngine))*0.2904764;
87 y=-std::log(1.0 - ziggurat_UNI(anEngine));
89 return (hz>0)? r+x : -r-x;
92 if( fn[iz]+(1.0 - ziggurat_UNI(anEngine))*(fn[iz-1]-fn[iz]) < std::exp(-.5*x*x) )
return x;
95 hz=(signed)ziggurat_SHR3(anEngine);
97 if((
unsigned long)std::abs(hz)<kn[iz])
return (hz*wn[iz]);
101 double RandGaussZiggurat::operator()() {
102 return ziggurat_RNOR(localEngine.get()) * defaultStdDev + defaultMean;
105 double RandGaussZiggurat::operator()(
double mean,
double stdDev ) {
106 return ziggurat_RNOR(localEngine.get()) * stdDev + mean;
109 void RandGaussZiggurat::shootArray(
const int size,
float* vect,
float mean,
float stdDev )
111 for (
int i=0; i<size; ++i) {
112 vect[i] =
shoot(mean,stdDev);
116 void RandGaussZiggurat::shootArray(
const int size,
double* vect,
double mean,
double stdDev )
118 for (
int i=0; i<size; ++i) {
119 vect[i] =
shoot(mean,stdDev);
123 void RandGaussZiggurat::shootArray( HepRandomEngine* anEngine,
const int size,
float* vect,
float mean,
float stdDev )
125 for (
int i=0; i<size; ++i) {
126 vect[i] =
shoot(anEngine,mean,stdDev);
130 void RandGaussZiggurat::shootArray( HepRandomEngine* anEngine,
const int size,
double* vect,
double mean,
double stdDev )
132 for (
int i=0; i<size; ++i) {
133 vect[i] =
shoot(anEngine,mean,stdDev);
137 void RandGaussZiggurat::fireArray(
const int size,
float* vect)
139 for (
int i=0; i<size; ++i) {
140 vect[i] = fire( defaultMean, defaultStdDev );
144 void RandGaussZiggurat::fireArray(
const int size,
double* vect)
146 for (
int i=0; i<size; ++i) {
147 vect[i] = fire( defaultMean, defaultStdDev );
151 void RandGaussZiggurat::fireArray(
const int size,
float* vect,
float mean,
float stdDev )
153 for (
int i=0; i<size; ++i) {
154 vect[i] = fire( mean, stdDev );
158 void RandGaussZiggurat::fireArray(
const int size,
double* vect,
double mean,
double stdDev )
160 for (
int i=0; i<size; ++i) {
161 vect[i] = fire( mean, stdDev );
165 std::ostream & RandGaussZiggurat::put ( std::ostream & os )
const {
166 int pr=os.precision(20);
167 os <<
" " <<
name() <<
"\n";
173 std::istream & RandGaussZiggurat::get ( std::istream & is ) {
176 if (inName !=
name()) {
177 is.clear(std::ios::badbit | is.rdstate());
178 std::cerr <<
"Mismatch when expecting to read state of a "
179 <<
name() <<
" distribution\n"
180 <<
"Name found was " << inName
181 <<
"\nistream is left in the badbit state\n";
ThreeVector shoot(const G4int Ap, const G4int Af)
static int engine(pchar, pchar, double &, pchar &, const dic_type &)
const char * name(G4int ptype)