Fermi Physics Class Libraries Package: CLHEP-Random
ZOOM
ZOOM
ZOOM Validated CLHEP Random Package
HEP Random is a collection of
random number engines and a variety of
distributions which use those engines to generate pseudo-random
numbers.
The ZOOM validation consists of
- Verifying correct statistical properties of the engines and distributions
- Testing the original code and correcting minor bugs
- Providing a few additional methods requested by the Run II user community
- Completing the set of distributions, to include the full list
Review of Particle Properties.
The source code for headers and implementations of the ZOOM version of CLHEP
Random may be browsed here .
The extensions, corrections and validations on this page are completed and
reflected in the Random sub-package of the ZOOM distribution of CLHEP.
What is new:
10/23/98
New Distribution: RandMultiGauss
Multivariate Gaussian Distribution, as per page 170 of the new
Review of Particle Physics.
Returns a HepVector of random variates according to a given
HepVector means mu and HepSymMatrix
covariance about the mean S.
10/23/98
Tests of Distributions:
testRandDists
has Tests based on generating a large number of variates and verifying that
known properties of each distribution hold.
Distributions tested thus far are:
- RandGauss
- Mean and first four moments.
- Counts at 1, 2, 3, 4, and 5+ sigma.
- RandMultiGauss
- Mean.
- Covariance matrix.
9/17/98
Cleanup of the new random engines:
- Ranlux64
-
The earlier CLHEP implementation of this did not accurately follow Luscher's
prescription. Though it passed all the usual tests, it would likely have a
shorter period that the correct algorithm. The implementation has been
corrected to match Luscher's ranlxd.
- Hurd288Engine, Hurd160Engine, TripleRand, Mtwist
-
These have had several cleanups associated with the translation from integer
bit streams to doubles.
- (float) and (unsigned int)
-
Methods returning random variables of single precision are included. As
compared with flat(), for engines which take the trouble to ensure
randomness out to 53 bits of mantissa, (float) and
(unsigned int) run faster by generating fewer random bits.
-
8/25/98
Several new random engines have been added:
- TripleRand
-
is a combination of the DualRand and the Hurd288 engines, with a
period of over 2**400. This is intended as a small-state (60 bytes)
reasonably fast "mother of all generators" for applications that are
fairly paranoid.
- Hurd288Engine
-
- Hurd160ENgine
-
are a pair of linearly interconnected shift register engines, based
on the paper by William Hurd (not to be confused with GNU Hurd)
in IEEE Transactions on Computers, C23 No. 2 page 146. This
method is claimed to remove some unsatisfactory properties in
the Tausworthe methods, stemming from the latter using trinomial
primitive polynomials. We implement 160 and 288 bit instances,
based on lines 9 and 10 of table I in that paper.
Older "Whats New" Items
Testing for Proper Behavior of CLHEP Random sub-package
- Random Engine Validation
We have applied the "DIEHARD" suite of statistical tests for
uniformly distributed random numbers to each of the engines
in CLHEP Random.
Results show that several engines
pass the full suite of tests:
- DualRand
- Hurd288Engine
- MTwistEngine
- RanecuEngine
- RanluxEngine on luxury level 2 or higher
- Ranlux64Engine
- RanshiEngine
- TripleRand
Other engines fail one or more tests of randomness; in particular
RandEngine and RanluxEngine on level zero fail several significant
tests and should not be considered reliably random. RanshiEngine and
Hurd288Engine are about as fast as these (and much faster for
32-bit interger generation) and should be considered as substitutes.
Distribution Generator Validation
Validation of proper behavior of each distribution is
mathematically subtle in some cases. This validation is
has been done for:
Run testRandDists to execute these tests.
ZOOM-supplied Extensions
A couple of extensions to the basic interface are useful
to our community. These are in the area of internally
saving and restoring state, and support for large collections
of generators without getting identical sequences.
(In no case will these extensions modify or eliminate existing correct
functionality.
Any bug fixes which may change behavior will be indicated explicitly.)
Changes (fed back to CLHEP) are discussed
here.
Additional Constructors
- The default constructors for random engines tracks
starting seeds, so that multiple instances of engine
instantiated by default constructors give different
starting points in the random sequence. The following
code will work and give to each distribution an independent
engines with a unique starting seed:
RandGauss g1 (JamesRandom j1);
RandGauss g2 (JamesRandom j2);
RandGauss g3 (JamesRandom j3);
- The constructors for all engines now follow the same
pattern. Along with the default constructor and a copy
consturctor to duplicate the state,
- Each engine has
a constructor taking a single long argument.
This exhibits the identical behavior to that constructor
in CLHEP; in new engines the long is used in a direct way
to form the state.
- Each egine has a constructor taking
two int arguments. For engines in CLHEP that
already had such a constructor (top access a seed table)
the behavior is left intact.
For all other engines, this constructor establishes
the starting state based on those ints.
In generators
with 64-bits of state or more, the states which can
be established by default constructor, by supplying one
long, and by supplying two ints are all
distinct from one another.
- Each distribution
class has a default constructor, which
instantiates its own (default) instance of RanLuxEngine.
The following code would give an array of standard-parameter
Gaussian distributions, with
independent engines with different starting seeds for each
distribution:
-
Distributions have a form of constructor that accepts
a set a parameters to use as defaults for that distribution
instance, when fire() is done without supplying
parameters.
ZMRandGauss g(5.0,2.5);
double x = g.fire();
// x is distrbuted with mean = 5, sigma = 2.5
double y = g.fire(3, 2);
// y is distrbuted with mean = 3, sigma = 2
Of course, if parameters are explicitly supplied to an
invocation of fire(), those supplied parameters
are used. And if no
parameters are provided when constructing the distribution
instance, the standard values are used as before.
ZMRandGauss g(e, 0.0, 1.0);
// same as:
ZMRandGauss g(e);
Additional Methods
- Saving and restoring engine state to file with
user-supplied name.
RanluxEngine e;
e.saveStatus ( "myFile.conf" );
e.restoreStatus ( "yourFile.conf" );
- Engine state stream output via << and
input via >> . There are also constructors
accepting an istream to determine the state.
RanluxEngine e;
cin >> e;
cout << e;
RanLuxEngine e2 ( cin );
-
The flat() methods in all added engines supply double precision
numbers random out to the last bit. If the underlying engine works
with 32-bit numbers, this requires a bit of extra work. We will
provide conversion constructors for each engine, which can be used
as in:
DualRand e;
double x; float f; unsigned int u;
x = double(e); // Exactly equivalent to x = e.flat();
f = float(e); // Equivalent to f = e.flat();
// but somewhat faster
u = unsigned int(e); // Equivalient to u=pow(2.0, 32)*e.flat()
// but supplies the 32-bits obtained from
// the algorithm kernel, without the "middleman"
A shorter syntax will also work, but is disparaged because it looks
too mysterious:
x = e; // Will come out x = double(e);
f = e; // Will come out f = float(e);
u = e; // Will come out f = unsigned int(e);
For consistency, the double, float and unsigned int operators are also
be provided for the original engines, but these save no time.
Additional Distributions
The package now include the following distributions:
- All eight distributions in table
28.1 of the Review of Particle Properties.
Of these, Uniform, Poisson, and Gaussian were already
present in HEP Random. The ZOOM work adds:
- Binomial -- RandBinomial
- Chi-squared -- RandChiSquare
- Student's t -- RandStudentT
- Gamma -- RandGamma
- Multivariate Gaussian -- RandMultiGauss
- The two special cases of these
(Exponential and Breit-Wigner)
provided in the original CLHEP Random.
Additional Random Engines
- DualRand
-
A new random engine, implementing one which is in wide use in the
Lattice Gauge Monte Carlo community. It is a combination of a
(127,97) Tausworthe shift register generator and ordinary
32-bit integer congruence.
This passes
the statistical tests in the Diehard suite, and is rather fast.
It also has the property that two instances based on different seeds
will give truly different streams, and not two separated segments of
the same long stream.
- Ranshi
-
A huge-state (2K bytes) generator based on F. Gutbrod's method of
that same name.
It repeatedly simulates throwing spinning balls onto a large
collection of other spinning balls. One instance of Ranshi
uses as a state one 32-bit "red ball" and 512 32-bit "black ball"
spins. Techniques to avoid "trap" sequences are employed.
Though the properties of this process have not been studied
with any rigor, the huge state lends confidence in a good random
sequence of long period. Despite the huge state, the time taken to
generate a single random is excellent.
- Ranlux64
-
A 64-bit variant of the Ranlux engine, again from Europe. This (along
with all the ZOOM-supplied additional engines) supplies doubles which
are random out to all 53 bits of mantissa, rather than just 32 as the
original Ranlux does.
- MTwist
-
The
Mersenne Twister engine. This is a huge-state (~2.5 Kbytes)
engine which has mathematically proven outstanding randomness
properties and a period of 2**19,937 -1. Our implementation is
from the algorithm in the paper; there is a culture on the web page
of speed improvements but it is rather fast as it is, and we wanted
as few risks of incorrectness as possible. This is probably the best
huge-state engine available.
- TripleRand
-
is a combination of the DualRand and the Hurd288 engines, with a
period of over 2**400. This is intended as a small-state (60 bytes)
reasonably fast "mother of all generators" for applications that are
fairly paranoid. The Hurd288 engine implements a set of
linearly interconnected shift register engines, based
on the paper by William Hurd (not to be confused with GNU Hurd)
in IEEE Transactions on Computers, C23 No. 2 page 146. This
method is claimed to remove some unsatisfactory properties in
the Tausworthe methods, stemming from the latter using trinomial
primitive polynomials. We implement 160 and 288 bit instances,
based on lines 9 and 10 of table I in that paper.
Corrections
Several minor changes
were made in the behavior of these classes,
either to conform to the clearly intended behavior,
or to conform to normal semantics a user would expect in C++:
- When engines were constructed, they were supposed to be given
zero-terminated arrays of seed numbers as arguments. They were not,
and in the case of RanLuxEngine this made a difference. In
principle, this could lead to access violations; in
typical use, the only effect would be that two identically seeded
distributions would after a short while begin to diverge. This bug
has been fixed, for all the distribution classes.
- The previous behavior of default constructors of random engines
was such that if the user instantiated two intances of the same engine
class using the default constructor each time, the sequences obtained
would be identical. This is very trappy, and contradicts the most
probable purpose of using this syntax. We now provide a different
starting state each time. The user can get two matching sequences by
explicitly supplying a specific seed, or by copying the engine
object itself.
Validation and Extensions in Progress
Additional Methods
-
Default constructors will be provided for each of the distributions.
These will conform to the following semantics: When a distribution
is instantiated without specifying a specific engine, a new instance
of a good random engine will be constructed, and will be owned only
by the new distribution instance.
- Copy constructors and assignment operators will be provided for
each distribution. The semantics for what engine is used when
copying a distribution are as yet undecided. The three
possibilities are:
- A clone of the same class of engine as used in the
original distribution is instantiated and associated with
the copy distribution. Thus the original and the copy
distributions will have two completely independent streams.
- The copy distribution will share the same engine as the
original. Thus firing either will advance the state of the
other.
- A copy of the engine associated with the original will
be made and associated with the copy distribution. Thus
the distribution and its copy will fire identical streams of
randoms.
We are leaning toward the first of these possibilities. we
welcome comments as to which
choice people feel is most useful.
Additional Distributions
- Distributions for fluctuation of ionization energy loss:
- Landau distribution.
- Vavilov distribution,
an approximation-free version
of the Landau distribution with energy
cutoff.
This version will be quicker
than the CERNLIB versions of Vavilov.
- Vavilov distribution corrected for spin-1/2
particles.
Additional Engines
- RanUniEngine
-
Another engine in use in the Lattice Gauge community. This
comes from Marsaglia, and appears to be a lagged addition
Fibonacci, added mod 1 to a simple c*d mod m. Since the set
of other engines do not include a lagged Fibonacci, we will likely
incorporate this one.
The following engines are also logical candidates for inclusion but
we presently do not plan to provide them:
- Ran2 from Numerical recipes, which is related to Ranecu.
- Ran4 from Numerical recipes, which is related to the DES
encryption standard.
- GFSR, a 4-tap feedback shift register discussed by R. Ziff
in Computers in Physics, July 1998.
Validation

ZOOM Home Page -
Fermilab at Work -
Fermilab Home
Mark Fischler
Last modified: October 23, 1998