R/dust_generator.R

## DO NOT EDIT THIS FILE!
## Instead, edit the file inst/template/dust.R.template
## and run ./scripts/update_dust_generator

## NOTE: R6 classes do not support interfaces and inheritence is not
## really needed here as this does not *do* anything, so consider this
## a hack to allow Roxygen's R6 documentation to work.

## The code and object below have exactly the interface of all generated
## dust objects, and this page acts as a reference for all such methods
## modelled on the ?regex page in base R's documentation
##' @name dust_generator
##' @rdname dust_generator
##' @title The dust class
##'
##' @description
##'
##' All "dust" dust models are [R6][R6::R6Class] objects and expose a
##'   common set of "methods".  To create a dust model of your own,
##'   see [dust::dust] and to interact with some built-in ones see
##'   [dust::dust_example()]
##'
##' @section Time:
##'
##' 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.
##'
##' @return A `dust_generator` object
##'
##' @examples
##' # An example dust object from the package:
##' walk <- dust::dust_example("walk")
##'
##' # The generator object has class "dust_generator"
##' class(walk)
##'
##' # The methods below are are described in the documentation
##' walk
dust_generator <- R6::R6Class(
  "dust",
  cloneable = FALSE,

  private = list(
    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
  ),

  public = list(
    ##' @description
    ##' 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.
    ##'
    ##' @param 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).
    ##'
    ##' @param time Initial time - must be nonnegative
    ##'
    ##' @param n_particles Number of particles to create - must be at
    ##' least 1
    ##'
    ##' @param 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.
    ##'
    ##' @param 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).
    ##'
    ##' @param 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.
    ##'
    ##' @param 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.
    ##'
    ##' @param 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!
    ##'
    ##' @param ode_control For ODE models, control over the integration;
    ##' must be a `dust_ode_control` model, produced by
    ##' [dust::dust_ode_control()]. It is an error to provide a non-`NULL`
    ##' value for discrete time models.
    initialize = function(pars, time, n_particles, n_threads = 1L,
                          seed = NULL, pars_multi = FALSE,
                          deterministic = FALSE,
                          gpu_config = NULL, ode_control = NULL) {
    },

    ##' @description
    ##' Returns friendly model name
    name = function() {
    },

    ##' @description
    ##' 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.
    param = function() {
    },

    ##' @description
    ##' Run the model up to a point in time, returning the filtered state
    ##' at that point.
    ##'
    ##' @param time_end Time to run to (if less than or equal to the current
    ##'   time(), silently nothing will happen)
    run = function(time_end) {
    },

    ##' @description
    ##' 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.
    ##'
    ##' @param time_end A vector of time points that the simulation should
    ##'   report output at. This the first time must be at least the same
    ##'   as the current time, and every subsequent time must be equal or
    ##'   greater than those before it (ties are allowed though probably
    ##'   not wanted).
    simulate = function(time_end) {
    },

    ##' @description
    ##'
    ##' Run model with gradient information (if supported). The
    ##' interface here will change, and documentation written once it
    ##' stabilises.
    run_adjoint = function() {
    },

    ##' @description
    ##' 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.
    ##'
    ##' @param index The index vector - must be an integer vector with
    ##' elements between 1 and the length of the state (this will be
    ##' validated, and an error thrown if an invalid index is given).
    set_index = function(index) {
    },

    ##' @description
    ##' Returns the `index` as set by `$set_index`
    index = function() {
    },

    ##' @description
    ##' Return the ODE control set into the object on creation.
    ##' For discrete-time models this always returns `NULL`.
    ode_control = function() {
    },

    ##' @description
    ##' Return statistics about the integration, for ODE models.
    ##' For discrete time models this makes little sense and so errors
    ##' if used.
    ode_statistics = function() {
    },

    ##' @description
    ##' Returns the number of threads that the model was constructed with
    n_threads = function() {
    },

    ##' @description
    ##' Returns the length of the per-particle state
    n_state = function() {
    },

    ##' @description
    ##' Returns the number of particles
    n_particles = function() {
    },

    ##' @description
    ##' Returns the number of particles per parameter set
    n_particles_each = function() {
    },

    ##' @description
    ##' Returns the shape of the particles
    shape = function() {
    },

    ##' @description 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.
    ##'
    ##' @param pars New pars for the model (see constructor)
    ##'
    ##' @param 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)`)
    ##'
    ##' @param 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).
    ##'
    ##' @param 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`.
    ##'
    ##' @param 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.
    ##'
    ##' @param 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.
    update_state = function(pars = NULL, state = NULL, time = NULL,
                            set_initial_state = NULL, index = NULL,
                            reset_step_size = NULL) {
    },

    ##' @description
    ##' Return full model state
    ##' @param index Optional index to select state using
    state = function(index = NULL) {
    },

    ##' @description
    ##' Return current model time
    time = function() {
    },

    ##' 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.
    ##'
    ##' @param time A vector of times to run the stochastic update at
    set_stochastic_schedule = function(time) {
    },

    ##' @description
    ##' Reorder particles.
    ##' @param index An integer vector, with values between 1 and n_particles,
    ##' indicating the index of the current particles that new particles should
    ##' take.
    reorder = function(index) {
    },

    ##' @description
    ##' Resample particles according to some weight.
    ##'
    ##' @param 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.
    resample = function(weights) {
    },

    ##' @description
    ##' Returns information about the pars that your model was created with.
    ##' Only returns non-NULL if the model provides a `dust_info` template
    ##' specialisation.
    info = function() {
    },

    ##' @description
    ##' Returns the `pars` object that your model was constructed with.
    pars = function() {
    },

    ##' @description
    ##' 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.
    ##'
    ##' @param first_only Logical, indicating if we should return only the
    ##'   first random number state
    ##'
    ##' @param last_only Logical, indicating if we should return only the
    ##' *last* random number state, which does not belong to a particle.
    rng_state = function(first_only = FALSE, last_only = FALSE) {
    },

    ##' @description 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.
    ##'
    ##' @param rng_state A random number state, as saved out by the
    ##' `$rng_state()` method. Note that unlike `seed` as passed to the
    ##' constructor, this *must* be a raw vector of the expected length.
    set_rng_state = function(rng_state) {
    },

    ##' @description
    ##' 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_openmp = function() {
    },

    ##' @description
    ##' 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()`
    ##'
    ##' @param fake_gpu Logical, indicating if we count as `TRUE`
    ##'   models that run on the "fake" GPU (i.e., using the GPU
    ##'   version of the model but running on the CPU)
    has_gpu_support = function(fake_gpu = FALSE) {
    },

    ##' @description
    ##' 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()`
    has_compare = function() {
    },

    ##' @description
    ##' 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()`
    real_size = function() {
    },

    ##' @description
    ##' 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()`
    time_type = function() {
    },

    ##' @description
    ##' 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()`
    rng_algorithm = function() {
    },

    ##' @description
    ##' Check if the model is running on a GPU
    ##' @param fake_gpu Logical, indicating if we count as `TRUE`
    ##'   models that run on the "fake" GPU (i.e., using the GPU
    ##'   version of the model but running on the CPU)
    uses_gpu = function(fake_gpu = FALSE) {
    },

    ##' @description
    ##' 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()`.
    n_pars = function() {
    },

    ##' @description
    ##' 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.
    ##'
    ##' @param n_threads The new number of threads to use. You may want to
    ##'   wrap this argument in [dust::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_n_threads = function(n_threads) {
    },

    ##' @description
    ##' 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::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.
    ##'
    ##' @param data A list of data to set.
    ##'
    ##' @param shared Logical, indicating if the data should be shared
    ##'   across all parameter sets, if your model is initialised to use
    ##'   more than one parameter set (`pars_multi = TRUE`).
    set_data = function(data, shared = FALSE) {
    },

    ##' @description
    ##' 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.
    compare_data = function() {
    },

    ##' @description
    ##' 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.
    ##'
    ##' @param 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.
    ##'
    ##' @param 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()`.
    ##'
    ##' @param 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.
    ##'
    ##' @param 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.
    filter = function(time_end = NULL, save_trajectories = FALSE,
                      time_snapshot = NULL, min_log_likelihood = NULL) {
    },

    ##' @description
    ##' 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.
    gpu_info = function() {
    }
  ))
class(dust_generator) <- c("dust_generator", class(dust_generator))
mrc-ide/dust documentation built on May 11, 2024, 1:08 p.m.