We have added new (as of late 2004) methods to the CLHEP Random classes allowing more convenient and natural saving and restoring of engines and distributions. Some inconvenient features of the original methods are:
saveStatus
and restoreStatus methods are
based on a named file, so that each distribution saved must be placed in
its own file.
restoreStatus method,
there can be no user-controlled flexibility in how to deal with trouble
(such as file not found) in opening that file.
We are adding 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.)
cerr
and setting the state of the restoring istream to "bad."
RandGauss::shoot().
She wishes to save/restore the full state (including underlying engine)
of just that distribution.
This is completely analogous to doing
RandGauss::saveState("filename"),
but it is desired that this state be added to a file rather than
placed in its own file.
shoot()
method of several static distributions)
and one or more instances of engines of various types.
To conserve I/O space, she wishes to separately save each engine and
the non-engine-dependant state of each distribution.
Since she knows which engines are used by which distributions, she will
be able to restore the full states of all the distributions after restoring
individual engine and distribution states.
shoot()
method of various static distributions.
They wish to make a single call to save/restore the states of all the
static distributions in the CLHEP Randoms package. This method needs to
take care of making sure that states of shared engines are saved only once,
and that all needed engine instances are saved.
Since most or all the static distributions will be sharing one instance of an engines, and since the (non-engine) state of a distribution itself is miniscule, the "wasted" cost of saving the unused static distributions is acceptable.
(For this method to work, either the program has never modified the types of
endgines underlying the various static distributions, or if these have been
modified, the restoring program must know how to set up the matching engine
type for each static distribution.)
Added Methods in CLHEP Random
There are two types of save and restore activities on a distribution,
just as there are two modes of using a distribution to generate a random
variate, depending on whether you want the static distribution or an instance
of the distribution.
For the generation activity, the methods are
Class::shoot()
to use the static distribution, and
instance.fire() to use
an instance.
For these added methods which deal with saving and restoring to
an fstream, the static methods all take the stream as an argument,
while the
instance methods use the
ostream << whatever
or
istream >> whatever
syntax.
As in the case of variate generation, all the methods dealing with just an engine are based on an instance.
HepRandom
class:
static ostream& saveFullState (ostream& os) const; static ostream& restoreFullState(ostream& os);
shoot()
is invoked and any
additional cached data, such as the second gaussian in the Box-Mueller
method used by RandGauss.
static ostream& saveDistState (ostream& os) const; static ostream& restoreDistState(ostream& os);
shoot() method,
so that if the engine used is also restored,
the full state will have been replicated.
static ostream& saveStaticRandomStates (ostream& os) const;
theEngine
in the static shoot()
method of one or more of the distributions.
Save the state of each of those engines (but in the case of a shared engine,
only one copy of the state is saved). Then saves the static state of each
distribution, attached to an identification of which saved engine is used
by shoot() for that distribution.
static ostream& restoreStaticRandomStates(ostream& os);
theEngine
in the static shoot()
method of one or more of the distributions.
Uses the information about which distribution uses which engine,
attached to the additional distribution state of each distribution,
to restore every distribution
so the state is replicated for ayn call to
shoot() for any of the
CLHEP Random distributions.
theEngine
and engine and distribution save/restore methods,
but it would be awkward, so we have put this combination into
the library.
ostream& operator << (ostream& os, const HepRandom & distribution); istream& operator >> (ostream& os, HepRandom & distribution);
fire() method,
so that if the engine used is also restored,
the full state will have been replicated.
RandomEngine * HepRandom::engine();
string RandomEngine::name();
ostream& operator << (ostream& os, const RandomEngine & engine); istream& operator >> (ostream& os, RandomEngine & engine);
RandEngine.
In such a case, it is unclear whether it is possible to modfy the engine state
to accomplish the restore functionality.
e = new DualRand(24681357); // illustrating that the engine need not RandGauss::setTheEngine (e); // be the default engine for RandGauss ofstream fs(filename); // or pass an ofstream already in use codeUsingRandGaussManyTimes(); RandGauss::saveFullState(fs);The "restoring job" does:
e = new DualRand(); RandGauss::setTheEngine (e); ifstream file(filename); // or pass an ifstream already in use RandGauss::restoreFullState(fs);
e = new DualRand(24681357); RandGauss g(e); // normal distribution, based on engine e; ofstream fs(filename); codeUsing_g_ManyTimes(); fs << g.engine() << g;The "restoring job" does:
e = new DualRand(); RandGauss g(e); ifstream fs(filename); fs >> g.engine() >> g;
e1 = new DualRand(24681357); e2 = new MTwistEngine(135797531); RandGauss g(e1); RandFlat f(e1); RandBit b(e2); ofstream fs(filename); codeUsing_g_f_and_b(); fs << e1 << e2 << g << f << b;The "restoring job" does:
e = new DualRand(); RandGauss g(e); ifstream fs(filename); fs >> e1 >> e2 >> g >> f >> b;To save and restore successfully in the general case, you must know not only which types of engines underlie the various distributions, but also which distributions share an engine.
e = new DualRand(24681357); // illustrating that the some distributions RandGauss::setTheEngine (e); // need not use the default engine ofstream fs(filename); codeUsingVariousDistributions(); saveStaticRandomStates(fs);The "restoring job" does:
e = new DualRand(); RandGauss::setTheEngine (e); ifstream file(filename); restoreStaticRandomStates(fs);
Last modified: December 1, 2004