Simulator concepts and exceptions
Exceptions
rdmini::operation_not_supported
Derives from std::logic_error
Some operations described in the API below may be optional, in that they may not be practical to support in every implementation, and are not crucial in providing SSA functionality. Such operations may thus instead throw an exception of this type.
rdmini::invalid_value
Derives from std::runtime_error
Implementations are not obliged to perform range checking; should they do so, however, they must throw this exception when a supplied value is invalid.
rdmini::ssa_error
Derives from std::runtime_error
Represents an internal error in an SSA implementation.
Simulator engine interface
Any instance s of a simulator implementation S should provide the following interface to callers.
An SSA simulator engine may be comprised of an SSA selector and SSA process system, as described below.
Types
| name | type | description |
|---|---|---|
S::count_type |
integral type | represents population counts |
Constants
| name | type | description |
|---|---|---|
S::max_process_order |
unsigned integral type | maximum order of an (elementary) reaction |
S::max_participants |
unsigned integral type | maximum number of distinct populations affected by one reaction |
S::max_instances |
unsigned integral type | maximum number of simulation instances |
S::dynamic_range |
unsigned integral type | maximum (base 2) logarithm of ratios of propensities |
Methods
In the following,
grepresents a uniform random generator, passed by reference,tis of typedouble,sis an unsigned integral value representing a species index,cis an unsigned integral value representing a cell index,kis a population count of typeS::count_type,nis an unsigned integral value representing a number of instances,jis an unsigned integral value representing a particular instance.
| expression | return type | description |
|---|---|---|
s.initialise(n,M,t0) |
set up simulator to simulate n instances of the given rd_model M with initial simulation time t0 |
|
s.count(s,c,j) |
count_type |
population count of species index s in cell c in instance j |
s.count(s,c) |
count_type |
equivalent to s.count(s,c,0) |
s.counts(j) |
implementaiton specific | return population counts of instance j as an iterable collection |
s.set_count(s,c,k,j) |
set population count of species index s in cell c to k in instance j |
|
s.set_count(s,c,k) |
equivalent to s.set_count(s,c,k,0) |
|
s.advance(g) |
double | [optional] advance simulator state by minimum time step, returning new simulation time |
s.advance(t,g) |
double | advance simulator up to time t, returning new simulation time |
Population counts returned by s.counts(j) are ordered such that the population of species s in cell c is stored in the c·S+s element, where S is the number of species. Note that non-const operations on s may invalidate the collection returned by s.counts(j).
SSA selector implementations
Let A denote a class implementing the SSA selector API.
Types
| name | type | description |
|---|---|---|
A::key_type |
implementation specific | keys representing individual procesess |
A::value_type |
floating point type | represents process propensities |
A::event_type |
implementation specific | describes generated process events |
Methods
In the following let a be an instance of A, ac a const instance of A, g a uniform random number generator (see section [rand.req.urng] in C++ standard), n an unsigned integral value, k a value of type A::key_type, r a value of type A::value_type, and ev an event of type A::event_type returned by the next method.
| expression | return type | description |
|---|---|---|
a.reset(n) |
initialise state to represent n processes, with initially zero propensity |
|
a.update(k,r) |
set propensity of process k to r; may throw rdmini::invalid_value |
|
ac.size() |
unsigned integral type | total number of represented processes |
ac.propensity(k) |
A::value_type |
[optional] retrieve propensity of process k; may throw rdmini::invalid_value |
ac.total_propensity() |
A::value_type |
[optional] retrieve propensity of process k; may throw rdmini::invalid_value |
a.next(g) |
A::event_type |
generate next event drawing uniformly distributed numbers from g |
ev.key() |
A::key_type |
identifier of process in event |
ev.dt() |
floating point type | event time delta |
In practice, A::key_type should generally be an unsigned integral type, taking values from the range [0, a.size()).
SSA process system implementation
A process system encapsulates the dependency relations between populations and processes, and maintains the state of populations and processes across one or more independent instances.
For a process system of type Y, instance y.
Types
| name | type | description |
|---|---|---|
Y::key_type |
implementation specific | keys representing individual procesess |
Y::value_type |
floating point type | represents process propensities |
Y::pop_type |
integral type | represents population indices |
Y::count_type |
integral type | represents population counts |
As for an SSA selector, Y::key_type and Y::pop_type should likely be unsigned integral types.
Individual processes are described by a process description p which offers methods according to the following:
| expression | type | description |
|---|---|---|
p.left() |
collection of Y::pop_type |
(multi-)set of population indices consumed by process |
p.right() |
collection of Y::pop_type |
(multi-)set of population indices produced by process |
p.rate() |
Y::value_type |
elementary process rate |
Constants
| name | type | description |
|---|---|---|
Y::max_population_index |
unsigned integral | maximum population index |
Y::max_process_order |
unsigned integral | maximum process order |
Y::max_participants |
unsigned integral | maximum disrinct populations involved in a process |
Y::max_count |
unsigned integral | maximum population count |
Y::max_instances |
integral type | maximum number of system instances |
Methods
In the following,
kis of typeY::key_type, representing a process identifier,pis an unsigned integral value referencing a population,cis of typeY::count_type, representing a population count,qis a process description,b,eform an iterator range of process descriptions,nis an unsigned integral value representing a number of instances,jis an unsigned integral value representing a particular instance,notifyis a function or functional object with signature equivalent tovoid notify(key_type).
| expression | return type | description |
|---|---|---|
y.initialise(n) |
initialise state for n instances and |
|
y.clear() |
remove all processes | |
y.add(q) |
add process with description q |
|
y.add(b,e) |
add processes described by iterator interval [b,e) |
|
y.define_processes(b,e) |
configure system with processes described by iterator interval [b,e) |
|
y.size() |
size_t |
number of processes in system |
y.n_instances() |
size_t |
number of instances |
y.reset() |
zero population counts across all instances | |
y.propensity(k,j) |
Y::value_type |
calculate propensity for process k in instance j |
y.count(p,j) |
Y::count_type |
population count for population p in instance j |
y.count(p) |
Y::count_type |
equivalent to y.count(p,0) |
y.counts(j) |
implementaiton specific | return population counts of instance j as an iterable collection |
y.set_count(p,c,notify,j) |
set count for population p to c in instance j; call notify(u) for each affected process u |
|
y.set_count(p,c,notify) |
equivalent to y.set_count(p,c,notify,0) |
|
y.apply(k,notify,j) |
apply process k to state of instance j; call notify(u) for each affected process u. |
|
y.apply(k,notify) |
equivalent to y.apply(k,notify,0) |
As for an SSA selector, Y::key_type should likely be an unsigned integral type. Adding a process to a process system may or may not preserve population counts — this is a quality of implementation issue.
Note that non-const operations on y may invalidate the collection returned by y.counts(j).