--- a/src/core/random-variable.cc Thu Mar 22 16:02:33 2007 -0400
+++ b/src/core/random-variable.cc Thu Mar 22 16:41:01 2007 -0400
@@ -89,6 +89,7 @@
//-----------------------------------------------------------------------------
// RandomVariable methods
+uint32_t RandomVariable::runNumber = 0;
bool RandomVariable::initialized = false; // True if RngStream seed set
bool RandomVariable::useDevRandom = false; // True if use /dev/random desired
bool RandomVariable::globalSeedSet = false; // True if GlobalSeed called
@@ -101,12 +102,12 @@
m_generator = new RngStream();
RandomVariable::Initialize(); // sets the seed for the static object
m_generator->InitializeStream();
+ m_generator->ResetNthSubstream(RandomVariable::runNumber);
}
RandomVariable::RandomVariable(const RandomVariable& r)
{
m_generator = new RngStream(*r.m_generator);
- RandomVariable::Initialize();
}
RandomVariable::~RandomVariable()
@@ -124,29 +125,9 @@
RandomVariable::useDevRandom = udr;
}
-bool RandomVariable::SetSeed(const Seed& s)
+void RandomVariable::GetSeed(uint32_t seed[6])
{
- // Seed this stream with the specified seed
- if (s.IsRandom())
- {
- uint32_t seeds[6];
- while(true)
- { // Insure seeds are valid
- GetRandomSeeds(seeds);
- if (RngStream::CheckSeed(seeds)) break;
- }
- m_generator->SetSeeds(seeds);
- return true;
- }
- // Not random seed, use specified
- const ConstantSeed& cs = (ConstantSeed&)s;
- if (!RngStream::CheckSeed(cs.seeds))
- {
- cout << "Constant seed failed valid check" << endl;
- return false; // Seed is not valid
- }
- m_generator->SetSeeds(cs.seeds);
- return true;
+ m_generator->GetState(seed);
}
//-----------------------------------------------------------------------------
@@ -233,6 +214,11 @@
}
}
+void RandomVariable::SetRunNumber(uint32_t n)
+{
+ runNumber = n;
+}
+
//-----------------------------------------------------------------------------
//-----------------------------------------------------------------------------
// UniformVariable methods
--- a/src/core/random-variable.h Thu Mar 22 16:02:33 2007 -0400
+++ b/src/core/random-variable.h Thu Mar 22 16:41:01 2007 -0400
@@ -113,22 +113,17 @@
* \return A copy of this object
*/
virtual RandomVariable* Copy() const = 0;
-
+
/**
- * \brief Use a private seed and private stream for this generator.
- *
- * This function explicitly overrides all other seeding behavior for
- * this object. For example, even if another seeding method has been
- * used (either by default or calls to UseDevRandom, UseGlobalSeed, etc.)
- * a call to SetSeed explicitly re-seeds this generator. Example:
- * \code
- * UniformVariable x(0,10);//with no other code, defaults to time of day seed
- * x.SetSeed(...); //overrides time of day seed
- * \endcode
- * \param s Seed to use. Can either be a RandomSeed or ConstantSeed.
- * \return true if valid seed.
+ * \brief Get the internal state of the RNG
+ *
+ * This function is for power users who understand the inner workings
+ * of the underlying RngStream method used. It returns the internal
+ * state of the RNG via the input parameter.
+ * \param seed Output parameter; gets overwritten with the internal state of
+ * of the RNG.
*/
- bool SetSeed(const Seed& s);
+ virtual void GetSeed(uint32_t seed[6]);
/**
* \brief Set seeding behavior
@@ -168,16 +163,49 @@
* \return True if seed is valid.
*/
static void UseGlobalSeed(const Seed& s);
-
+
+ /**
+ * \brief Set the run number of this simulation
+ *
+ * These RNGs have the ability to give independent sets of trials for a fixed
+ * global seed. For example, suppose one sets up a simulation with
+ * RandomVariables with a given global seed. Suppose the user wanted to
+ * retry the same simulation with different random values for validity,
+ * statistical rigor, etc. The user could either change the global seed and
+ * re-run the simulation, or could use this facility to increment all of the
+ * RNGs to a next substream state. This predictably advances the internal
+ * state of all RandomVariables n steps. This should be called immediately
+ * after the global seed is set, and before the creation of any
+ * RandomVariables. For example:
+ * \code
+ * RandomVariable::UseGlobalSeed(ConstantSeed(1,2,3,4,5,6));
+ * int N = atol(argv[1]); //read in run number from command line
+ * RandomVariable::SetRunNumber(N);
+ * UniformVariable x(0,10);
+ * ExponentialVariable y(2902);
+ * \endcode
+ * In this example, N could successivly be equal to 1,2,3, etc. and the user
+ * would continue to get independent runs out of the single simulation. For
+ * this simple example, the following might work:
+ * \code
+ * ./simulation 0
+ * ...Results for run 0:...
+ *
+ * ./simulation 1
+ * ...Results for run 1:...
+ * \endcode
+ */
+ static void SetRunNumber(uint32_t n);
private:
- static bool initialized; // True if package seed is set
static void Initialize(); // Initialize the RNG system
static void GetRandomSeeds(uint32_t seeds[6]);
private:
+ static bool initialized; // True if package seed is set
static bool useDevRandom; // True if using /dev/random desired
static bool globalSeedSet; // True if global seed has been specified
static int devRandom; // File handle for /dev/random
static uint32_t globalSeed[6]; // The global seed to use
+ static uint32_t runNumber;
protected:
static unsigned long heuristic_sequence;
RngStream* m_generator; //underlying generator being wrapped
--- a/src/core/rng-stream.cc Thu Mar 22 16:02:33 2007 -0400
+++ b/src/core/rng-stream.cc Thu Mar 22 16:41:01 2007 -0400
@@ -378,6 +378,19 @@
Cg[i] = Bg[i];
}
+//-------------------------------------------------------------------------
+// Reset Stream to Nth SubStream.
+//
+void RngStream::ResetNthSubstream (uint32_t N)
+{
+ if(N==0) return;
+ for(uint32_t i=0;i<N;++i) {
+ MatVecModM(A1p76, Bg, Bg, m1);
+ MatVecModM(A2p76, &Bg[3], &Bg[3], m2);
+ }
+ for (int i = 0; i < 6; ++i)
+ Cg[i] = Bg[i];
+}
//-------------------------------------------------------------------------
bool RngStream::SetPackageSeed (const uint32_t seed[6])
--- a/src/core/rng-stream.h Thu Mar 22 16:02:33 2007 -0400
+++ b/src/core/rng-stream.h Thu Mar 22 16:41:01 2007 -0400
@@ -31,6 +31,7 @@
void ResetStartStream ();
void ResetStartSubstream ();
void ResetNextSubstream ();
+ void ResetNthSubstream(uint32_t N);
void SetAntithetic (bool a);
void IncreasedPrecis (bool incp);
bool SetSeeds (const uint32_t seed[6]);