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:
restoreStatusmethods are based on a named file, so that each distribution saved must be placed in its own file.
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.)
cerrand 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
to use the static distribution, and
.fire() to use
For these added methods which deal with saving and restoring to
an fstream, the static methods all take the stream as an argument,
instance methods use the
ostream << whatever
istream >> whatever
As in the case of variate generation, all the methods dealing with just an engine are based on an instance.
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;
theEnginein 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);
theEnginein 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.
theEngineand 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();
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