StRoot  1
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Groups Pages
RandGauss.cc
1 /***************************************************************************
2  *
3  * $Id: RandGauss.cc,v 1.4 2016/01/22 17:10:50 smirnovd Exp $
4  *
5  * Author: Gabriele Cosmo - Created: 5th September 1995
6  * modified for SCL bl
7  ***************************************************************************
8  *
9  * Description:
10  * RandGauss.cc,v 1.5 1997/08/12 00:38:43
11  * -----------------------------------------------------------------------
12  * HEP Random
13  * --- RandGauss ---
14  * class implementation file
15  * -----------------------------------------------------------------------
16  * This file is part of Geant4 (simulation toolkit for HEP).
17  *
18  ***************************************************************************
19  *
20  * $Log: RandGauss.cc,v $
21  * Revision 1.4 2016/01/22 17:10:50 smirnovd
22  * StarClassLibrary: Removed deprecated storage class specifier 'register'
23  *
24  * This keyword is deprecated since C++11 and serves no purpose
25  *
26  * "
27  * The register specifier is only allowed for objects declared at block scope and
28  * in function parameter lists. It indicates automatic storage duration, which is
29  * the default for these kinds of declarations. Additionally, the presence of this
30  * keyword may be used as a hint for the optimizer to store the value of this
31  * variable in a CPU register.
32  * "
33  *
34  * Revision 1.3 2003/09/02 17:59:34 perev
35  * gcc 3.2 updates + WarnOff
36  *
37  * Revision 1.2 1999/12/07 23:43:04 ullrich
38  * Modified to get rid of warnings on Linux.
39  *
40  * Revision 1.1 1999/01/30 03:59:00 fisyak
41  * Root Version of StarClassLibrary
42  *
43  * Revision 1.1 1999/01/23 00:29:08 ullrich
44  * Initial Revision
45  *
46  **************************************************************************/
47 #include "RandGauss.h"
48 
49 RandGauss::~RandGauss() {
50  if ( deleteEngine ) delete localEngine;
51 }
52 
53 HepDouble RandGauss::operator()() {
54  return fire();
55 }
56 
57 HepDouble RandGauss::shoot()
58 {
59  // Gaussian random numbers are generated two at the time, so every other
60  // time this is called we just return a number generated the time before.
61 
62  if ( getFlag() ) {
63  setFlag(false);
64  return getVal();
65  }
66 
67  HepDouble r;
68  HepDouble v1,v2,fac,val;
69 
70  do {
71  v1 = 2.0 * HepRandom::getTheGenerator()->flat() - 1.0;
72  v2 = 2.0 * HepRandom::getTheGenerator()->flat() - 1.0;
73  r = v1*v1 + v2*v2;
74  } while ( r > 1.0 );
75 
76  fac = ::sqrt(-2.0*::log(r)/r);
77  val = v1*fac;
78  setVal(val);
79  setFlag(true);
80  return v2*fac;
81 }
82 
83 void RandGauss::shootArray( const HepInt size, HepDouble* vect,
84  HepDouble mean, HepDouble stdDev )
85 {
86  HepInt i;
87 
88  for (i=0; i<size; ++i)
89  vect[i] = shoot(mean,stdDev);
90 }
91 
92 void
93 #ifndef ST_NO_TEMPLATE_DEF_ARGS
94 RandGauss::shootArray( vector<HepDouble>& vec,
95  HepDouble mean, HepDouble stdDev )
96 #else
97 RandGauss::shootArray( vector<HepDouble,allocator<HepDouble> >& vec,
98  HepDouble mean, HepDouble stdDev )
99 #endif
100 {
101  for (unsigned int i=0; i<vec.size(); ++i)
102  vec[i] = shoot(mean,stdDev);
103 }
104 
105 HepDouble RandGauss::shoot( HepRandomEngine* anEngine )
106 {
107  // Gaussian random numbers are generated two at the time, so every other
108  // time this is called we just return a number generated the time before.
109 
110  if ( getFlag() ) {
111  setFlag(false);
112  return getVal();
113  }
114 
115  HepDouble r;
116  HepDouble v1,v2,fac,val;
117 
118  do {
119  v1 = 2.0 * anEngine->flat() - 1.0;
120  v2 = 2.0 * anEngine->flat() - 1.0;
121  r = v1*v1 + v2*v2;
122  } while ( r > 1.0 );
123 
124  fac = ::sqrt( -2.0*::log(r)/r);
125  val = v1*fac;
126  setVal(val);
127  setFlag(true);
128  return v2*fac;
129 }
130 
131 void RandGauss::shootArray( HepRandomEngine* anEngine,
132  const HepInt size, HepDouble* vect,
133  HepDouble mean, HepDouble stdDev )
134 {
135  HepInt i;
136 
137  for (i=0; i<size; ++i)
138  vect[i] = shoot(anEngine,mean,stdDev);
139 }
140 
141 void
142 #ifndef ST_NO_TEMPLATE_DEF_ARGS
143 RandGauss::shootArray( HepRandomEngine* anEngine,
144  vector<HepDouble>& vec,
145  HepDouble mean, HepDouble stdDev )
146 #else
147 RandGauss::shootArray( HepRandomEngine* anEngine,
148  vector<HepDouble,allocator<HepDouble> >& vec,
149  HepDouble mean, HepDouble stdDev )
150 #endif
151 {
152  for (unsigned int i=0; i<vec.size(); ++i)
153  vec[i] = shoot(anEngine,mean,stdDev);
154 }
155 
156 
157 HepDouble RandGauss::fire()
158 {
159  // Gaussian random numbers are generated two at the time, so every other
160  // time this is called we just return a number generated the time before.
161 
162  if ( set ) {
163  set = false;
164  return nextGauss;
165  }
166 
167  HepDouble r;
168  HepDouble v1,v2,fac,val;
169 
170  do {
171  v1 = 2.0 * localEngine->flat() - 1.0;
172  v2 = 2.0 * localEngine->flat() - 1.0;
173  r = v1*v1 + v2*v2;
174  } while ( r > 1.0 );
175 
176  fac = ::sqrt(-2.0*::log(r)/r);
177  val = v1*fac;
178  nextGauss = val;
179  set = true;
180  return v2*fac;
181 }
182 
183 void RandGauss::fireArray( const HepInt size, HepDouble* vect,
184  HepDouble mean, HepDouble stdDev )
185 {
186  HepInt i;
187 
188  for (i=0; i<size; ++i)
189  vect[i] = fire(mean,stdDev);
190 }
191 
192 void
193 #ifndef ST_NO_TEMPLATE_DEF_ARGS
194 RandGauss::fireArray( vector<HepDouble>& vec,
195  HepDouble mean, HepDouble stdDev )
196 #else
197 RandGauss::fireArray( vector<HepDouble,allocator<HepDouble> >& vec,
198  HepDouble mean, HepDouble stdDev )
199 #endif
200 {
201  for (unsigned int i=0; i<vec.size(); ++i)
202  vec[i] = fire(mean,stdDev);
203 }