All "dust" dust models are R6 objects and expose a
common set of "methods". To create a dust model of your own,
see dust and to interact with some built-in ones see
dust_example()
A dust_generator
object
For discrete time models, dust has an internal "time", which was
called step
in version 0.11.x
and below. This must always
be non-negative (i.e., zero or more) and always increases in
unit increments. Typically a model will remap this internal
time onto a more meaningful time in model space, e.g. by applying
the transform model_time = offset + time * dt
; with this approach
you can start at any real valued time and scale the unit increments
to control the model dynamics.
new()
Create a new model. Note that the behaviour of this object
created by this function will change considerably based on
whether the pars_multi
argument is TRUE
. If not (the
default) then we create n_particles
which all share the same
parameters as specified by the pars
argument. If pars_multi
is TRUE
then pars
must be an unnamed list, and each element
of it represents a different set of parameters. We will
create length(pars)
sets of n_particles
particles which
will be simulated together. These particles must have the same
dimension - that is, they must correspond to model state that
is the same size.
dust_generator$new(
pars,
time,
n_particles,
n_threads = 1L,
seed = NULL,
pars_multi = FALSE,
deterministic = FALSE,
gpu_config = NULL,
ode_control = NULL
)
pars
Data to initialise your model with; a list
object, but the required elements will depend on the details of
your model. If pars_multi
is TRUE
, then this must be an
unnamed list of pars
objects (see Details).
time
Initial time - must be nonnegative
n_particles
Number of particles to create - must be at least 1
n_threads
Number of OMP threads to use, if dust
and
your model were compiled with OMP support (details to come).
n_particles
should be a multiple of n_threads
(e.g., if you use 8
threads, then you should have 8, 16, 24, etc particles). However, this
is not compulsory.
seed
The seed to use for the random number generator. Can
be a positive integer, NULL
(initialise with R's random number
generator) or a raw
vector of a length that is a multiple of
32 to directly initialise the generator (e..g., from the
dust
object's $rng_state()
method).
pars_multi
Logical, indicating if pars
should be
interpreted as a set of different initialisations, and that we
should prepare n_particles * length(pars)
particles for
simulation. This has an effect on many of the other methods of
the object.
deterministic
Run random number generation deterministically, replacing a random number from some distribution with its expectation. Deterministic models are not compatible with running on a a GPU.
gpu_config
GPU configuration, typically an integer
indicating the device to use, where the model has GPU support.
If not given, then the default value of NULL
will fall back on the
first found device if any are available. An error is thrown if the
device id given is larger than those reported to be available (note
that CUDA numbers devices from 0, so that '0' is the first device,
and so on). See the method $gpu_info()
for available device ids;
this can be called before object creation as
dust_generator$public_methods$gpu_info()
.
For additional control, provide a list with elements device_id
and run_block_size
. Further options (and validation) of this
list will be added in a future version!
ode_control
For ODE models, control over the integration;
must be a dust_ode_control
model, produced by
dust_ode_control()
. It is an error to provide a non-NULL
value for discrete time models.
param()
Returns parameter information, if provided by the model. This
describes the contents of pars passed to the constructor or to
$update_state()
as the pars
argument, and the details depend
on the model.
simulate()
Iterate all particles forward in time over a series of times,
collecting output as they go. This is a helper around $run()
where you want to run to a series of points in time and save
output. The returned object will be filtered by your active index,
so that it has shape (n_state
x n_particles
x length(time_end)
)
for single-parameter objects, and (n_state
x n_particles
x
n_pars
x length(time_end)
) for multiparameter objects. Note that
this method is very similar to $run()
except that the rank of
the returned array is one less. For a scalar time_end
you would
ordinarily want to use $run()
but the resulting numbers would
be identical.
run_adjoint()
Run model with gradient information (if supported). The interface here will change, and documentation written once it stabilises.
set_index()
Set the "index" vector that is used to return a subset of pars
after using run()
. If this is not used then run()
returns
all elements in your state vector, which may be excessive and slower
than necessary.
ode_control()
Return the ODE control set into the object on creation.
For discrete-time models this always returns NULL
.
ode_statistics()
Return statistics about the integration, for ODE models. For discrete time models this makes little sense and so errors if used.
update_state()
Update one or more components of the model state.
This method can be used to update any or all of pars
, state
and
time
. If both pars
and time
are given and state
is not,
then by default we will update the model internal state according
to your model's initial conditions - use set_initial_state = FALSE
to prevent this.
dust_generator$update_state(
pars = NULL,
state = NULL,
time = NULL,
set_initial_state = NULL,
index = NULL,
reset_step_size = NULL
)
pars
New pars for the model (see constructor)
state
The state vector - can be either a numeric vector with the same length as the model's current state (in which case the same state is applied to all particles), or a numeric matrix with as many rows as your model's state and as many columns as you have particles (in which case you can set a number of different starting states at once).
time
New initial time for the model. If this
is a vector (with the same length as the number of particles), then
particles are started from different initial times and run up to the
largest time given (i.e., max(time)
)
set_initial_state
Control if the model initial state
should be set while setting parameters. It is an error for
this to be TRUE
when either pars
is NULL
or when state
is non-NULL
.
index
Used in conjunction with state
, use this to set a
fraction of the model state; the index
vector provided must
be the same length as the number of provided states, and
indicates the index within the model state that should be updated.
For example, if your model has states [a, b, c, d]
and
you provide an index of [1, 3]
then of state
was [10, 20]
you would set a
to 10 and c
to 20.
reset_step_size
Logical, indicating if we should reset the initial step size. This only has an effect with ode models and is silently ignored in discrete time models where the step size is constant.
time()
Return current model time
For ODE models, sets the schedule at which stochastic events are
handled. The timing here is quite subtle - an event happens
immediately after the time (so at time + eps
). If your model
runs up to time
an event is not triggered, but as soon as that
time is passed, by any amount of time, the event will trigger. It
is an error to set this to a non-NULL
value in a discrete time
model; later we may generalise the approach here.
reorder()
Reorder particles.
resample()
Resample particles according to some weight.
weights
A numeric vector representing particle weights. For a "multi-parameter" dust object this should be be a matrix with the number of rows being the number of particles per parameter set and the number of columns being the number of parameter sets. long as all particles or be a matrix.
info()
Returns information about the pars that your model was created with.
Only returns non-NULL if the model provides a dust_info
template
specialisation.
rng_state()
Returns the state of the random number generator. This returns a
raw vector of length 32 * n_particles. This can be useful for
debugging or for initialising other dust objects. The arguments
first_only
and last_only
are mutually exclusive. If neither is
given then all all particles states are returned, being 32 bytes
per particle. The full returned state or first_only
are most
suitable for reseeding a new dust object.
set_rng_state()
Set the random number state for this model. This replaces the RNG state that the model is using with a state of your choosing, saved out from a different model object. This method is designed to support advanced use cases where it is easier to manipulate the state of the random number generator than the internal state of the dust object.
has_openmp()
Returns a logical, indicating if this model was compiled with
"OpenMP" support, in which case it will react to the n_threads
argument passed to the constructor. This method can also be used
as a static method by running it directly
as dust_generator$public_methods$has_openmp()
has_gpu_support()
Returns a logical, indicating if this model was compiled with
"CUDA" support, in which case it will react to the device
argument passed to the run method. This method can also be used
as a static method by running it directly
as dust_generator$public_methods$has_gpu_support()
has_compare()
Returns a logical, indicating if this model was compiled with
"compare" support, in which case the set_data
and compare_data
methods are available (otherwise these methods will error). This
method can also be used as a static method by running it directly
as dust_generator$public_methods$has_compare()
real_size()
Return the size of real numbers (in bits). Typically this will be
64 for double precision and 32 for float
. This method can also be
used as a static method by running it directly as
dust_generator$public_methods$real_size()
time_type()
Return the type of time this model uses; will be one of discrete
(for discrete time models) or continuous
(for ODE models).
This method can also be used as a static method by running it
directly as dust_generator$public_methods$time_type()
rng_algorithm()
Return the random number algorithm used. Typically this will be
xoshiro256plus
for models using double precision reals and
xoshiro128plus
for single precision (float
). This method can
also be used as a static method by running it directly as
dust_generator$public_methods$rng_algorithm()
n_pars()
Returns the number of distinct pars elements required. This is 0
where the object was initialised with pars_multi = FALSE
and
an integer otherwise. For multi-pars dust objects, Where pars
is accepted, you must provide an unnamed list of length $n_pars()
.
set_n_threads()
Change the number of threads that the dust object will use. Your model must be compiled with "OpenMP" support for this to have an effect. Returns (invisibly) the previous value.
n_threads
The new number of threads to use. You may want to
wrap this argument in dust_openmp_threads()
in order to
verify that you can actually use the number of threads
requested (based on environment variables and OpenMP support).
set_data()
Set "data" into the model for use with the $compare_data()
method.
This is not supported by all models, depending on if they define a
data_type
type. See dust_data()
for a helper function to
construct suitable data and a description of the required format. You
will probably want to use that here, and definitely if using multiple
parameter sets.
compare_data()
Compare the current model state against the data as set by
set_data
. If there is no data set, or no data corresponding to
the current time then NULL
is returned. Otherwise a numeric vector
the same length as the number of particles is returned. If model's
underlying compare_data
function is stochastic, then each call to
this function may be result in a different answer.
filter()
Run a particle filter. The interface here will change a lot over the
next few versions. You must reset the dust object using
$update_state(pars = ..., time = ...)
before using this method to
get sensible values.
dust_generator$filter(
time_end = NULL,
save_trajectories = FALSE,
time_snapshot = NULL,
min_log_likelihood = NULL
)
time_end
The time to run to. If NULL
, run to the end
of the last data. This value must be larger than the current
model time ($time()
) and must exactly appear in the data.
save_trajectories
Logical, indicating if the filtered particle
trajectories should be saved. If TRUE
then the trajectories
element
will be a multidimensional array (state x <shape> x time
)
containing the state values, selected according to the index set
with $set_index()
.
time_snapshot
Optional integer vector indicating times
that we should record a snapshot of the full particle filter state.
If given it must be strictly increasing vector whose elements
match times given in the data
object. The return value with be
a multidimensional array (state x <shape> x time_snapshot
)
containing full state values at the requested times.
min_log_likelihood
Optionally, a numeric value representing
the smallest likelihood we are interested in. If non-NULL
either a scalar value or vector the same length as the number
of parameter sets. Not yet supported, and included for future
compatibility.
gpu_info()
Return information about GPU devices, if the model
has been compiled with CUDA/GPU support. This can be called as a
static method by running dust_generator$public_methods$gpu_info()
.
If run from a GPU enabled object, it will also have an element
config
containing the computed device configuration: the device
id, shared memory and the block size for the run
method on the
device.
# An example dust object from the package:
walk <- dust::dust_example("walk")
# The generator object has class "dust_generator"
class(walk)
#> [1] "dust_generator" "R6ClassGenerator"
# The methods below are are described in the documentation
walk
#> <dust> object generator
#> Public:
#> initialize: function (pars, time, n_particles, n_threads = 1L, seed = NULL,
#> name: function ()
#> param: function ()
#> run: function (time_end)
#> simulate: function (time_end)
#> run_adjoint: function ()
#> set_index: function (index)
#> index: function ()
#> ode_control: function ()
#> ode_statistics: function ()
#> n_threads: function ()
#> n_state: function ()
#> n_particles: function ()
#> n_particles_each: function ()
#> shape: function ()
#> update_state: function (pars = NULL, state = NULL, time = NULL, set_initial_state = NULL,
#> state: function (index = NULL)
#> time: function ()
#> set_stochastic_schedule: function (time)
#> reorder: function (index)
#> resample: function (weights)
#> info: function ()
#> pars: function ()
#> rng_state: function (first_only = FALSE, last_only = FALSE)
#> set_rng_state: function (rng_state)
#> has_openmp: function ()
#> has_gpu_support: function (fake_gpu = FALSE)
#> has_compare: function ()
#> real_size: function ()
#> time_type: function ()
#> rng_algorithm: function ()
#> uses_gpu: function (fake_gpu = FALSE)
#> n_pars: function ()
#> set_n_threads: function (n_threads)
#> set_data: function (data, shared = FALSE)
#> compare_data: function ()
#> filter: function (time_end = NULL, save_trajectories = FALSE, time_snapshot = NULL,
#> gpu_info: function ()
#> Private:
#> pars_: NULL
#> pars_multi_: NULL
#> index_: NULL
#> info_: NULL
#> n_threads_: NULL
#> n_particles_: NULL
#> n_particles_each_: NULL
#> shape_: NULL
#> ptr_: NULL
#> gpu_config_: NULL
#> ode_control_: NULL
#> methods_: NULL
#> param_: NULL
#> reload_: NULL
#> Parent env: <environment: namespace:dust>
#> Locked objects: TRUE
#> Locked class: FALSE
#> Portable: TRUE