Commit d64dddec authored by Mark Fishcler's avatar Mark Fishcler
Browse files

Ability to save/restored state to vector of unsigned longs.

parent 8ad527fc
Fri Mar 11 2005 Mark Fischler <mf@fnal.gov>
* engineIDulong.cc, engineIDulong.h
DOubConv.cc, DoubConv.h
EngineFactory.cc
* DRand48Engine.cc DualRand.cc Hurd160Engine.cc
Hurd288Engine.cc JamesRandom.cc MTwistEngine.cc RandFlat.cc
RandGauss.cc RandomEngine.cc RandomEngine.cc RanecuEngine.cc
Ranlux64Engine.cc RanluxEngine.cc TripleRand.cc
* ranRestoreTest.cc
Add put() and get() methods to every engine transfering state to a
vector of unsigned longs.
Fri Mar 11 2005 Mark Fischler <mf@fnal.gov>
* NonRandomEngine.cc
Initialize (in the ctor) nextRandom and randomInterval (used if
interval-style is set) because these are writtten out and read in
as part of the state, and Microsooft VC++ fouls up the i/o when
reading back the uninitialized number written out.
Mon Feb 14 2005 Mark Fischler <mf@fnal.gov>
* JamesRandom.cc
Check that seed is non-negative negative sees give terrible sequences.
Check that seed is non-negative.
Negative seeds give terrible sequences.
Fri Feb 11 2005 Mark Fischler <mf@fnal.gov>
......
// $Id: DRand48Engine.h,v 1.3.2.4 2004/12/28 16:11:33 fischler Exp $
// $Id: DRand48Engine.h,v 1.3.2.5 2005/03/15 21:20:41 fischler Exp $
// -*- C++ -*-
//
// -----------------------------------------------------------------------
......@@ -36,7 +36,8 @@
// E.Tcherniaev - prototypes for drand48(), srand48() and seed48() have
// been moved to DRand48Engine.cc: 21 Feb 2002
// Mark Fischler - methods for distrib. instance save/restore 12/8/04
// Mark Fischler - methods for anonymous save/restore 12/27/04
// Mark Fischler - methods for anonymous save/restore 12/27/04
// Mark Fischler - methods for vector save/restore 3/7/05
// =======================================================================
#ifndef DRand48Engine_h
......@@ -94,6 +95,10 @@ public:
std::string name() const;
static std::string engineName() {return "DRand48Engine";}
std::vector<unsigned long> put () const;
bool get (const std::vector<unsigned long> & v);
bool getState (const std::vector<unsigned long> & v);
private:
......
#ifndef DOUBCONV_HH
#define DOUBCONV_HH
#include <string>
#include <vector>
#include <exception>
namespace CLHEP {
class DoubConvException : public std::exception {
public:
DoubConvException(const std::string & w) throw() : msg(w) {}
~DoubConvException() throw() {}
const char* what() const throw() { return msg.c_str(); }
private:
std::string msg;
};
class DoubConv {
public:
// dto2longs(d) returns (in a vector) two unsigned longs string containing the
// representation of its double input. This is byte-ordering
// independant, and depends for complete portability ONLY on adherance
// to the IEEE 754 standard for 64-bit floating point representation.
// The first unsigned long contains the high-order bits in IEEE; thus
// 1.0 will always be 0x3FF00000, 00000000
static std::vector<unsigned long> dto2longs(double d);
// longs2double (v) returns a double containing the value represented by its
// input, which must be a vector containing 2 unsigned longs.
// The input is taken to be the representation according to
// the IEEE 754 standard for a 64-bit floating point number, whose value
// is returned as a double. The byte-ordering of the double result is,
// of course, tailored to the proper byte-ordering for the system.
static double longs2double (const std::vector<unsigned long> & v);
// dtox(d) returns a 16-character string containing the (zero-filled) hex
// representation of its double input. This is byte-ordering
// independant, and depends for complete portability ONLY on adherance
// to the IEEE 754 standard for 64-bit floating point representation.
static std::string d2x(double d);
private:
union DB8 {
unsigned char b[8];
double d;
};
static void fill_byte_order ();
static bool byte_order_known;
static int byte_order[8];
// Meaning of byte_order: The first (high-order in IEEE 754) byte to
// output (or the high-order byte of the first unsigned long)
// is of db.b[byte_order[0]]. Thus the index INTO byte_order
// is a position in the IEEE representation of the double, and the value
// of byte_order[k] is an offset in the memory representation of the
// double.
};
}
#endif // DOUBCONV_HH
// $Id: DualRand.h,v 1.3.2.4 2004/12/28 16:11:33 fischler Exp $
// $Id: DualRand.h,v 1.3.2.5 2005/03/15 21:20:41 fischler Exp $
// -*- C++ -*-
//
// -----------------------------------------------------------------------
......@@ -32,6 +32,7 @@
// Ken Smith - Added conversion operators: 6th Aug 1998
// Mark Fischler methods for distrib. instance save/restore 12/8/04
// Mark Fischler methods for anonymous save/restore 12/27/04
// Mark Fischler - methods for vector save/restore 3/7/05
// =======================================================================
......@@ -94,6 +95,10 @@ public:
std::string name() const;
static std::string engineName() {return "DualRand";}
std::vector<unsigned long> put () const;
bool get (const std::vector<unsigned long> & v);
bool getState (const std::vector<unsigned long> & v);
private:
static int numEngines;
......@@ -111,7 +116,9 @@ private:
Tausworthe(unsigned int seed);
operator unsigned int();
void put(std::ostream & os) const;
void put(std::vector<unsigned long> & v) const;
void get(std::istream & is);
bool get(std::vector<unsigned long>::const_iterator & iv);
private:
int wordIndex;
unsigned int words[4];
......@@ -123,7 +130,9 @@ private:
IntegerCong(unsigned int seed, int streamNumber);
operator unsigned int();
void put(std::ostream & os) const;
void put(std::vector<unsigned long> & v) const;
void get(std::istream & is);
bool get(std::vector<unsigned long>::const_iterator & iv);
private:
unsigned int state, multiplier, addend;
}; // IntegerCong
......
......@@ -10,7 +10,7 @@
// Class generating new engines from streamed saves.
// =======================================================================
// M Fischler - Created: not yet really
// M Fischler - Created: 12/21/04
// =======================================================================
#ifndef EngineFactory_h
......@@ -24,9 +24,9 @@ namespace CLHEP {
class EngineFactory {
public:
static HepRandomEngine* newEngine(std::istream & is);
static HepRandomEngine* newEngine(std::vector<unsigned long> const & v);
};
} // namespace CLHEP
#ifdef ENABLE_BACKWARDS_COMPATIBILITY
......
// $Id: Hurd160Engine.h,v 1.3.2.4 2004/12/28 16:11:33 fischler Exp $
// $Id: Hurd160Engine.h,v 1.3.2.5 2005/03/15 21:20:41 fischler Exp $
// -*- C++ -*-
//
// -----------------------------------------------------------------------
......@@ -87,6 +87,10 @@ public:
static std::string beginTag ( );
virtual std::istream & getState ( std::istream & is );
std::vector<unsigned long> put () const;
bool get (const std::vector<unsigned long> & v);
bool getState (const std::vector<unsigned long> & v);
private:
static int numEngines;
static int maxIndex;
......
// $Id: Hurd288Engine.h,v 1.3.2.4 2004/12/28 16:11:33 fischler Exp $
// $Id: Hurd288Engine.h,v 1.3.2.5 2005/03/15 21:20:41 fischler Exp $
// -*- C++ -*-
//
// -----------------------------------------------------------------------
......@@ -86,6 +86,10 @@ public:
std::string name() const;
static std::string engineName() {return "Hurd288Engine";}
std::vector<unsigned long> put () const;
bool get (const std::vector<unsigned long> & v);
bool getState (const std::vector<unsigned long> & v);
private:
static int numEngines;
static int maxIndex;
......
// $Id: JamesRandom.h,v 1.3.2.4 2004/12/28 16:11:33 fischler Exp $
// $Id: JamesRandom.h,v 1.3.2.5 2005/03/15 21:20:41 fischler Exp $
// -*- C++ -*-
//
// -----------------------------------------------------------------------
......@@ -94,6 +94,10 @@ public:
std::string name() const;
static std::string engineName() {return "HepJamesRandom";}
std::vector<unsigned long> put () const;
bool get (const std::vector<unsigned long> & v);
bool getState (const std::vector<unsigned long> & v);
private:
// Members defining the current status of the generator.
......
// $Id: MTwistEngine.h,v 1.3.2.4 2004/12/28 16:11:33 fischler Exp $
// $Id: MTwistEngine.h,v 1.3.2.5 2005/03/15 21:20:41 fischler Exp $
// -*- C++ -*-
//
// -----------------------------------------------------------------------
......@@ -81,6 +81,10 @@ public:
std::string name() const;
static std::string engineName() {return "MTwistEngine";}
std::vector<unsigned long> put () const;
bool get (const std::vector<unsigned long> & v);
bool getState (const std::vector<unsigned long> & v);
private:
unsigned int mt[624];
......
......@@ -5,9 +5,11 @@ tempincludedir = $(TEMPDIR)/CLHEP/@PACKAGE@
COPY_P = @COPY_P@
pkginclude_HEADERS = \
DoubConv.hh \
DRand48Engine.h \
DualRand.h \
EngineFactory.h \
engineIDulong.h \
Hurd160Engine.h \
Hurd288Engine.h \
JamesRandom.h \
......
// $Id: NonRandomEngine.h,v 1.3.2.4 2004/12/28 16:11:33 fischler Exp $
// $Id: NonRandomEngine.h,v 1.3.2.5 2005/03/15 21:20:41 fischler Exp $
// -*- C++ -*-
//
// -----------------------------------------------------------------------
......@@ -71,6 +71,10 @@ public:
std::string name() const;
static std::string engineName() {return "NonRandomEngine";}
std::vector<unsigned long> put () const;
bool get (const std::vector<unsigned long> & v);
bool getState (const std::vector<unsigned long> & v);
private:
bool nextHasBeenSet;
......
// $Id: RandEngine.h,v 1.3.2.5 2004/12/28 16:11:33 fischler Exp $
// $Id: RandEngine.h,v 1.3.2.6 2005/03/15 21:20:41 fischler Exp $
// -*- C++ -*-
//
// -----------------------------------------------------------------------
......@@ -97,6 +97,10 @@ public:
std::string name() const;
static std::string engineName() {return "RandEngine";}
std::vector<unsigned long> put () const;
bool get (const std::vector<unsigned long> & v);
bool getState (const std::vector<unsigned long> & v);
private:
RandEngine(const RandEngine &p);
......
// $Id: RandomEngine.h,v 1.3.2.5 2005/02/11 23:10:32 fischler Exp $
// $Id: RandomEngine.h,v 1.3.2.6 2005/03/15 21:20:41 fischler Exp $
// -*- C++ -*-
//
// -----------------------------------------------------------------------
......@@ -42,6 +42,7 @@
#include <fstream>
#include <iomanip>
#include <string>
#include <vector>
#include "CLHEP/Random/defs.h"
namespace CLHEP {
......@@ -100,7 +101,15 @@ public:
static HepRandomEngine* newEngine(std::istream & is);
// Instantiates on the heap a new engine of type specified by content of is
static HepRandomEngine* newEngine(const std::vector<unsigned long> & v);
// Instantiates on the heap a new engine of type specified by content of v
virtual std::vector<unsigned long> put () const;
virtual bool get (const std::vector<unsigned long> & v);
virtual bool getState (const std::vector<unsigned long> & v);
// Save and restore to/from vectors
long getSeed() const { return theSeed; }
// Gets the current seed.
......
// $Id: RanecuEngine.h,v 1.3.2.4 2004/12/28 16:11:33 fischler Exp $
// $Id: RanecuEngine.h,v 1.3.2.5 2005/03/15 21:20:41 fischler Exp $
// -*- C++ -*-
//
// -----------------------------------------------------------------------
......@@ -102,6 +102,10 @@ public:
std::string name() const;
static std::string engineName() {return "RanecuEngine";}
std::vector<unsigned long> put () const;
bool get (const std::vector<unsigned long> & v);
bool getState (const std::vector<unsigned long> & v);
protected:
// Suggested L'ecuyer coefficients for portable 32 bits generators.
......
// $Id: Ranlux64Engine.h,v 1.3.2.4 2004/12/28 16:11:33 fischler Exp $
// $Id: Ranlux64Engine.h,v 1.3.2.5 2005/03/15 21:20:41 fischler Exp $
// -*- C++ -*-
//
// -----------------------------------------------------------------------
......@@ -98,6 +98,10 @@ public:
std::string name() const;
static std::string engineName() {return "Ranlux64Engine";}
std::vector<unsigned long> put () const;
bool get (const std::vector<unsigned long> & v);
bool getState (const std::vector<unsigned long> & v);
private:
void update();
......
// $Id: RanluxEngine.h,v 1.3.2.4 2004/12/28 16:11:33 fischler Exp $
// $Id: RanluxEngine.h,v 1.3.2.5 2005/03/15 21:20:41 fischler Exp $
// -*- C++ -*-
//
// -----------------------------------------------------------------------
......@@ -108,6 +108,10 @@ public:
std::string name() const;
static std::string engineName() {return "RanluxEngine";}
std::vector<unsigned long> put () const;
bool get (const std::vector<unsigned long> & v);
bool getState (const std::vector<unsigned long> & v);
private:
int nskip, luxury;
......
// $Id: RanshiEngine.h,v 1.3.2.4 2004/12/28 16:11:33 fischler Exp $
// $Id: RanshiEngine.h,v 1.3.2.5 2005/03/15 21:20:41 fischler Exp $
// -*- C++ -*-
//
// -----------------------------------------------------------------------
......@@ -99,6 +99,10 @@ public:
std::string name() const;
static std::string engineName() {return "RanshiEngine";}
std::vector<unsigned long> put () const;
bool get (const std::vector<unsigned long> & v);
bool getState (const std::vector<unsigned long> & v);
private:
static double twoToMinus_32;
static double twoToMinus_53;
......
// $Id: TripleRand.h,v 1.3.2.4 2004/12/28 16:11:33 fischler Exp $
// $Id: TripleRand.h,v 1.3.2.5 2005/03/15 21:20:41 fischler Exp $
// -*- C++ -*-
//
// -----------------------------------------------------------------------
......@@ -98,6 +98,10 @@ public:
std::string name() const;
static std::string engineName() {return "TripleRand";}
std::vector<unsigned long> put () const;
bool get (const std::vector<unsigned long> & v);
bool getState (const std::vector<unsigned long> & v);
private:
static int numEngines;
......@@ -115,7 +119,9 @@ public:
operator unsigned int();
void put( std::ostream & os ) const;
void put(std::vector<unsigned long> & v) const;
void get( std::istream & is );
bool get(std::vector<unsigned long>::const_iterator & iv);
private:
......@@ -136,7 +142,9 @@ public:
operator unsigned int();
void put( std::ostream & os ) const;
void put(std::vector<unsigned long> & v) const;
void get( std::istream & is );
bool get(std::vector<unsigned long>::const_iterator & iv);
private:
......
// $Id
// -*- C++ -*-
//
// -----------------------------------------------------------------------
// HEP Random
// --- engineIDulong ---
// function header file
// -----------------------------------------------------------------------
// Class generating new engines from streamed saves.
// =======================================================================
// M Fischler - Created: Mar. 8, 2005
// =======================================================================
#ifndef engineIDulong_h
#define engineIDulong_h 1
namespace CLHEP {
unsigned long crc32ul(const std::string & s);
template <class E>
unsigned long engineIDulong() {
static unsigned long id = crc32ul(E::engineName());
return id;
}
} // namespace CLHEP
#ifdef ENABLE_BACKWARDS_COMPATIBILITY
// backwards compatibility will be enabled ONLY in CLHEP 1.9
using namespace CLHEP;
#endif
#endif
......@@ -31,6 +31,15 @@ there can be no user-controlled flexibility in how to deal with trouble
Each distribution saves the state of the engine it is using. If several
distributions share a single instance of an engine, then this wastes I/O
time and space on multiple copies of the same data.
<li>
There was never a way to save an engine, and then have another program
instantiate a <em>HepRandomEngine*</em> and read back the state to create
an engine of the appropriate type, without knowing what sort of engine was
saved. We call this functionallity an "engine factory."
<li>
For cases where the user program has its own scheme to persist numbers (for
example, unsigned longs), there is no way to cause an engine to produce
its state (or restore from a saved state) as a vector of unsigned longs.
</ul>
The usual idiom for saving data would be to write to an ostream and read
......@@ -40,10 +49,15 @@ It is assumed that users know how to construct an <em>fstream</em>
using these
<em>fstream</em>s as <em>ostream</em>s and <em>istream</em>s.
<p>
We are adding methods that stick to this idiom, which
We have added methods that stick to this idiom, which
greatly helps matters. (In fact,
the first two of these inconveniences are immediately resolved,
and the structure is right for dealing with the third.)
<p>
We have also added engine factory
capability to deal with anonymous engine saves,
and we have given every engine the ability to save and restore to/from
a vector of unsigned longs.
<ul>
<li> <a href="#usecases"> Use Cases </a>
......@@ -139,6 +153,14 @@ knowledge of which engine type this will be.
For example, the saved engine may be a product of a simulation job
where the engine created was determined by run-time input.
<h3> Saving and restoring state via a vector of unsigned longs </h3>
An experiment framework has a means of imbedding an array of numbers into
the data for an event, and would wish to use this to hold the state of
the engine(s) used. Here, the model of saving to a stream is less convenient
and much less efficient. HepMC assumes random engines can produce their
states in the form of a vector of unsigned longs.
<font color=blue>
<h2> Added Methods in CLHEP Random </h2>
</font>
......@@ -318,6 +340,16 @@ istream& RandomEngine::get(istream&);
Outputs or inputs engine state, including identifying name. <br>
Used by operator<< and operator>>.
</ul>
<font size=+1, color=red>
<pre>
vector < unsigned long > RandomEngine::put() const;
bool RandomEngine::get(const vector<unsigned long> &);
</pre>
</font>
<ul>
Writes or sets engine state, including 32-bit identifier,
to a vector of unsigned longs.
</ul>
Methods for I/O of engine states to streams are already present.
Though not "additional methods," this are listed here because they
......@@ -336,17 +368,20 @@ to help catch mismatches where erroneous code tries to use an engine state
as the state of a different kind of engine.
</ul>
Finally, the base class <font size=+1><pre>HepRandomEngine </pre></font>
has a method to obtain a pointer to a new engine based on
Finally, the base class <em>HepRandomEngine </em>
has a pair of methods to obtain a pointer to a new engine based on
"generic" or anonymous engine input:
<font size=+1, color=red>
<pre>
static HepRandomEngine* HepRandomEngine::newEngine(istream& is);
static HepRandomEngine* HepRandomEngine::newEngine
(const vector<unsigned long> & v);
</pre>
</font>
<ul>
Based on the contents of the istream, which must contain the output of
Based on the contents of the istream or vector,
which must contain the output of
saving some engine, this instantiates a <em>new</em> engine of the
saved type, and returns a pointer to that object. The semantics are
that of <em>new</em>: It is the user's responsibility to invoke delete
......@@ -540,6 +575,36 @@ The "restoring job" does:
</pre>
</font>
<h3> Saving and restoring state via a vector of unsigned longs </h3>
The "saving job" does:
<font color=blue>
<pre>
HepJamesRandom e = new HepJamesRandom(12343211);
codeUsing_e (e);
std::vector < unsigned long > v;
<font size=+1, color=red><b>
v = e.put();
</b></font>
eventData.add_a_vector (v);
</pre>
</font>
The "restoring job" does:
<font color=blue>
<pre>
eventData.add_a_vector (v);
HepJamesRandom e;
<font size=+1, color=red><b>
bool ok = e.get(v);
if (!ok) throw "problem restoring an engine";
</b></font>
codeUsing_e(e);
</pre>
</font>
<p>
<center>
......@@ -551,7 +616,7 @@ The "restoring job" does:
Author: <address><a href="mailto:mf@fnal.gov">Mark Fischler</a></address>
<p>
<!-- hhmts start -->
Last modified: December 13, 2004
Last modified: March 15, 2005
<!-- hhmts end -->
</body>
</html>
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment