# Interface

These are methods which are defined for any samplers subtyping `<:SSA`

, the abstract sampler type.

## Use a Sampler

`CompetingClocks.enable!`

— Function`enable!(sampler, clock, distribution, enablingtime, currenttime, RNG)`

Tell the sampler to start a clock.

`sampler::SSA{KeyType,TimeType}`

- The sampler to tell.`clock::KeyType`

- The ID of the clock. Can be a string, integer, tuple, etc.`distribution::Distributions.UnivariateDistribution`

`enablingtime::TimeType`

- The zero time for the clock's distribution, in absolute time. Usually equal to`when`

.`when::TimeType`

- The current time of the simulation.`rng::AbstractRNG`

- A random number generator.

`enable!(dc::DirectCall, clock::T, distribution::Exponential, when, rng)`

Tell the `DirectCall`

sampler to enable this clock. The `clock`

argument is an identifier for the clock. The distribution is a univariate distribution in time. In Julia, distributions are always relative to time `t=0`

, but ours start at some absolute enabling time, $t_e$, so we provide that here. The `when`

argument is the time at which this clock is enabled, which may be later than when it was first enabled. The `rng`

is a random number generator.

If a particular clock had one rate before an event and it has another rate after the event, call `enable!`

to update the rate.

`CompetingClocks.disable!`

— Function`disable!(sampler, clock, when)`

Tell the sampler to forget a clock. We include the current simulation time because some Next Reaction methods use this to optimize sampling.

`disable!(dc::DirectCall, clock::T, when)`

Tell the `DirectCall`

sampler to disable this clock. The `clock`

argument is an identifier for the clock. The `when`

argument is the time at which this clock is enabled.

`CompetingClocks.next`

— Function`next(sampler, when, rng)`

Ask the sampler for what happens next, in the form of `(when, which)::Tuple{TimeType,KeyType}`

. `rng`

is a random number generator.

`next(dc::DirectCall, when::TimeType, rng::AbstractRNG)`

Ask the sampler what clock will be the next to fire and at what time. This does not change the sampler. You can call this multiple times and get multiple answers. Each answer is a tuple of `(when, which clock)`

. If there is no clock to fire, then the response will be `(Inf, nothing)`

. That's a good sign the simulation is done.

`next(multiple_direct, when, rng)`

Selects the next transition to fire and when it fires.

There are two main algorithms for this selection. This implementation handles the case when there are a lot of clocks or when some clocks have much smaller hazards. It first draws a random number to choose which subset of hazards will be used, and then it asks that subset to draw a random number to choose which particular hazard is used. When there are many hazards, it is possible that a random number generator will *never* choose a particular value because there is no guarantee that a random number generator covers every combination of bits. Using more draws decreases the likelihood of this problem.

For the first reaction sampler, you can call next() multiple times and get different, valid, answers. That isn't the case here. When you call next() on a CombinedNextReaction sampler, it returns the key associated with the clock that fires and marks that clock as fired. Calling next() again would return a nonsensical value.

`CompetingClocks.reset!`

— Function`reset!(sampler)`

After a sampler is used for a simulation run, it has internal state. This function resets that internal state to the initial value in preparation for another sample run.

`reset!(recorder::CommonRandomRecorder)`

The common random recorder records the state of the random number generator for each clock, but the same clock can be enabled multiple times in one simulation, so it records the generator state for each (clock, index of the enabling of that clock). The `reset!`

function says we are starting a new simulation run, so all clocks haven't been seen.

## Query a Sampler

`Base.getindex`

— Function`getindex(sampler, clock::KeyType)`

Return stored state for a particular clock. If the clock does not exist, a `KeyError`

will be thrown.

`getindex(sampler::FirstReaction{K,T}, clock::K)`

For the `FirstReaction`

sampler, returns the distribution object associated to the clock.

`getindex(sampler::FirstToFire{K,T}, clock::K)`

For the `FirstToFire`

sampler, returns the stored firing time associated to the clock.

`getindex(sampler::DirectCall{K,T}, clock::K)`

For the `DirectCall`

sampler, returns the rate parameter associated to the clock.

`getindex(sampler::CombinedNextReaction{K,T}, clock::K)`

For the `CombinedNextReaction`

sampler, returns the stored firing time associated to the clock.

`Base.keys`

— Function`keys(sampler)`

Return all stored clocks as a vector.

`Base.keytype`

— Function`keytype(sampler)`

Return the type of clock keys.

`Base.length`

— Function`length(sampler)::Int64`

Return the number of stored clocks.