Import Geant4 10.5.0.beta source tree
This commit is contained in:
@@ -1,234 +0,0 @@
|
||||
//
|
||||
// ********************************************************************
|
||||
// * License and Disclaimer *
|
||||
// * *
|
||||
// * The Geant4 software is copyright of the Copyright Holders of *
|
||||
// * the Geant4 Collaboration. It is provided under the terms and *
|
||||
// * conditions of the Geant4 Software License, included in the file *
|
||||
// * LICENSE and available at http://cern.ch/geant4/license . These *
|
||||
// * include a list of copyright holders. *
|
||||
// * *
|
||||
// * Neither the authors of this software system, nor their employing *
|
||||
// * institutes,nor the agencies providing financial support for this *
|
||||
// * work make any representation or warranty, express or implied, *
|
||||
// * regarding this software system or assume any liability for its *
|
||||
// * use. Please see the license in the file LICENSE and URL above *
|
||||
// * for the full disclaimer and the limitation of liability. *
|
||||
// * *
|
||||
// * This code implementation is the result of the scientific and *
|
||||
// * technical work of the GEANT4 collaboration. *
|
||||
// * By using, copying, modifying or distributing the software (or *
|
||||
// * any work based on the software) you agree to acknowledge its *
|
||||
// * use in resulting scientific publications, and indicate your *
|
||||
// * acceptance of all terms of the Geant4 Software license. *
|
||||
// ********************************************************************
|
||||
//
|
||||
//
|
||||
// $Id:$
|
||||
//
|
||||
#if __clang__
|
||||
#if ((defined(G4MULTITHREADED) && !defined(G4USE_STD11)) || \
|
||||
!__has_feature(cxx_thread_local)) || !__has_feature(c_atomic)
|
||||
#define CLANG_NOSTDTLS
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#if (defined(G4MULTITHREADED) && \
|
||||
(!defined(G4USE_STD11) || (defined(CLANG_NOSTDTLS) || defined(__INTEL_COMPILER))))
|
||||
|
||||
#include <CLHEP/Random/StaticRandomStates.h>
|
||||
#include <CLHEP/Random/JamesRandom.h>
|
||||
|
||||
#include "G4MTHepRandom.hh"
|
||||
#include "G4Threading.hh"
|
||||
#include "G4AutoLock.hh"
|
||||
|
||||
G4ThreadLocal CLHEP::HepRandomEngine* G4MTHepRandom::theEngine = 0;
|
||||
G4ThreadLocal G4MTHepRandom* G4MTHepRandom::theGenerator = 0;
|
||||
G4ThreadLocal G4int G4MTHepRandom::isActive = 0 ;
|
||||
|
||||
//---------------------------- HepRandom ---------------------------------
|
||||
|
||||
G4MTHepRandom::G4MTHepRandom()
|
||||
: deleteEngine(false)
|
||||
{
|
||||
createInstance();
|
||||
}
|
||||
|
||||
G4MTHepRandom::G4MTHepRandom(G4long seed)
|
||||
: deleteEngine(false)
|
||||
{
|
||||
createInstance();
|
||||
setTheSeed(seed);
|
||||
}
|
||||
|
||||
G4MTHepRandom::G4MTHepRandom(CLHEP::HepRandomEngine & algorithm)
|
||||
: deleteEngine(false)
|
||||
{
|
||||
theGenerator = this;
|
||||
theEngine = &algorithm;
|
||||
isActive = 1;
|
||||
}
|
||||
|
||||
G4MTHepRandom::G4MTHepRandom(CLHEP::HepRandomEngine * algorithm)
|
||||
: deleteEngine(true)
|
||||
{
|
||||
createInstance();
|
||||
theEngine = algorithm;
|
||||
}
|
||||
|
||||
G4MTHepRandom::~G4MTHepRandom()
|
||||
{
|
||||
if ( deleteEngine ) { delete theEngine; theEngine = 0; }
|
||||
//if ( theGenerator ) { delete theGenerator; theGenerator = 0; }
|
||||
}
|
||||
|
||||
G4double G4MTHepRandom::flat()
|
||||
{
|
||||
return theEngine->flat();
|
||||
}
|
||||
|
||||
void G4MTHepRandom::flatArray(const G4int size, G4double* vect)
|
||||
{
|
||||
theEngine->flatArray(size,vect);
|
||||
}
|
||||
|
||||
G4double G4MTHepRandom::operator()()
|
||||
{
|
||||
return flat();
|
||||
}
|
||||
|
||||
std::ostream & operator<< (std::ostream & os, const G4MTHepRandom & dist)
|
||||
{
|
||||
return dist.put(os);
|
||||
}
|
||||
|
||||
std::istream & operator>> (std::istream & is, G4MTHepRandom & dist)
|
||||
{
|
||||
return dist.get(is);
|
||||
}
|
||||
|
||||
std::ostream & G4MTHepRandom::put(std::ostream & os) const
|
||||
{
|
||||
return os;
|
||||
}
|
||||
std::istream & G4MTHepRandom::get(std::istream & is)
|
||||
{
|
||||
return is;
|
||||
}
|
||||
|
||||
// --------------------------
|
||||
// Static methods definitions
|
||||
// --------------------------
|
||||
|
||||
void G4MTHepRandom::setTheSeed(G4long seed, G4int lux)
|
||||
{
|
||||
createInstance();
|
||||
theEngine->setSeed(seed,lux);
|
||||
}
|
||||
|
||||
G4long G4MTHepRandom::getTheSeed()
|
||||
{
|
||||
createInstance();
|
||||
return theEngine->getSeed();
|
||||
}
|
||||
|
||||
void G4MTHepRandom::setTheSeeds(const G4long* seeds, G4int aux)
|
||||
{
|
||||
createInstance();
|
||||
theEngine->setSeeds(seeds,aux);
|
||||
}
|
||||
|
||||
const G4long* G4MTHepRandom::getTheSeeds ()
|
||||
{
|
||||
createInstance();
|
||||
return theEngine->getSeeds();
|
||||
}
|
||||
|
||||
G4MTHepRandom * G4MTHepRandom::getTheGenerator()
|
||||
{
|
||||
if (!isActive) { isActive = G4MTHepRandom::createInstanceOnce(); }
|
||||
return theGenerator;
|
||||
}
|
||||
|
||||
CLHEP::HepRandomEngine * G4MTHepRandom::getTheEngine()
|
||||
{
|
||||
if (!isActive) { isActive = G4MTHepRandom::createInstanceOnce(); }
|
||||
return theEngine;
|
||||
}
|
||||
|
||||
void G4MTHepRandom::setTheEngine (CLHEP::HepRandomEngine* theNewEngine)
|
||||
{
|
||||
theEngine = theNewEngine;
|
||||
}
|
||||
|
||||
void G4MTHepRandom::saveEngineStatus( const char filename[] )
|
||||
{
|
||||
createInstance();
|
||||
theEngine->saveStatus( filename );
|
||||
}
|
||||
|
||||
void G4MTHepRandom::restoreEngineStatus( const char filename[] )
|
||||
{
|
||||
createInstance();
|
||||
theEngine->restoreStatus( filename );
|
||||
}
|
||||
|
||||
std::ostream& G4MTHepRandom::saveFullState ( std::ostream & os )
|
||||
{
|
||||
os << *getTheEngine();
|
||||
return os;
|
||||
}
|
||||
|
||||
std::istream& G4MTHepRandom::restoreFullState ( std::istream & is )
|
||||
{
|
||||
is >> *getTheEngine();
|
||||
return is;
|
||||
}
|
||||
|
||||
std::ostream& G4MTHepRandom::saveStaticRandomStates ( std::ostream & os )
|
||||
{
|
||||
return CLHEP::StaticRandomStates::save(os);
|
||||
}
|
||||
|
||||
std::istream& G4MTHepRandom::restoreStaticRandomStates ( std::istream & is )
|
||||
{
|
||||
return CLHEP::StaticRandomStates::restore(is);
|
||||
}
|
||||
|
||||
void G4MTHepRandom::showEngineStatus()
|
||||
{
|
||||
createInstance();
|
||||
theEngine->showStatus();
|
||||
}
|
||||
|
||||
G4int G4MTHepRandom::createInstance()
|
||||
{
|
||||
if (!isActive) { isActive = G4MTHepRandom::createInstanceOnce(); }
|
||||
if (theGenerator) return 1; // should always be true
|
||||
return 0;
|
||||
}
|
||||
|
||||
namespace {
|
||||
G4Mutex jamesrandom = G4MUTEX_INITIALIZER;
|
||||
}
|
||||
|
||||
G4int G4MTHepRandom::createInstanceOnce()
|
||||
{
|
||||
if (isActive) return isActive;
|
||||
isActive = 1;
|
||||
|
||||
|
||||
static G4ThreadLocal CLHEP::HepJamesRandom *defaultEngine = 0;
|
||||
if (!defaultEngine) {
|
||||
G4AutoLock l(&jamesrandom);
|
||||
defaultEngine = new CLHEP::HepJamesRandom;
|
||||
}
|
||||
|
||||
if ( !theEngine ) { theEngine = defaultEngine; }
|
||||
if ( !theGenerator ) { theGenerator = new G4MTHepRandom( theEngine ); }
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
#endif
|
||||
@@ -1,67 +0,0 @@
|
||||
//
|
||||
// ********************************************************************
|
||||
// * License and Disclaimer *
|
||||
// * *
|
||||
// * The Geant4 software is copyright of the Copyright Holders of *
|
||||
// * the Geant4 Collaboration. It is provided under the terms and *
|
||||
// * conditions of the Geant4 Software License, included in the file *
|
||||
// * LICENSE and available at http://cern.ch/geant4/license . These *
|
||||
// * include a list of copyright holders. *
|
||||
// * *
|
||||
// * Neither the authors of this software system, nor their employing *
|
||||
// * institutes,nor the agencies providing financial support for this *
|
||||
// * work make any representation or warranty, express or implied, *
|
||||
// * regarding this software system or assume any liability for its *
|
||||
// * use. Please see the license in the file LICENSE and URL above *
|
||||
// * for the full disclaimer and the limitation of liability. *
|
||||
// * *
|
||||
// * This code implementation is the result of the scientific and *
|
||||
// * technical work of the GEANT4 collaboration. *
|
||||
// * By using, copying, modifying or distributing the software (or *
|
||||
// * any work based on the software) you agree to acknowledge its *
|
||||
// * use in resulting scientific publications, and indicate your *
|
||||
// * acceptance of all terms of the Geant4 Software license. *
|
||||
// ********************************************************************
|
||||
//
|
||||
//
|
||||
// $Id:$
|
||||
//
|
||||
#if __clang__
|
||||
#if ((defined(G4MULTITHREADED) && !defined(G4USE_STD11)) || \
|
||||
!__has_feature(cxx_thread_local)) || !__has_feature(c_atomic)
|
||||
#define CLANG_NOSTDTLS
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#if (defined(G4MULTITHREADED) && \
|
||||
(!defined(G4USE_STD11) || (defined(CLANG_NOSTDTLS) || defined(__INTEL_COMPILER))))
|
||||
|
||||
#include "G4MTRandBit.hh"
|
||||
|
||||
G4MTRandBit::~G4MTRandBit()
|
||||
{
|
||||
}
|
||||
|
||||
// Static methods
|
||||
|
||||
G4int G4MTRandBit::shootBit()
|
||||
{
|
||||
G4double x = shoot();
|
||||
if (x > .5) {
|
||||
return 1;
|
||||
} else {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
G4int G4MTRandBit::shootBit(CLHEP::HepRandomEngine* engine)
|
||||
{
|
||||
G4double x = shoot(engine);
|
||||
if (x > .5) {
|
||||
return 1;
|
||||
} else {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
@@ -1,93 +0,0 @@
|
||||
//
|
||||
// ********************************************************************
|
||||
// * License and Disclaimer *
|
||||
// * *
|
||||
// * The Geant4 software is copyright of the Copyright Holders of *
|
||||
// * the Geant4 Collaboration. It is provided under the terms and *
|
||||
// * conditions of the Geant4 Software License, included in the file *
|
||||
// * LICENSE and available at http://cern.ch/geant4/license . These *
|
||||
// * include a list of copyright holders. *
|
||||
// * *
|
||||
// * Neither the authors of this software system, nor their employing *
|
||||
// * institutes,nor the agencies providing financial support for this *
|
||||
// * work make any representation or warranty, express or implied, *
|
||||
// * regarding this software system or assume any liability for its *
|
||||
// * use. Please see the license in the file LICENSE and URL above *
|
||||
// * for the full disclaimer and the limitation of liability. *
|
||||
// * *
|
||||
// * This code implementation is the result of the scientific and *
|
||||
// * technical work of the GEANT4 collaboration. *
|
||||
// * By using, copying, modifying or distributing the software (or *
|
||||
// * any work based on the software) you agree to acknowledge its *
|
||||
// * use in resulting scientific publications, and indicate your *
|
||||
// * acceptance of all terms of the Geant4 Software license. *
|
||||
// ********************************************************************
|
||||
//
|
||||
//
|
||||
// $Id:$
|
||||
//
|
||||
#if __clang__
|
||||
#if ((defined(G4MULTITHREADED) && !defined(G4USE_STD11)) || \
|
||||
!__has_feature(cxx_thread_local)) || !__has_feature(c_atomic)
|
||||
#define CLANG_NOSTDTLS
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#if (defined(G4MULTITHREADED) && \
|
||||
(!defined(G4USE_STD11) || (defined(CLANG_NOSTDTLS) || defined(__INTEL_COMPILER))))
|
||||
|
||||
#include "G4MTRandExponential.hh"
|
||||
|
||||
G4MTRandExponential::~G4MTRandExponential()
|
||||
{
|
||||
if ( deleteEngine ) delete localEngine;
|
||||
}
|
||||
|
||||
G4double G4MTRandExponential::operator()()
|
||||
{
|
||||
return fire( defaultMean );
|
||||
}
|
||||
|
||||
G4double G4MTRandExponential::operator()( G4double mean )
|
||||
{
|
||||
return fire( mean );
|
||||
}
|
||||
|
||||
G4double G4MTRandExponential::shoot()
|
||||
{
|
||||
return -std::log(G4MTHepRandom::getTheEngine()->flat());
|
||||
}
|
||||
|
||||
G4double G4MTRandExponential::shoot(G4double mean)
|
||||
{
|
||||
return -std::log(G4MTHepRandom::getTheEngine()->flat())*mean;
|
||||
}
|
||||
|
||||
void G4MTRandExponential::shootArray( const G4int size, G4double* vect,
|
||||
G4double mean )
|
||||
{
|
||||
for (G4int i=0; i<size; ++i)
|
||||
vect[i] = shoot(mean);
|
||||
}
|
||||
|
||||
void G4MTRandExponential::shootArray(CLHEP::HepRandomEngine* anEngine,
|
||||
const G4int size, G4double* vect, G4double mean )
|
||||
{
|
||||
for (G4int i=0; i<size; ++i)
|
||||
vect[i] = shoot(anEngine, mean);
|
||||
}
|
||||
|
||||
void G4MTRandExponential::fireArray( const G4int size, G4double* vect)
|
||||
{
|
||||
for (G4int i=0; i<size; ++i)
|
||||
vect[i] = fire( defaultMean );
|
||||
}
|
||||
|
||||
void G4MTRandExponential::fireArray( const G4int size, G4double* vect,
|
||||
G4double mean )
|
||||
{
|
||||
for (G4int i=0; i<size; ++i)
|
||||
vect[i] = fire( mean );
|
||||
}
|
||||
|
||||
#endif
|
||||
@@ -1,104 +0,0 @@
|
||||
//
|
||||
// ********************************************************************
|
||||
// * License and Disclaimer *
|
||||
// * *
|
||||
// * The Geant4 software is copyright of the Copyright Holders of *
|
||||
// * the Geant4 Collaboration. It is provided under the terms and *
|
||||
// * conditions of the Geant4 Software License, included in the file *
|
||||
// * LICENSE and available at http://cern.ch/geant4/license . These *
|
||||
// * include a list of copyright holders. *
|
||||
// * *
|
||||
// * Neither the authors of this software system, nor their employing *
|
||||
// * institutes,nor the agencies providing financial support for this *
|
||||
// * work make any representation or warranty, express or implied, *
|
||||
// * regarding this software system or assume any liability for its *
|
||||
// * use. Please see the license in the file LICENSE and URL above *
|
||||
// * for the full disclaimer and the limitation of liability. *
|
||||
// * *
|
||||
// * This code implementation is the result of the scientific and *
|
||||
// * technical work of the GEANT4 collaboration. *
|
||||
// * By using, copying, modifying or distributing the software (or *
|
||||
// * any work based on the software) you agree to acknowledge its *
|
||||
// * use in resulting scientific publications, and indicate your *
|
||||
// * acceptance of all terms of the Geant4 Software license. *
|
||||
// ********************************************************************
|
||||
//
|
||||
//
|
||||
// $Id:$
|
||||
//
|
||||
#if __clang__
|
||||
#if ((defined(G4MULTITHREADED) && !defined(G4USE_STD11)) || \
|
||||
!__has_feature(cxx_thread_local)) || !__has_feature(c_atomic)
|
||||
#define CLANG_NOSTDTLS
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#if (defined(G4MULTITHREADED) && \
|
||||
(!defined(G4USE_STD11) || (defined(CLANG_NOSTDTLS) || defined(__INTEL_COMPILER))))
|
||||
|
||||
#include "G4MTRandFlat.hh"
|
||||
|
||||
const G4int G4MTRandFlat::MSBBits= 15;
|
||||
const unsigned long G4MTRandFlat::MSB= 1ul<<G4MTRandFlat::MSBBits;
|
||||
G4ThreadLocal unsigned long G4MTRandFlat::staticRandomInt= 0;
|
||||
G4ThreadLocal unsigned long G4MTRandFlat::staticFirstUnusedBit= 0;
|
||||
|
||||
G4MTRandFlat::~G4MTRandFlat()
|
||||
{
|
||||
if ( deleteEngine ) delete localEngine;
|
||||
}
|
||||
|
||||
G4double G4MTRandFlat::operator()()
|
||||
{
|
||||
return fire( defaultA, defaultB );
|
||||
}
|
||||
|
||||
G4double G4MTRandFlat::operator()( G4double w )
|
||||
{
|
||||
return fire( w );
|
||||
}
|
||||
|
||||
G4double G4MTRandFlat::operator()( G4double a, G4double b )
|
||||
{
|
||||
return fire( a, b );
|
||||
}
|
||||
|
||||
G4double G4MTRandFlat::shoot()
|
||||
{
|
||||
return G4MTHepRandom::getTheEngine()->flat();
|
||||
}
|
||||
|
||||
void G4MTRandFlat::shootArray(const G4int size, G4double* vect)
|
||||
{
|
||||
G4MTHepRandom::getTheEngine()->flatArray(size,vect);
|
||||
}
|
||||
|
||||
void G4MTRandFlat::shootArray( const G4int size, G4double* vect,
|
||||
G4double lx, G4double dx )
|
||||
{
|
||||
for (G4int i=0; i<size; ++i)
|
||||
vect[i] = shoot(lx,dx);
|
||||
}
|
||||
|
||||
void G4MTRandFlat::shootArray( CLHEP::HepRandomEngine* anEngine,
|
||||
const G4int size, G4double* vect,
|
||||
G4double lx, G4double dx )
|
||||
{
|
||||
for (G4int i=0; i<size; ++i)
|
||||
vect[i] = shoot(anEngine,lx,dx);
|
||||
}
|
||||
|
||||
void G4MTRandFlat::fireArray( const G4int size, G4double* vect)
|
||||
{
|
||||
for (G4int i=0; i<size; ++i)
|
||||
vect[i] = fire( defaultA, defaultB );
|
||||
}
|
||||
|
||||
void G4MTRandFlat::fireArray( const G4int size, G4double* vect,
|
||||
G4double lx, G4double dx )
|
||||
{
|
||||
for (G4int i=0; i<size; ++i)
|
||||
vect[i] = fire( lx, dx );
|
||||
}
|
||||
|
||||
#endif
|
||||
@@ -1,247 +0,0 @@
|
||||
//
|
||||
// ********************************************************************
|
||||
// * License and Disclaimer *
|
||||
// * *
|
||||
// * The Geant4 software is copyright of the Copyright Holders of *
|
||||
// * the Geant4 Collaboration. It is provided under the terms and *
|
||||
// * conditions of the Geant4 Software License, included in the file *
|
||||
// * LICENSE and available at http://cern.ch/geant4/license . These *
|
||||
// * include a list of copyright holders. *
|
||||
// * *
|
||||
// * Neither the authors of this software system, nor their employing *
|
||||
// * institutes,nor the agencies providing financial support for this *
|
||||
// * work make any representation or warranty, express or implied, *
|
||||
// * regarding this software system or assume any liability for its *
|
||||
// * use. Please see the license in the file LICENSE and URL above *
|
||||
// * for the full disclaimer and the limitation of liability. *
|
||||
// * *
|
||||
// * This code implementation is the result of the scientific and *
|
||||
// * technical work of the GEANT4 collaboration. *
|
||||
// * By using, copying, modifying or distributing the software (or *
|
||||
// * any work based on the software) you agree to acknowledge its *
|
||||
// * use in resulting scientific publications, and indicate your *
|
||||
// * acceptance of all terms of the Geant4 Software license. *
|
||||
// ********************************************************************
|
||||
//
|
||||
//
|
||||
// $Id:$
|
||||
//
|
||||
#if __clang__
|
||||
#if ((defined(G4MULTITHREADED) && !defined(G4USE_STD11)) || \
|
||||
!__has_feature(cxx_thread_local)) || !__has_feature(c_atomic)
|
||||
#define CLANG_NOSTDTLS
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#if (defined(G4MULTITHREADED) && \
|
||||
(!defined(G4USE_STD11) || (defined(CLANG_NOSTDTLS) || defined(__INTEL_COMPILER))))
|
||||
|
||||
#include <cmath> // for log()
|
||||
|
||||
#include "G4MTRandGamma.hh"
|
||||
|
||||
G4MTRandGamma::~G4MTRandGamma() {
|
||||
if ( deleteEngine ) delete localEngine;
|
||||
}
|
||||
|
||||
G4double G4MTRandGamma::shoot( CLHEP::HepRandomEngine *anEngine, G4double k,
|
||||
G4double lambda ) {
|
||||
return genGamma( anEngine, k, lambda );
|
||||
}
|
||||
|
||||
G4double G4MTRandGamma::shoot( G4double k, G4double lambda ) {
|
||||
CLHEP::HepRandomEngine *anEngine = G4MTHepRandom::getTheEngine();
|
||||
return genGamma( anEngine, k, lambda );
|
||||
}
|
||||
|
||||
G4double G4MTRandGamma::fire( G4double k, G4double lambda ) {
|
||||
return genGamma( localEngine, k, lambda );
|
||||
}
|
||||
|
||||
void G4MTRandGamma::shootArray( const G4int size, G4double* vect,
|
||||
G4double k, G4double lambda )
|
||||
{
|
||||
G4int i;
|
||||
|
||||
for (i=0; i<size; ++i)
|
||||
vect[i] = shoot(k,lambda);
|
||||
}
|
||||
|
||||
void G4MTRandGamma::shootArray( CLHEP::HepRandomEngine* anEngine,
|
||||
const G4int size, G4double* vect,
|
||||
G4double k, G4double lambda )
|
||||
{
|
||||
G4int i;
|
||||
|
||||
for (i=0; i<size; ++i)
|
||||
vect[i] = shoot(anEngine,k,lambda);
|
||||
}
|
||||
|
||||
void G4MTRandGamma::fireArray( const G4int size, G4double* vect)
|
||||
{
|
||||
G4int i;
|
||||
|
||||
for (i=0; i<size; ++i)
|
||||
vect[i] = fire(defaultK,defaultLambda);
|
||||
}
|
||||
|
||||
void G4MTRandGamma::fireArray( const G4int size, G4double* vect,
|
||||
G4double k, G4double lambda )
|
||||
{
|
||||
G4int i;
|
||||
|
||||
for (i=0; i<size; ++i)
|
||||
vect[i] = fire(k,lambda);
|
||||
}
|
||||
|
||||
G4double G4MTRandGamma::genGamma( CLHEP::HepRandomEngine *anEngine,
|
||||
G4double a, G4double lambda ) {
|
||||
/*************************************************************************
|
||||
* Gamma Distribution - Rejection algorithm gs combined with *
|
||||
* Acceptance complement method gd *
|
||||
*************************************************************************/
|
||||
|
||||
static G4ThreadLocal G4double aa = -1.0, aaa = -1.0, b, c, d, e, r, s, si, ss, q0,
|
||||
q1 = 0.0416666664, q2 = 0.0208333723, q3 = 0.0079849875,
|
||||
q4 = 0.0015746717, q5 = -0.0003349403, q6 = 0.0003340332,
|
||||
q7 = 0.0006053049, q8 = -0.0004701849, q9 = 0.0001710320,
|
||||
a1 = 0.333333333, a2 = -0.249999949, a3 = 0.199999867,
|
||||
a4 =-0.166677482, a5 = 0.142873973, a6 =-0.124385581,
|
||||
a7 = 0.110368310, a8 = -0.112750886, a9 = 0.104089866,
|
||||
e1 = 1.000000000, e2 = 0.499999994, e3 = 0.166666848,
|
||||
e4 = 0.041664508, e5 = 0.008345522, e6 = 0.001353826,
|
||||
e7 = 0.000247453;
|
||||
|
||||
G4double gds,p,q,t,sign_u,u,v,w,x;
|
||||
G4double v1,v2,v12;
|
||||
|
||||
// Check for invalid input values
|
||||
|
||||
if( a <= 0.0 ) return (-1.0);
|
||||
if( lambda <= 0.0 ) return (-1.0);
|
||||
|
||||
if (a < 1.0)
|
||||
{ // CASE A: Acceptance rejection algorithm gs
|
||||
b = 1.0 + 0.36788794412 * a; // Step 1
|
||||
for(;;)
|
||||
{
|
||||
p = b * anEngine->flat();
|
||||
if (p <= 1.0)
|
||||
{ // Step 2. Case gds <= 1
|
||||
gds = std::exp(std::log(p) / a);
|
||||
if (std::log(anEngine->flat()) <= -gds) return(gds/lambda);
|
||||
}
|
||||
else
|
||||
{ // Step 3. Case gds > 1
|
||||
gds = - std::log ((b - p) / a);
|
||||
if (std::log(anEngine->flat()) <= ((a - 1.0) * std::log(gds))) return(gds/lambda);
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{ // CASE B: Acceptance complement algorithm gd
|
||||
if (a != aa)
|
||||
{ // Step 1. Preparations
|
||||
aa = a;
|
||||
ss = a - 0.5;
|
||||
s = std::sqrt(ss);
|
||||
d = 5.656854249 - 12.0 * s;
|
||||
}
|
||||
// Step 2. Normal deviate
|
||||
do {
|
||||
v1 = 2.0 * anEngine->flat() - 1.0;
|
||||
v2 = 2.0 * anEngine->flat() - 1.0;
|
||||
v12 = v1*v1 + v2*v2;
|
||||
} while ( v12 > 1.0 );
|
||||
t = v1*std::sqrt(-2.0*std::log(v12)/v12);
|
||||
x = s + 0.5 * t;
|
||||
gds = x * x;
|
||||
if (t >= 0.0) return(gds/lambda); // Immediate acceptance
|
||||
|
||||
u = anEngine->flat(); // Step 3. Uniform random number
|
||||
if (d * u <= t * t * t) return(gds/lambda); // Squeeze acceptance
|
||||
|
||||
if (a != aaa)
|
||||
{ // Step 4. Set-up for hat case
|
||||
aaa = a;
|
||||
r = 1.0 / a;
|
||||
q0 = ((((((((q9 * r + q8) * r + q7) * r + q6) * r + q5) * r + q4) *
|
||||
r + q3) * r + q2) * r + q1) * r;
|
||||
if (a > 3.686)
|
||||
{
|
||||
if (a > 13.022)
|
||||
{
|
||||
b = 1.77;
|
||||
si = 0.75;
|
||||
c = 0.1515 / s;
|
||||
}
|
||||
else
|
||||
{
|
||||
b = 1.654 + 0.0076 * ss;
|
||||
si = 1.68 / s + 0.275;
|
||||
c = 0.062 / s + 0.024;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
b = 0.463 + s - 0.178 * ss;
|
||||
si = 1.235;
|
||||
c = 0.195 / s - 0.079 + 0.016 * s;
|
||||
}
|
||||
}
|
||||
if (x > 0.0) // Step 5. Calculation of q
|
||||
{
|
||||
v = t / (s + s); // Step 6.
|
||||
if (std::fabs(v) > 0.25)
|
||||
{
|
||||
q = q0 - s * t + 0.25 * t * t + (ss + ss) * std::log(1.0 + v);
|
||||
}
|
||||
else
|
||||
{
|
||||
q = q0 + 0.5 * t * t * ((((((((a9 * v + a8) * v + a7) * v + a6) *
|
||||
v + a5) * v + a4) * v + a3) * v + a2) * v + a1) * v;
|
||||
} // Step 7. Quotient acceptance
|
||||
if (std::log(1.0 - u) <= q) return(gds/lambda);
|
||||
}
|
||||
|
||||
for(;;)
|
||||
{ // Step 8. Double exponential deviate t
|
||||
do
|
||||
{
|
||||
e = -std::log(anEngine->flat());
|
||||
u = anEngine->flat();
|
||||
u = u + u - 1.0;
|
||||
sign_u = (u > 0)? 1.0 : -1.0;
|
||||
t = b + (e * si) * sign_u;
|
||||
}
|
||||
while (t <= -0.71874483771719); // Step 9. Rejection of t
|
||||
v = t / (s + s); // Step 10. New q(t)
|
||||
if (std::fabs(v) > 0.25)
|
||||
{
|
||||
q = q0 - s * t + 0.25 * t * t + (ss + ss) * std::log(1.0 + v);
|
||||
}
|
||||
else
|
||||
{
|
||||
q = q0 + 0.5 * t * t * ((((((((a9 * v + a8) * v + a7) * v + a6) *
|
||||
v + a5) * v + a4) * v + a3) * v + a2) * v + a1) * v;
|
||||
}
|
||||
if (q <= 0.0) continue; // Step 11.
|
||||
if (q > 0.5)
|
||||
{
|
||||
w = std::exp(q) - 1.0;
|
||||
}
|
||||
else
|
||||
{
|
||||
w = ((((((e7 * q + e6) * q + e5) * q + e4) * q + e3) * q + e2) *
|
||||
q + e1) * q;
|
||||
} // Step 12. Hat acceptance
|
||||
if ( c * u * sign_u <= w * std::exp(e - 0.5 * t * t))
|
||||
{
|
||||
x = s + 0.5 * t;
|
||||
return(x*x/lambda);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
@@ -1,171 +0,0 @@
|
||||
//
|
||||
// ********************************************************************
|
||||
// * License and Disclaimer *
|
||||
// * *
|
||||
// * The Geant4 software is copyright of the Copyright Holders of *
|
||||
// * the Geant4 Collaboration. It is provided under the terms and *
|
||||
// * conditions of the Geant4 Software License, included in the file *
|
||||
// * LICENSE and available at http://cern.ch/geant4/license . These *
|
||||
// * include a list of copyright holders. *
|
||||
// * *
|
||||
// * Neither the authors of this software system, nor their employing *
|
||||
// * institutes,nor the agencies providing financial support for this *
|
||||
// * work make any representation or warranty, express or implied, *
|
||||
// * regarding this software system or assume any liability for its *
|
||||
// * use. Please see the license in the file LICENSE and URL above *
|
||||
// * for the full disclaimer and the limitation of liability. *
|
||||
// * *
|
||||
// * This code implementation is the result of the scientific and *
|
||||
// * technical work of the GEANT4 collaboration. *
|
||||
// * By using, copying, modifying or distributing the software (or *
|
||||
// * any work based on the software) you agree to acknowledge its *
|
||||
// * use in resulting scientific publications, and indicate your *
|
||||
// * acceptance of all terms of the Geant4 Software license. *
|
||||
// ********************************************************************
|
||||
//
|
||||
//
|
||||
// $Id:$
|
||||
//
|
||||
#if __clang__
|
||||
#if ((defined(G4MULTITHREADED) && !defined(G4USE_STD11)) || \
|
||||
!__has_feature(cxx_thread_local)) || !__has_feature(c_atomic)
|
||||
#define CLANG_NOSTDTLS
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#if (defined(G4MULTITHREADED) && \
|
||||
(!defined(G4USE_STD11) || (defined(CLANG_NOSTDTLS) || defined(__INTEL_COMPILER))))
|
||||
|
||||
#include <cmath> // for log()
|
||||
|
||||
#include "G4MTRandGauss.hh"
|
||||
|
||||
// Initialisation of static data
|
||||
G4ThreadLocal G4bool G4MTRandGauss::set_st = false;
|
||||
G4ThreadLocal G4double G4MTRandGauss::nextGauss_st = 0.0;
|
||||
|
||||
G4MTRandGauss::~G4MTRandGauss()
|
||||
{
|
||||
if ( deleteEngine ) delete localEngine;
|
||||
}
|
||||
|
||||
G4double G4MTRandGauss::operator()()
|
||||
{
|
||||
return fire( defaultMean, defaultStdDev );
|
||||
}
|
||||
|
||||
G4double G4MTRandGauss::operator()( G4double mean, G4double stdDev )
|
||||
{
|
||||
return fire( mean, stdDev );
|
||||
}
|
||||
|
||||
G4double G4MTRandGauss::shoot()
|
||||
{
|
||||
// Gaussian random numbers are generated two at the time, so every other
|
||||
// time this is called we just return a number generated the time before.
|
||||
|
||||
if ( getFlag() ) {
|
||||
setFlag(false);
|
||||
G4double x = getVal();
|
||||
return x;
|
||||
// return getVal();
|
||||
}
|
||||
|
||||
G4double r;
|
||||
G4double v1,v2,fac,val;
|
||||
CLHEP::HepRandomEngine* anEngine = G4MTHepRandom::getTheEngine();
|
||||
|
||||
do {
|
||||
v1 = 2.0 * anEngine->flat() - 1.0;
|
||||
v2 = 2.0 * anEngine->flat() - 1.0;
|
||||
r = v1*v1 + v2*v2;
|
||||
} while ( r > 1.0 );
|
||||
|
||||
fac = std::sqrt(-2.0*std::log(r)/r);
|
||||
val = v1*fac;
|
||||
setVal(val);
|
||||
setFlag(true);
|
||||
return v2*fac;
|
||||
}
|
||||
|
||||
void G4MTRandGauss::shootArray( const G4int size, G4double* vect,
|
||||
G4double mean, G4double stdDev )
|
||||
{
|
||||
for (G4int i=0; i<size; ++i)
|
||||
vect[i] = shoot(mean,stdDev);
|
||||
}
|
||||
|
||||
G4double G4MTRandGauss::shoot( CLHEP::HepRandomEngine* anEngine )
|
||||
{
|
||||
// Gaussian random numbers are generated two at the time, so every other
|
||||
// time this is called we just return a number generated the time before.
|
||||
|
||||
if ( getFlag() ) {
|
||||
setFlag(false);
|
||||
return getVal();
|
||||
}
|
||||
|
||||
G4double r;
|
||||
G4double v1,v2,fac,val;
|
||||
|
||||
do {
|
||||
v1 = 2.0 * anEngine->flat() - 1.0;
|
||||
v2 = 2.0 * anEngine->flat() - 1.0;
|
||||
r = v1*v1 + v2*v2;
|
||||
} while ( r > 1.0 );
|
||||
|
||||
fac = std::sqrt( -2.0*std::log(r)/r);
|
||||
val = v1*fac;
|
||||
setVal(val);
|
||||
setFlag(true);
|
||||
return v2*fac;
|
||||
}
|
||||
|
||||
void G4MTRandGauss::shootArray( CLHEP::HepRandomEngine* anEngine,
|
||||
const G4int size, G4double* vect,
|
||||
G4double mean, G4double stdDev )
|
||||
{
|
||||
for (G4int i=0; i<size; ++i)
|
||||
vect[i] = shoot(anEngine,mean,stdDev);
|
||||
}
|
||||
|
||||
G4double G4MTRandGauss::normal()
|
||||
{
|
||||
// Gaussian random numbers are generated two at the time, so every other
|
||||
// time this is called we just return a number generated the time before.
|
||||
|
||||
if ( set ) {
|
||||
set = false;
|
||||
return nextGauss;
|
||||
}
|
||||
|
||||
G4double r;
|
||||
G4double v1,v2,fac,val;
|
||||
|
||||
do {
|
||||
v1 = 2.0 * localEngine->flat() - 1.0;
|
||||
v2 = 2.0 * localEngine->flat() - 1.0;
|
||||
r = v1*v1 + v2*v2;
|
||||
} while ( r > 1.0 );
|
||||
|
||||
fac = std::sqrt(-2.0*std::log(r)/r);
|
||||
val = v1*fac;
|
||||
nextGauss = val;
|
||||
set = true;
|
||||
return v2*fac;
|
||||
}
|
||||
|
||||
void G4MTRandGauss::fireArray( const G4int size, G4double* vect)
|
||||
{
|
||||
for (G4int i=0; i<size; ++i)
|
||||
vect[i] = fire( defaultMean, defaultStdDev );
|
||||
}
|
||||
|
||||
void G4MTRandGauss::fireArray( const G4int size, G4double* vect,
|
||||
G4double mean, G4double stdDev )
|
||||
{
|
||||
for (G4int i=0; i<size; ++i)
|
||||
vect[i] = fire( mean, stdDev );
|
||||
}
|
||||
|
||||
#endif
|
||||
@@ -1,194 +0,0 @@
|
||||
//
|
||||
// ********************************************************************
|
||||
// * License and Disclaimer *
|
||||
// * *
|
||||
// * The Geant4 software is copyright of the Copyright Holders of *
|
||||
// * the Geant4 Collaboration. It is provided under the terms and *
|
||||
// * conditions of the Geant4 Software License, included in the file *
|
||||
// * LICENSE and available at http://cern.ch/geant4/license . These *
|
||||
// * include a list of copyright holders. *
|
||||
// * *
|
||||
// * Neither the authors of this software system, nor their employing *
|
||||
// * institutes,nor the agencies providing financial support for this *
|
||||
// * work make any representation or warranty, express or implied, *
|
||||
// * regarding this software system or assume any liability for its *
|
||||
// * use. Please see the license in the file LICENSE and URL above *
|
||||
// * for the full disclaimer and the limitation of liability. *
|
||||
// * *
|
||||
// * This code implementation is the result of the scientific and *
|
||||
// * technical work of the GEANT4 collaboration. *
|
||||
// * By using, copying, modifying or distributing the software (or *
|
||||
// * any work based on the software) you agree to acknowledge its *
|
||||
// * use in resulting scientific publications, and indicate your *
|
||||
// * acceptance of all terms of the Geant4 Software license. *
|
||||
// ********************************************************************
|
||||
//
|
||||
//
|
||||
// $Id:$
|
||||
//
|
||||
#if __clang__
|
||||
#if ((defined(G4MULTITHREADED) && !defined(G4USE_STD11)) || \
|
||||
!__has_feature(cxx_thread_local)) || !__has_feature(c_atomic)
|
||||
#define CLANG_NOSTDTLS
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#if (defined(G4MULTITHREADED) && \
|
||||
(!defined(G4USE_STD11) || (defined(CLANG_NOSTDTLS) || defined(__INTEL_COMPILER))))
|
||||
|
||||
#include <cmath> // for log()
|
||||
#include <CLHEP/Units/PhysicalConstants.h>
|
||||
|
||||
#include "G4MTRandGaussQ.hh"
|
||||
|
||||
G4MTRandGaussQ::~G4MTRandGaussQ()
|
||||
{
|
||||
}
|
||||
|
||||
G4MTRandGaussQ::G4MTRandGaussQ(const G4MTRandGaussQ& right)
|
||||
: G4MTRandGauss(right)
|
||||
{
|
||||
}
|
||||
|
||||
G4double G4MTRandGaussQ::operator()()
|
||||
{
|
||||
return transformQuick(localEngine->flat()) * defaultStdDev + defaultMean;
|
||||
}
|
||||
|
||||
G4double G4MTRandGaussQ::operator()( G4double mean, G4double stdDev )
|
||||
{
|
||||
return transformQuick(localEngine->flat()) * stdDev + mean;
|
||||
}
|
||||
|
||||
void G4MTRandGaussQ::shootArray( const G4int size, G4double* vect,
|
||||
G4double mean, G4double stdDev )
|
||||
{
|
||||
for (G4int i=0; i<size; ++i)
|
||||
vect[i] = shoot(mean,stdDev);
|
||||
}
|
||||
|
||||
void G4MTRandGaussQ::shootArray( CLHEP::HepRandomEngine* anEngine,
|
||||
const G4int size, G4double* vect,
|
||||
G4double mean, G4double stdDev )
|
||||
{
|
||||
for (G4int i=0; i<size; ++i)
|
||||
vect[i] = shoot(anEngine,mean,stdDev);
|
||||
}
|
||||
|
||||
void G4MTRandGaussQ::fireArray( const G4int size, G4double* vect)
|
||||
{
|
||||
for (G4int i=0; i<size; ++i)
|
||||
vect[i] = fire( defaultMean, defaultStdDev );
|
||||
}
|
||||
|
||||
void G4MTRandGaussQ::fireArray( const G4int size, G4double* vect,
|
||||
G4double mean, G4double stdDev )
|
||||
{
|
||||
for (G4int i=0; i<size; ++i)
|
||||
vect[i] = fire( mean, stdDev );
|
||||
}
|
||||
|
||||
//
|
||||
// Table of errInts, for use with transform(r) and quickTransform(r)
|
||||
//
|
||||
|
||||
// Since all these are this is static to this compilation unit only, the
|
||||
// info is establised a priori and not at each invocation.
|
||||
|
||||
// The main data is of course the gaussQTables table; the rest is all
|
||||
// bookkeeping to know what the tables mean.
|
||||
|
||||
#define Table0size 250
|
||||
#define Table1size 1000
|
||||
#define TableSize (Table0size+Table1size)
|
||||
|
||||
#define Table0step (2.0E-6)
|
||||
#define Table1step (5.0E-4)
|
||||
|
||||
#define Table0scale (1.0/Table1step)
|
||||
|
||||
#define Table0offset 0
|
||||
#define Table1offset (Table0size)
|
||||
|
||||
// Here comes the big (5K bytes) table, kept in a file ---
|
||||
|
||||
static const G4float gaussTables [TableSize] = {
|
||||
#include "gaussQTables.cdat"
|
||||
};
|
||||
|
||||
G4double G4MTRandGaussQ::transformQuick (G4double r)
|
||||
{
|
||||
G4double sign = +1.0; // We always compute a negative number of
|
||||
// sigmas. For r > 0 we will multiply by
|
||||
// sign = -1 to return a positive number.
|
||||
if ( r > .5 ) {
|
||||
r = 1-r;
|
||||
sign = -1.0;
|
||||
}
|
||||
|
||||
G4int index;
|
||||
G4double dx;
|
||||
|
||||
if ( r >= Table1step ) {
|
||||
index = G4int((Table1size<<1) * r); // 1 to Table1size
|
||||
if (index == Table1size) return 0.0;
|
||||
dx = (Table1size<<1) * r - index; // fraction of way to next bin
|
||||
index += Table1offset-1;
|
||||
} else if ( r > Table0step ) {
|
||||
G4double rr = r * Table0scale;
|
||||
index = G4int(Table0size * rr); // 1 to Table0size
|
||||
dx = Table0size * rr - index; // fraction of way to next bin
|
||||
index += Table0offset-1;
|
||||
} else { // r <= Table0step - not in tables
|
||||
return sign*transformSmall(r);
|
||||
}
|
||||
|
||||
G4double y0 = gaussTables [index++];
|
||||
G4double y1 = gaussTables [index];
|
||||
|
||||
return (G4float) (sign * ( y1 * dx + y0 * (1.0-dx) ));
|
||||
|
||||
} // transformQuick()
|
||||
|
||||
G4double G4MTRandGaussQ::transformSmall (G4double r)
|
||||
{
|
||||
// Solve for -v in the asymtotic formula
|
||||
//
|
||||
// errInt (-v) = exp(-v*v/2) 1 1*3 1*3*5
|
||||
// ------------ * (1 - ---- + ---- - ----- + ... )
|
||||
// v*sqrt(2*pi) v**2 v**4 v**6
|
||||
|
||||
// The value of r (=errInt(-v)) supplied is going to less than 2.0E-13,
|
||||
// which is such that v < -7.25. Since the value of r is meaningful only
|
||||
// to an absolute error of 1E-16 (double precision accuracy for a number
|
||||
// which on the high side could be of the form 1-epsilon), computing
|
||||
// v to more than 3-4 digits of accuracy is suspect; however, to ensure
|
||||
// smoothness with the table generator (which uses quite a few terms) we
|
||||
// also use terms up to 1*3*5* ... *13/v**14, and insist on accuracy of
|
||||
// solution at the level of 1.0e-7.
|
||||
|
||||
// This routine is called less than one time in a million firings, so
|
||||
// speed is of no concern. As a matter of technique, we terminate the
|
||||
// iterations in case they would be infinite, but this should not happen.
|
||||
|
||||
G4double eps = 1.0e-7;
|
||||
G4double guess = 7.5;
|
||||
G4double v;
|
||||
|
||||
for ( G4int i = 1; i < 50; i++ ) {
|
||||
G4double vn2 = 1.0/(guess*guess);
|
||||
G4double s = -13*11*9*7*5*3 * vn2*vn2*vn2*vn2*vn2*vn2*vn2;
|
||||
s += 11*9*7*5*3 * vn2*vn2*vn2*vn2*vn2*vn2;
|
||||
s += -9*7*5*3 * vn2*vn2*vn2*vn2*vn2;
|
||||
s += 7*5*3 * vn2*vn2*vn2*vn2;
|
||||
s += -5*3 * vn2*vn2*vn2;
|
||||
s += 3 * vn2*vn2 - vn2 + 1.0;
|
||||
v = std::sqrt ( 2.0 * std::log ( s / (r*guess*std::sqrt(CLHEP::twopi)) ) );
|
||||
if ( std::fabs(v-guess) < eps ) break;
|
||||
guess = v;
|
||||
}
|
||||
return -v;
|
||||
|
||||
} // transformSmall()
|
||||
|
||||
#endif
|
||||
@@ -1,226 +0,0 @@
|
||||
//
|
||||
// ********************************************************************
|
||||
// * License and Disclaimer *
|
||||
// * *
|
||||
// * The Geant4 software is copyright of the Copyright Holders of *
|
||||
// * the Geant4 Collaboration. It is provided under the terms and *
|
||||
// * conditions of the Geant4 Software License, included in the file *
|
||||
// * LICENSE and available at http://cern.ch/geant4/license . These *
|
||||
// * include a list of copyright holders. *
|
||||
// * *
|
||||
// * Neither the authors of this software system, nor their employing *
|
||||
// * institutes,nor the agencies providing financial support for this *
|
||||
// * work make any representation or warranty, express or implied, *
|
||||
// * regarding this software system or assume any liability for its *
|
||||
// * use. Please see the license in the file LICENSE and URL above *
|
||||
// * for the full disclaimer and the limitation of liability. *
|
||||
// * *
|
||||
// * This code implementation is the result of the scientific and *
|
||||
// * technical work of the GEANT4 collaboration. *
|
||||
// * By using, copying, modifying or distributing the software (or *
|
||||
// * any work based on the software) you agree to acknowledge its *
|
||||
// * use in resulting scientific publications, and indicate your *
|
||||
// * acceptance of all terms of the Geant4 Software license. *
|
||||
// ********************************************************************
|
||||
//
|
||||
//
|
||||
// $Id:$
|
||||
//
|
||||
#if __clang__
|
||||
#if ((defined(G4MULTITHREADED) && !defined(G4USE_STD11)) || \
|
||||
!__has_feature(cxx_thread_local)) || !__has_feature(c_atomic)
|
||||
#define CLANG_NOSTDTLS
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#if (defined(G4MULTITHREADED) && \
|
||||
(!defined(G4USE_STD11) || (defined(CLANG_NOSTDTLS) || defined(__INTEL_COMPILER))))
|
||||
|
||||
#include "G4MTRandGeneral.hh"
|
||||
|
||||
//////////////////
|
||||
// Constructors
|
||||
//////////////////
|
||||
|
||||
G4MTRandGeneral::G4MTRandGeneral( const G4double* aProbFunc,
|
||||
G4int theProbSize,
|
||||
G4int IntType )
|
||||
: deleteEngine(false),
|
||||
nBins(theProbSize),
|
||||
InterpolationType(IntType)
|
||||
{
|
||||
localEngine = G4MTHepRandom::getTheEngine();
|
||||
prepareTable(aProbFunc);
|
||||
}
|
||||
|
||||
G4MTRandGeneral::G4MTRandGeneral(CLHEP::HepRandomEngine& anEngine,
|
||||
const G4double* aProbFunc,
|
||||
G4int theProbSize,
|
||||
G4int IntType )
|
||||
: localEngine(&anEngine),
|
||||
deleteEngine(false),
|
||||
nBins(theProbSize),
|
||||
InterpolationType(IntType)
|
||||
{
|
||||
prepareTable(aProbFunc);
|
||||
}
|
||||
|
||||
G4MTRandGeneral::G4MTRandGeneral(CLHEP::HepRandomEngine* anEngine,
|
||||
const G4double* aProbFunc,
|
||||
G4int theProbSize,
|
||||
G4int IntType )
|
||||
: localEngine(anEngine),
|
||||
deleteEngine(true),
|
||||
nBins(theProbSize),
|
||||
InterpolationType(IntType)
|
||||
{
|
||||
prepareTable(aProbFunc);
|
||||
}
|
||||
|
||||
void G4MTRandGeneral::prepareTable(const G4double* aProbFunc)
|
||||
{
|
||||
//
|
||||
// Private method called only by constructors. Prepares theIntegralPdf.
|
||||
//
|
||||
if (nBins < 1) {
|
||||
std::cerr <<
|
||||
"G4MTRandGeneral constructed with no bins - will use flat distribution\n";
|
||||
useFlatDistribution();
|
||||
return;
|
||||
}
|
||||
|
||||
theIntegralPdf.resize(nBins+1);
|
||||
theIntegralPdf[0] = 0;
|
||||
G4int ptn;
|
||||
G4double weight;
|
||||
|
||||
for ( ptn = 0; ptn<nBins; ++ptn ) {
|
||||
weight = aProbFunc[ptn];
|
||||
if ( weight < 0 ) {
|
||||
// We can't stomach negative bin contents, they invalidate the
|
||||
// search algorithm when the distribution is fired.
|
||||
std::cerr <<
|
||||
"G4MTRandGeneral constructed with negative-weight bin " << ptn <<
|
||||
" = " << weight << " \n -- will substitute 0 weight \n";
|
||||
weight = 0;
|
||||
}
|
||||
// std::cout << ptn << " " << weight << " " << theIntegralPdf[ptn] << "\n";
|
||||
theIntegralPdf[ptn+1] = theIntegralPdf[ptn] + weight;
|
||||
}
|
||||
|
||||
if ( theIntegralPdf[nBins] <= 0 ) {
|
||||
std::cerr <<
|
||||
"G4MTRandGeneral constructed nothing in bins - will use flat distribution\n";
|
||||
useFlatDistribution();
|
||||
return;
|
||||
}
|
||||
|
||||
for ( ptn = 0; ptn < nBins+1; ++ptn ) {
|
||||
theIntegralPdf[ptn] /= theIntegralPdf[nBins];
|
||||
// std::cout << ptn << " " << theIntegralPdf[ptn] << "\n";
|
||||
}
|
||||
|
||||
// And another useful variable is ...
|
||||
oneOverNbins = 1.0 / nBins;
|
||||
|
||||
// One last chore:
|
||||
|
||||
if ( (InterpolationType != 0) && (InterpolationType != 1) ) {
|
||||
std::cerr <<
|
||||
"G4MTRandGeneral does not recognize IntType " << InterpolationType
|
||||
<< "\n Will use type 0 (continuous linear interpolation \n";
|
||||
InterpolationType = 0;
|
||||
}
|
||||
|
||||
} // prepareTable()
|
||||
|
||||
void G4MTRandGeneral::useFlatDistribution()
|
||||
{
|
||||
//
|
||||
// Private method called only by prepareTables in case of user error.
|
||||
//
|
||||
nBins = 1;
|
||||
theIntegralPdf.resize(2);
|
||||
theIntegralPdf[0] = 0;
|
||||
theIntegralPdf[1] = 1;
|
||||
oneOverNbins = 1.0;
|
||||
return;
|
||||
|
||||
} // UseFlatDistribution()
|
||||
|
||||
//////////////////
|
||||
// Destructor
|
||||
//////////////////
|
||||
|
||||
G4MTRandGeneral::~G4MTRandGeneral()
|
||||
{
|
||||
if ( deleteEngine ) delete localEngine;
|
||||
}
|
||||
|
||||
|
||||
///////////////////
|
||||
// mapRandom(rand)
|
||||
///////////////////
|
||||
|
||||
G4double G4MTRandGeneral::mapRandom(G4double rand) const
|
||||
{
|
||||
//
|
||||
// Private method to take the random (however it is created) and map it
|
||||
// according to the distribution.
|
||||
//
|
||||
G4int nbelow = 0; // largest k such that I[k] is known to be <= rand
|
||||
G4int nabove = nBins; // largest k such that I[k] is known to be > rand
|
||||
G4int middle;
|
||||
|
||||
while (nabove > nbelow+1) {
|
||||
middle = (nabove + nbelow+1)>>1;
|
||||
if (rand >= theIntegralPdf[middle]) {
|
||||
nbelow = middle;
|
||||
} else {
|
||||
nabove = middle;
|
||||
}
|
||||
} // after this loop, nabove is always nbelow+1 and they straddle rad:
|
||||
// assert ( nabove == nbelow+1 );
|
||||
// assert ( theIntegralPdf[nbelow] <= rand );
|
||||
// assert ( theIntegralPdf[nabove] >= rand );
|
||||
// If a defective engine produces rand=1, that will
|
||||
// still give sensible results so we relax the > rand assertion
|
||||
|
||||
if ( InterpolationType == 1 ) {
|
||||
|
||||
return nbelow * oneOverNbins;
|
||||
|
||||
} else {
|
||||
|
||||
G4double binMeasure = theIntegralPdf[nabove] - theIntegralPdf[nbelow];
|
||||
// binMeasure is always aProbFunc[nbelow],
|
||||
// but we don't have aProbFunc any more so we subtract.
|
||||
|
||||
if ( binMeasure == 0 ) {
|
||||
// rand lies right in a bin of measure 0. Simply return the center
|
||||
// of the range of that bin. (Any value between k/N and (k+1)/N is
|
||||
// equally good, in this rare case.)
|
||||
return (nbelow + .5) * oneOverNbins;
|
||||
}
|
||||
|
||||
G4double binFraction = (rand - theIntegralPdf[nbelow]) / binMeasure;
|
||||
|
||||
return (nbelow + binFraction) * oneOverNbins;
|
||||
}
|
||||
|
||||
} // mapRandom(rand)
|
||||
|
||||
|
||||
void G4MTRandGeneral::shootArray( CLHEP::HepRandomEngine* anEngine,
|
||||
const G4int size, G4double* vect )
|
||||
{
|
||||
for (G4int i=0; i<size; ++i)
|
||||
vect[i] = shoot(anEngine);
|
||||
}
|
||||
|
||||
void G4MTRandGeneral::fireArray( const G4int size, G4double* vect )
|
||||
{
|
||||
for (G4int i=0; i<size; ++i)
|
||||
vect[i] = fire();
|
||||
}
|
||||
#endif
|
||||
@@ -25,11 +25,16 @@
|
||||
//
|
||||
//
|
||||
// $Id:$
|
||||
|
||||
//
|
||||
// G4UniformRandPool implementation
|
||||
//
|
||||
// Author: A.Dotti (SLAC)
|
||||
// ------------------------------------------------------------
|
||||
|
||||
#include "G4UniformRandPool.hh"
|
||||
#include "globals.hh"
|
||||
#include "G4Threading.hh"
|
||||
#include "G4AutoDelete.hh"
|
||||
|
||||
#include <climits>
|
||||
#include <stdlib.h>
|
||||
@@ -48,7 +53,6 @@ void destroy_pool( G4double*& buffer)
|
||||
delete[] buffer;
|
||||
}
|
||||
|
||||
|
||||
#if defined(WIN32)
|
||||
// No bother with WIN
|
||||
void create_pool_align( G4double*& buffer , G4int ps)
|
||||
@@ -67,11 +71,6 @@ void destroy_pool_align( G4double*& buffer )
|
||||
//
|
||||
void create_pool_align( G4double*& buffer , G4int ps)
|
||||
{
|
||||
//#if defined(__ICC) || (__INTEL_COMPILER)
|
||||
// //INTEL optimized way
|
||||
// buffer = (G4doulbe*)mm_allign(ps*sizeof(G4double),sizeof(G4double)*CHAR_BIT);
|
||||
//#else
|
||||
|
||||
// POSIX standard way
|
||||
G4int errcode = posix_memalign( (void**) &buffer ,
|
||||
sizeof(G4double)*CHAR_BIT,
|
||||
@@ -83,20 +82,12 @@ void create_pool_align( G4double*& buffer , G4int ps)
|
||||
"Cannot allocate aligned buffer");
|
||||
return;
|
||||
}
|
||||
//#endif
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
void destroy_pool_align( G4double*& buffer )
|
||||
{
|
||||
//#if defined(__ICC) || (__INTEL_COMPILER)
|
||||
//mm_free(buffer);
|
||||
//#else
|
||||
|
||||
free(buffer);
|
||||
|
||||
//#endif
|
||||
}
|
||||
#endif
|
||||
|
||||
@@ -153,6 +144,16 @@ void G4UniformRandPool::Resize(/*PoolSize_t*/ G4int newSize )
|
||||
currentIdx = 0;
|
||||
}
|
||||
|
||||
void G4UniformRandPool::Fill( G4int howmany )
|
||||
{
|
||||
assert(howmany>0 && howmany <= size);
|
||||
|
||||
// Fill buffer with random numbers
|
||||
//
|
||||
G4Random::getTheEngine()->flatArray(howmany,buffer);
|
||||
currentIdx = 0;
|
||||
}
|
||||
|
||||
void G4UniformRandPool::GetMany( G4double* rnds , G4int howmany )
|
||||
{
|
||||
assert(rnds!=0 && howmany>0);
|
||||
@@ -171,7 +172,7 @@ void G4UniformRandPool::GetMany( G4double* rnds , G4int howmany )
|
||||
const G4int peel = howmany%size;
|
||||
assert(peel<size);
|
||||
|
||||
// Ok from now I will get random numbers in group of "size"
|
||||
// Ok from now on I will get random numbers in group of "size"
|
||||
// Note that if howmany<size maxcycles == 0
|
||||
//
|
||||
G4int cycle = 0;
|
||||
@@ -190,9 +191,9 @@ void G4UniformRandPool::GetMany( G4double* rnds , G4int howmany )
|
||||
// We can use memcpy of std::copy, it turns out that the two are basically
|
||||
// performance-wise equivalent (expected), since in my tests memcpy is a
|
||||
// little bit faster, I use that
|
||||
// std::copy(buffer,buffer+size,rnds+(cycle*size));
|
||||
//
|
||||
memcpy(rnds+(cycle*size),buffer,sizeof(G4double)*size );
|
||||
// std::copy(buffer,buffer+size,rnds+(cycle*size));
|
||||
|
||||
// Get a new set of numbers
|
||||
//
|
||||
@@ -201,7 +202,7 @@ void G4UniformRandPool::GetMany( G4double* rnds , G4int howmany )
|
||||
|
||||
// If maxcycles>0 last think we did was to call Fill(size)
|
||||
// so currentIdx == 0
|
||||
// and it is guranteed that peel<size, we have enough fresh random numbers
|
||||
// and it is guaranteed that peel<size, we have enough fresh random numbers
|
||||
// but if maxcycles==0 currentIdx can be whatever, let's make sure we have
|
||||
// enough fresh numbers
|
||||
//
|
||||
@@ -220,9 +221,6 @@ void G4UniformRandPool::GetMany( G4double* rnds , G4int howmany )
|
||||
|
||||
// Static interfaces implementing CLHEP methods
|
||||
|
||||
#include "G4Threading.hh"
|
||||
#include "G4AutoDelete.hh"
|
||||
|
||||
namespace
|
||||
{
|
||||
G4ThreadLocal G4UniformRandPool* rndpool = 0;
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
Reference in New Issue
Block a user