Import Geant4 11.0.0.beta source tree
This commit is contained in:
+117
@@ -0,0 +1,117 @@
|
||||
// Copyright (C) 2010, Guy Barrand. All rights reserved.
|
||||
// See the file tools.license for terms.
|
||||
|
||||
#ifndef tools_rtausmeui
|
||||
#define tools_rtausmeui
|
||||
|
||||
// G.Barrand : not so clear if 0 and tools::uint32_max() are included.
|
||||
// A simple program shows that "if(r.shoot()==tools::uint32_max())" shows hits.
|
||||
// (But we did not see hits for "if(r.shoot()==0)"). (See inlib/tests/rand.cpp).
|
||||
|
||||
// tausme is for Tausworthe maxmally equidistributed.
|
||||
|
||||
// From logic and code of CERN-ROOT/TRandom2 class.
|
||||
|
||||
// Random number generator class based on the maximally quidistributed combined
|
||||
// Tausworthe generator by L'Ecuyer.
|
||||
//
|
||||
// The period of the generator is 2**88 (about 10**26) and it uses only 3 words
|
||||
// for the state.
|
||||
//
|
||||
// For more information see:
|
||||
// P. L'Ecuyer, Mathematics of Computation, 65, 213 (1996)
|
||||
// P. L'Ecuyer, Mathematics of Computation, 68, 225 (1999)
|
||||
//
|
||||
// The publication are available online at
|
||||
// http://www.iro.umontreal.ca/~lecuyer/myftp/papers/tausme.ps
|
||||
// http://www.iro.umontreal.ca/~lecuyer/myftp/papers/tausme2.ps
|
||||
|
||||
#ifdef TOOLS_MEM
|
||||
#include "mem"
|
||||
#include "S_STRING"
|
||||
#endif
|
||||
|
||||
namespace tools {
|
||||
|
||||
class rtausmeui {
|
||||
#ifdef TOOLS_MEM
|
||||
TOOLS_SCLASS(tools::rtausmeui)
|
||||
#endif
|
||||
public:
|
||||
rtausmeui(unsigned int a_seed = 1):m_seed(0),m_seed1(0),m_seed2(0){
|
||||
#ifdef TOOLS_MEM
|
||||
mem::increment(s_class().c_str());
|
||||
#endif
|
||||
set_seed(a_seed);
|
||||
}
|
||||
virtual ~rtausmeui(){
|
||||
#ifdef TOOLS_MEM
|
||||
mem::decrement(s_class().c_str());
|
||||
#endif
|
||||
}
|
||||
public:
|
||||
rtausmeui(const rtausmeui& a_from):m_seed(a_from.m_seed),m_seed1(a_from.m_seed1),m_seed2(a_from.m_seed2){
|
||||
#ifdef TOOLS_MEM
|
||||
mem::increment(s_class().c_str());
|
||||
#endif
|
||||
}
|
||||
rtausmeui& operator=(const rtausmeui& a_from) {
|
||||
m_seed = a_from.m_seed;
|
||||
m_seed1 = a_from.m_seed1;
|
||||
m_seed2 = a_from.m_seed2;
|
||||
return *this;
|
||||
}
|
||||
public:
|
||||
void set_seed(unsigned int a_seed) {
|
||||
m_seed = a_seed?a_seed:1;
|
||||
|
||||
// Generate m_seed[1,2] needed for the generator state using
|
||||
// a linear congruential generator
|
||||
// The only condition, stated at the end of the 1999 L'Ecuyer paper is that the seeds
|
||||
// must be greater than 1,7 and 15.
|
||||
|
||||
m_seed = LCG(m_seed);
|
||||
if (m_seed < 2) m_seed += 2UL;
|
||||
m_seed1 = LCG(m_seed);
|
||||
if (m_seed1 < 8) m_seed1 += 8UL;
|
||||
m_seed2 = LCG(m_seed1);
|
||||
if (m_seed2 < 16) m_seed2 += 16UL;
|
||||
|
||||
// "warm it up" by calling it 6 times
|
||||
for (unsigned int i = 0; i < 6; ++i) shoot();
|
||||
}
|
||||
unsigned int seed() const {return m_seed;}
|
||||
|
||||
unsigned int shoot() {
|
||||
// TausWorth generator from L'Ecuyer, uses as seed 3x32bits integers
|
||||
// Use a mask of 0xffffffffUL to make in work on 64 bit machines
|
||||
// Periodicity of about 10**26
|
||||
|
||||
unsigned int y;
|
||||
|
||||
do {
|
||||
m_seed = TAUSWORTHE (m_seed, 13, 19, 4294967294UL, 12);
|
||||
m_seed1 = TAUSWORTHE (m_seed1, 2, 25, 4294967288UL, 4);
|
||||
m_seed2 = TAUSWORTHE (m_seed2, 3, 11, 4294967280UL, 17);
|
||||
|
||||
y = m_seed ^ m_seed1 ^ m_seed2;
|
||||
} while(!y);
|
||||
|
||||
return y;
|
||||
}
|
||||
protected:
|
||||
static unsigned int LCG(unsigned int a_n) {
|
||||
return ((69069 * a_n) & 0xffffffffUL); // linear congurential generator
|
||||
}
|
||||
static unsigned int TAUSWORTHE(unsigned int a_s,unsigned int a_a,unsigned int a_b,unsigned int a_c,unsigned int a_d) {
|
||||
return (((a_s & a_c) << a_d) & 0xffffffffUL ) ^ ((((a_s << a_a) & 0xffffffffUL )^ a_s) >> a_b);
|
||||
}
|
||||
protected:
|
||||
unsigned int m_seed;
|
||||
unsigned int m_seed1;
|
||||
unsigned int m_seed2;
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif
|
||||
Reference in New Issue
Block a user