Skip to contents

Run large-scale (i.e., ensemble) simulations of stock-and-flow models, varying initial conditions and/or constants specified in conditions.

Usage

ensemble(
  object,
  n = 10,
  conditions = NULL,
  cross = TRUE,
  central,
  spread,
  quantiles,
  quiet = FALSE,
  ...
)

Arguments

object

Stock-and-flow model, object of class stockflow.

n

Number of simulations to run in the ensemble. When conditions is specified, n defines the number of simulations to run per condition. If each condition only needs to be run once, set n = 1. Defaults to n = 10.

conditions

A named list specifying fixed values for ensemble conditions. Names must correspond to stocks or constants in the model. Each list element should be a numeric vector of values to test.

If cross = TRUE (default), all combinations of values are generated. For example, list(param1 = c(1, 2), param2 = c(10, 20)) creates 4 conditions: (1,10), (1,20), (2,10), (2,20).

If cross = FALSE, values are paired element-wise, requiring all vectors to have equal length. For example, list(param1 = c(1, 2, 3), param2 = c(10, 20, 30)) creates 3 conditions: (1,10), (2,20), (3,30). Defaults to NULL (no parameter variation).

cross

If TRUE, cross the parameters in the conditions list to generate all possible combinations of parameters. Defaults to TRUE.

central

Which central-tendency statistic(s) to compute across the simulations at each time point: any of "mean", "median", or "none". Each one becomes a column of the same name in summary. Defaults to the model's central setting (see sim_settings()); set it here to override that for this run. Note that central and spread choose what is computed; plot.ensemble_stockflow() then chooses what to show.

spread

Which measures of spread to compute: "quantile" (columns quant1, quant2, ... at the probabilities in quantiles), "sd", "range" (a min and a max column), or "none". Several can be combined, e.g. c("quantile", "sd"). Defaults to the model's spread setting.

quantiles

Probabilities for the quantile columns, used when spread includes "quantile", e.g. c(0.025, 0.975). They become columns quant1, quant2, ... in the order given (so here quant1 is the 2.5% quantile and quant2 the 97.5%); the probabilities themselves are kept in sims$quantiles. Defaults to the model's quantiles setting.

quiet

If TRUE, suppress informational messages such as progress and status updates. Warnings and errors are always shown. Defaults to FALSE. R ensembles show a cli progress bar via progressr::handler_cli(), including when simulations run through a parallel future::plan().

...

Optional arguments passed to sim_settings(); these can be used to override the simulation specifications set in the model object.

Value

Object of class ensemble_stockflow, which is a list containing:

success

If TRUE, simulation was successful. If FALSE, simulation failed.

error_message

If success is FALSE, contains the error message.

df

data.frame with simulation results in long format, if save_sims is TRUE. The iteration number is indicated by column "sim". If conditions was specified, the condition is indicated by column "condition".

summary

data.frame with summary statistics of the ensemble. Contains the statistics requested via central and spread (as columns named after each statistic, plus quant1, quant2, ... when spread includes "quantile"), as well as a missing_count column. If conditions was specified, summary statistics are calculated for each condition in the ensemble.

n

Number of simulations run in the ensemble (per condition if conditions is specified).

n_total

Total number of simulations run in the ensemble (across all conditions if conditions is specified).

n_conditions

Total number of conditions.

conditions

data.frame with the conditions used in the ensemble, if conditions was specified.

init

List with df (if save_sims = TRUE) and summary, containing data.frame with the initial values of the stocks used in the ensemble.

constants

List with df (if save_sims = TRUE) and summary, containing data.frame with the constant parameters used in the ensemble.

script

Script used for the ensemble simulation.

duration

Duration of the simulation in seconds.

...

Other parameters passed to ensemble

Details

It is strongly recommended to reduce the size of the simulation output by saving fewer values with save_by, save_times, or save_length in sim_settings().

By default, only summary statistics across simulations are returned. To return individual simulations, set save_sims = TRUE in sim_settings() or pass save_sims = TRUE via ... in ensemble(). Note that returning individual simulations can consume a lot of memory for large ensembles.

For simulations in Julia, the ensemble can be run in parallel using multiple threads by setting nthreads in use_julia(). For simulations in R, use future::plan() to control parallel execution.

To create a reproducible ensemble simulation, set a seed using sim_settings().

If you do not see any variation within a condition of the ensemble (i.e., the confidence bands are virtually non-existent), there are likely no random elements in your model. Without these, there can be no variability in the model. Try specifying a random initial condition or adding randomness to other model elements (see examples).

Examples

# Ensemble simulation in R (no parallelization)
# Load example
sfm <- stockflow("predator_prey")

# Set random initial conditions
sfm <- update(sfm, c(predator, prey),
  eqn = runif(1, min = 20, max = 80)
)

# For ensemble simulations, it is highly recommended to reduce the
# returned output. For example, to save only 20 values per simulation:
sfm <- sim_settings(sfm, save_length = 20)

# Run ensemble simulation with a small number of simulations
sims <- ensemble(sfm, n = 3)
#> Starting ensemble simulation in "R" with 3 simulations.
#>  Ensemble simulation completed in 1.7592 seconds.
if (interactive()) plot(sims)

# To plot individual trajectories, rerun the ensemble with save_sims = TRUE.
# Note that this can consume a lot of memory for large simulations.
sims <- ensemble(sfm, n = 10, save_sims = TRUE)
#> Starting ensemble simulation in "R" with 10 simulations.
#>  Ensemble simulation completed in 5.8468 seconds.
plot(sims, which = "sims")
# Specify which trajectories to plot plot(sims, which = "sims", sim = 1)
# Plot the median with lighter individual trajectories plot(sims, central = "median", which = "sims", alpha = 0.1)
# For larger ensembles, we can use parallelization with future future::plan(future::multisession, workers = 4) # Ensembles can also be run with exact values for the initial conditions # and parameters. Below, we vary the initial values of the predator and the # birth rate of the predators (delta). We generate a hundred samples per # condition. By default, the parameters are crossed, meaning that all # combinations of the parameters are run. sims <- ensemble(sfm, n = 50, conditions = list(predator = c(10, 50), delta = c(.025, .05)) ) #> Starting ensemble simulation in "R" with 200 simulations in total. #> 4 conditions x 50 simulations per condition. #> Ensemble simulation completed in 47.4199 seconds. plot(sims)
# By default, a maximum of nine conditions is plotted. # Plot specific conditions: plot(sims, condition = c(1, 3), nrows = 1)
# Generate a non-crossed design, where the length of each conditions vector # needs to be equal: sims <- ensemble(sfm, n = 10, cross = FALSE, conditions = list( predator = c(10, 20, 30), delta = c(.020, .025, .03) ) ) #> Starting ensemble simulation in "R" with 30 simulations in total. #> 3 conditions x 10 simulations per condition. #> Ensemble simulation completed in 7.4948 seconds. plot(sims, nrows = 3)
# Stop parallelization after use future::plan(future::sequential)