Geant4  10.01.p02
G4MTRandGauss.cc
Go to the documentation of this file.
1 //
2 // ********************************************************************
3 // * License and Disclaimer *
4 // * *
5 // * The Geant4 software is copyright of the Copyright Holders of *
6 // * the Geant4 Collaboration. It is provided under the terms and *
7 // * conditions of the Geant4 Software License, included in the file *
8 // * LICENSE and available at http://cern.ch/geant4/license . These *
9 // * include a list of copyright holders. *
10 // * *
11 // * Neither the authors of this software system, nor their employing *
12 // * institutes,nor the agencies providing financial support for this *
13 // * work make any representation or warranty, express or implied, *
14 // * regarding this software system or assume any liability for its *
15 // * use. Please see the license in the file LICENSE and URL above *
16 // * for the full disclaimer and the limitation of liability. *
17 // * *
18 // * This code implementation is the result of the scientific and *
19 // * technical work of the GEANT4 collaboration. *
20 // * By using, copying, modifying or distributing the software (or *
21 // * any work based on the software) you agree to acknowledge its *
22 // * use in resulting scientific publications, and indicate your *
23 // * acceptance of all terms of the Geant4 Software license. *
24 // ********************************************************************
25 //
26 //
27 // $Id:$
28 //
29 #if __clang__
30  #if ((defined(G4MULTITHREADED) && !defined(G4USE_STD11)) || \
31  !__has_feature(cxx_thread_local))
32  #define CLANG_NOSTDTLS
33  #endif
34 #endif
35 
36 #if (defined(G4MULTITHREADED) && \
37  (!defined(G4USE_STD11) || (defined(CLANG_NOSTDTLS))))
38 
39 #include <cmath> // for log()
40 
41 #include "G4MTRandGauss.hh"
42 
43 // Initialisation of static data
46 
48 {
49  if ( deleteEngine ) delete localEngine;
50 }
51 
53 {
54  return fire( defaultMean, defaultStdDev );
55 }
56 
58 {
59  return fire( mean, stdDev );
60 }
61 
63 {
64  // Gaussian random numbers are generated two at the time, so every other
65  // time this is called we just return a number generated the time before.
66 
67  if ( getFlag() ) {
68  setFlag(false);
69  G4double x = getVal();
70  return x;
71  // return getVal();
72  }
73 
74  G4double r;
75  G4double v1,v2,fac,val;
76  CLHEP::HepRandomEngine* anEngine = G4MTHepRandom::getTheEngine();
77 
78  do {
79  v1 = 2.0 * anEngine->flat() - 1.0;
80  v2 = 2.0 * anEngine->flat() - 1.0;
81  r = v1*v1 + v2*v2;
82  } while ( r > 1.0 );
83 
84  fac = std::sqrt(-2.0*std::log(r)/r);
85  val = v1*fac;
86  setVal(val);
87  setFlag(true);
88  return v2*fac;
89 }
90 
91 void G4MTRandGauss::shootArray( const G4int size, G4double* vect,
92  G4double mean, G4double stdDev )
93 {
94  for (G4int i=0; i<size; ++i)
95  vect[i] = shoot(mean,stdDev);
96 }
97 
98 G4double G4MTRandGauss::shoot( CLHEP::HepRandomEngine* anEngine )
99 {
100  // Gaussian random numbers are generated two at the time, so every other
101  // time this is called we just return a number generated the time before.
102 
103  if ( getFlag() ) {
104  setFlag(false);
105  return getVal();
106  }
107 
108  G4double r;
109  G4double v1,v2,fac,val;
110 
111  do {
112  v1 = 2.0 * anEngine->flat() - 1.0;
113  v2 = 2.0 * anEngine->flat() - 1.0;
114  r = v1*v1 + v2*v2;
115  } while ( r > 1.0 );
116 
117  fac = std::sqrt( -2.0*std::log(r)/r);
118  val = v1*fac;
119  setVal(val);
120  setFlag(true);
121  return v2*fac;
122 }
123 
124 void G4MTRandGauss::shootArray( CLHEP::HepRandomEngine* anEngine,
125  const G4int size, G4double* vect,
126  G4double mean, G4double stdDev )
127 {
128  for (G4int i=0; i<size; ++i)
129  vect[i] = shoot(anEngine,mean,stdDev);
130 }
131 
133 {
134  // Gaussian random numbers are generated two at the time, so every other
135  // time this is called we just return a number generated the time before.
136 
137  if ( set ) {
138  set = false;
139  return nextGauss;
140  }
141 
142  G4double r;
143  G4double v1,v2,fac,val;
144 
145  do {
146  v1 = 2.0 * localEngine->flat() - 1.0;
147  v2 = 2.0 * localEngine->flat() - 1.0;
148  r = v1*v1 + v2*v2;
149  } while ( r > 1.0 );
150 
151  fac = std::sqrt(-2.0*std::log(r)/r);
152  val = v1*fac;
153  nextGauss = val;
154  set = true;
155  return v2*fac;
156 }
157 
158 void G4MTRandGauss::fireArray( const G4int size, G4double* vect)
159 {
160  for (G4int i=0; i<size; ++i)
161  vect[i] = fire( defaultMean, defaultStdDev );
162 }
163 
164 void G4MTRandGauss::fireArray( const G4int size, G4double* vect,
165  G4double mean, G4double stdDev )
166 {
167  for (G4int i=0; i<size; ++i)
168  vect[i] = fire( mean, stdDev );
169 }
170 
171 #endif
G4double defaultStdDev
static CLHEP::HepRandomEngine * getTheEngine()
virtual G4double operator()()
G4double nextGauss
static void shootArray(const G4int size, G4double *vect, G4double mean=0.0, G4double stdDev=1.0)
G4double defaultMean
G4double fire()
#define G4ThreadLocal
Definition: tls.hh:89
int G4int
Definition: G4Types.hh:78
static G4ThreadLocal G4double nextGauss_st
G4double normal()
bool G4bool
Definition: G4Types.hh:79
static G4bool getFlag()
virtual ~G4MTRandGauss()
void fireArray(const G4int size, G4double *vect)
static const G4double fac
static G4double shoot()
double G4double
Definition: G4Types.hh:76
static G4double getVal()
static void setFlag(G4bool val)
CLHEP::HepRandomEngine * localEngine
static void setVal(G4double nextVal)
static G4ThreadLocal G4bool set_st