Print

Print


On Jul 20, 2012, at 8:27 PM, Chris Hollander wrote:

> It looks like it should be okay for the moment, but doesn't
> 
> protected abstract double getNextTime(SimState state, double currentTime);
> 
> force the user to make use of Mason's random number generator, which
> if I recall only supports uniform and Gaussian distributions? Granted,
> you can use those to generate random variates of other types, but I'm
> not sure what the performance impact might be.

That's not how random number generators work.  When you pick a random number from a distribution, you're not using a different generator.  You're just using the core generator (in our case, Mersenne Twister) to pick a uniform number, and then the distribution is transforming it into a number selected from under the distribution.  Thus you never need anything more than the core generator passed in, and in fact if you're using a different generator on top of that then there's probably something seriously wrong with your model.

For example, to use my code with a basic stateless distribution (found in the Distributions class) like Power Law, you could do:

Steppable step = ...
double initialTime = 5.0;
int initialOrdering = 0;

RandomRepeat repeat = new RandomRepeat(step, initialOrdering, false)
      {
      protected double getNextTime(SimState state, double currentTime)
              {
		// return PowerLaw() + 1.0, with exponent=2.0 and lower cutoff=1.0
              return currentTime + Distributions.nextPowLaw(2.0, 1.0, state.random) + 1.0;
              }
      };

state.schedule.scheduleOnce(initialTIme, initialOrdering, repeat);




For a stateful distribution which requires its own instance, you attach the Mersenne Twister RNG during the constructor like this::

Steppable step = ...
double initialTime = 5.0;
int initialOrdering = 0;

final Logarithmic lg = new Logarithmic(p, state.random);

RandomRepeat repeat = new RandomRepeat(step, initialOrdering, false)
      {
      protected double getNextTime(SimState state, double currentTime)
              {
		// return Logarithmic() + 1.0, say...
              return currentTime + lg.nextDouble() + 1.0;
              }
      };

state.schedule.scheduleOnce(initialTIme, initialOrdering, repeat);