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,
g
represents a uniform random generator, passed by reference,t
is of typedouble
,s
is an unsigned integral value representing a species index,c
is an unsigned integral value representing a cell index,k
is a population count of typeS::count_type
,n
is an unsigned integral value representing a number of instances,j
is 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,
k
is of typeY::key_type
, representing a process identifier,p
is an unsigned integral value referencing a population,c
is of typeY::count_type
, representing a population count,q
is a process description,b
,e
form an iterator range of process descriptions,n
is an unsigned integral value representing a number of instances,j
is an unsigned integral value representing a particular instance,notify
is 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)
.