Solve a replicate set of difference (or recurrence) equation by iterating it a number of times. This is a wrapper around difeq that does not (yet) do anything clever to avoid many allocations.

difeq_replicate(n, y, steps, target, parms, ..., n_out = 0L,
  n_history = 0L, grow_history = FALSE, return_history = n_history > 0,
  dllname = "", parms_are_real = TRUE, ynames = NULL, outnames = NULL,
  return_by_column = TRUE, return_initial = TRUE, return_step = TRUE,
  return_output_with_y = TRUE, restartable = FALSE,
  return_minimal = FALSE, as_array = TRUE)

Arguments

n

Number of replicates. It is an error to request zero replicates.

y

The initial state of the system. Must be either a numeric vector or a list of numeric vectors. If the latter, it must have length n.

steps

A vector of steps to return the system at. The first step is taken as step zero, and the solution will be recorded at every other step in the vector. So to step a system from time zero to times 1, 2, 3, ..., n use 0:n. Must be integer values and will be passed through as.integer (which may truncate or otherwise butcher non-integer values).

target

The target function to advance. This can either be an R function taking arguments n, i, t, y, parms or be a scalar character with the name of a compiled function with arguments size_t n, size_t step, double time, const double *y, double *dydt, size_t n_out, double *output void *data.

parms

Parameters to pass through to the difference function

...

Dummy arguments - nothing is allowed here, but this means that all further arguments must be specified by name (not order) so I can easily reorder them later on.

n_out

The number of output variables (in addition to the difference equation variables). If given, then an R function must return an attribute output with the output variables.

n_history

The number of iterations of history to save during the simulation. By default, no history is saved.

grow_history

Logical indicating if history should be grown during the simulation. If FALSE (the default) then when history is used it is overwritten as needed (so only the most recent n_history elements are saved. This may require some tuning so that you have enough history to run your simulation (i.e. to the longest delay) or an error will be thrown when it underflows. The required history length will vary with your delay sizes and with the timestep for dopri. If TRUE, then history will grow as the buffer is exhausted. The growth is geometric, so every time it reaches the end of the buffer it will increase by a factor of about 1.6 (see the ring documentation). This may consume more memory than necessary, but may be useful where you don't want to care about picking the history length carefully.

return_history

Logical indicating if history is to be returned. By default, history is returned if n_history is nonzero.

dllname

Name of the shared library (without extension) to find the function func in the case where func refers to compiled function.

parms_are_real

Logical, indicating if parms should be treated as vector of doubles by func (when it is a compiled function). If TRUE (the default), then REAL(parms), which is double* is passed through. If FALSE then if params is an externalptr type (EXTPTRSXP) we pass through the result of R_ExternalPtrAddr, otherwise we pass params through unmodified as a SEXP. In the last case, in your target function you will need to include <Rinternals.h>, cast to SEXP and then pull it apart using the R API (or Rcpp).

ynames

Logical, indicating if the output should be named following the names of the input vector y. Alternatively, if ynames is a character vector of the same length as y, these will be used as the output names.

outnames

An optional character vector, used when n_out is greater than 0, to name the model output matrix.

return_by_column

Logical, indicating if the output should be returned organised by column (rather than row). This incurs a slight cost for transposing the matrices. If you can work with matrices that are transposed relative to deSolve, then set this to FALSE.

return_initial

Logical, indicating if the output should include the initial conditions. Specifying FALSE avoids binding this onto the output.

return_step

Logical, indicating if a row (or column if return_by_column is TRUE) representing step is included.

return_output_with_y

Logical, indicating if the output should be bound together with the returned matrix y (as it is with deSolve). If FALSE, then output will be returned as the attribute output.

restartable

Logical, indicating if the problem should be restartable. If TRUE, then the return value of a simulation can be passed to difeq_restart to continue the simulation after arbitrary changes to the state or the parameters. Note that this is really only useful for delay difference equations where you want to keep the history but make changes to the parameters or to the state vector while keeping the history of the problem so far.

return_minimal

Shorthand option - if set to TRUE then it sets all of return_by_column, return_initial, return_time, return_output_with_y to FALSE

as_array

(Defunct) Logical, indicating if the output should be converted into an array. If TRUE then res[, , i] will contain the i'th replicate, if FALSE then res[[i]] does instead. If both as_array and restartable are TRUE, then the attributes ptr and restart_data will be present as a list of restarting information for difeq_continue, though using these is not yet supported.

Details

It is not currently possible to replicate over a set of parameters at once yet; the same parameter set will be used for all replications.

The details of how replication is done here are all considered implementation details and are up for change in the future - in particular if the models are run in turn or simultaneously (and the effect that has on the random number stream). Logic around naming output may change in future too; note that varying names in the y here will have some unexpected behaviours.

Examples


# Here is a really simple equation that does a random walk with
# steps that are normally distributed:
rhs <- function(i, y, p) y + runif(1)
y0 <- 1
t <- 0:10
p <- 5
dde::difeq_replicate(10, y0, t, rhs, p)
#> , , 1
#> 
#>       [,1]     [,2]
#>  [1,]    0 1.000000
#>  [2,]    1 1.346696
#>  [3,]    2 1.656572
#>  [4,]    3 2.117793
#>  [5,]    4 3.113101
#>  [6,]    5 3.595671
#>  [7,]    6 4.372220
#>  [8,]    7 5.097078
#>  [9,]    8 5.667731
#> [10,]    9 6.155535
#> [11,]   10 6.229562
#> 
#> , , 2
#> 
#>       [,1]     [,2]
#>  [1,]    0 1.000000
#>  [2,]    1 1.523684
#>  [3,]    2 2.126881
#>  [4,]    3 2.877026
#>  [5,]    4 3.426866
#>  [6,]    5 3.429946
#>  [7,]    6 3.653029
#>  [8,]    7 3.733508
#>  [9,]    8 4.304087
#> [10,]    9 4.961662
#> [11,]   10 5.514447
#> 
#> , , 3
#> 
#>       [,1]     [,2]
#>  [1,]    0 1.000000
#>  [2,]    1 1.106547
#>  [3,]    2 1.134196
#>  [4,]    3 2.030247
#>  [5,]    4 2.481188
#>  [6,]    5 2.823182
#>  [7,]    6 2.827926
#>  [8,]    7 3.241826
#>  [9,]    8 3.347699
#> [10,]    9 3.782861
#> [11,]   10 4.119099
#> 
#> , , 4
#> 
#>       [,1]     [,2]
#>  [1,]    0 1.000000
#>  [2,]    1 1.636278
#>  [3,]    2 1.978811
#>  [4,]    3 2.407710
#>  [5,]    4 3.330227
#>  [6,]    5 3.820007
#>  [7,]    6 4.303634
#>  [8,]    7 4.877835
#>  [9,]    8 5.663112
#> [10,]    9 6.234946
#> [11,]   10 7.080461
#> 
#> , , 5
#> 
#>       [,1]     [,2]
#>  [1,]    0 1.000000
#>  [2,]    1 1.641920
#>  [3,]    2 1.758895
#>  [4,]    3 1.982820
#>  [5,]    4 2.107842
#>  [6,]    5 2.976428
#>  [7,]    6 3.651655
#>  [8,]    7 4.586064
#>  [9,]    8 5.386660
#> [10,]    9 5.923488
#> [11,]   10 6.439892
#> 
#> , , 6
#> 
#>       [,1]     [,2]
#>  [1,]    0 1.000000
#>  [2,]    1 1.303148
#>  [3,]    2 1.893953
#>  [4,]    3 2.425844
#>  [5,]    4 2.897208
#>  [6,]    5 3.212800
#>  [7,]    6 3.736451
#>  [8,]    7 4.110842
#>  [9,]    8 4.710226
#> [10,]    9 4.891088
#> [11,]   10 5.846115
#> 
#> , , 7
#> 
#>       [,1]     [,2]
#>  [1,]    0 1.000000
#>  [2,]    1 1.710117
#>  [3,]    2 1.947559
#>  [4,]    3 2.073728
#>  [5,]    4 2.883155
#>  [6,]    5 3.815878
#>  [7,]    6 4.109913
#>  [8,]    7 4.664577
#>  [9,]    8 5.611512
#> [10,]    9 6.072596
#> [11,]   10 6.366919
#> 
#> , , 8
#> 
#>       [,1]     [,2]
#>  [1,]    0 1.000000
#>  [2,]    1 1.459911
#>  [3,]    2 1.691268
#>  [4,]    3 2.443860
#>  [5,]    4 3.141154
#>  [6,]    5 3.981862
#>  [7,]    6 4.267355
#>  [8,]    7 4.282768
#>  [9,]    8 4.604796
#> [10,]    9 4.861247
#> [11,]   10 5.762426
#> 
#> , , 9
#> 
#>       [,1]     [,2]
#>  [1,]    0 1.000000
#>  [2,]    1 1.262155
#>  [3,]    2 1.695445
#>  [4,]    3 1.843536
#>  [5,]    4 2.552954
#>  [6,]    5 3.084169
#>  [7,]    6 3.445506
#>  [8,]    7 3.542876
#>  [9,]    8 4.488070
#> [10,]    9 5.053442
#> [11,]   10 5.327216
#> 
#> , , 10
#> 
#>       [,1]     [,2]
#>  [1,]    0 1.000000
#>  [2,]    1 1.934519
#>  [3,]    2 2.432702
#>  [4,]    3 3.043865
#>  [5,]    4 3.717686
#>  [6,]    5 4.534212
#>  [7,]    6 5.120800
#>  [8,]    7 5.604352
#>  [9,]    8 6.149778
#> [10,]    9 6.592085
#> [11,]   10 7.193246
#>