% Generated by roxygen2: do not edit by hand
% Please edit documentation in R/ensemble.R
\name{ensemble}
\alias{ensemble}
\title{Run ensemble simulation}
\usage{
ensemble(
  object,
  n = 10,
  conditions = NULL,
  cross = TRUE,
  central,
  spread,
  quantiles,
  quiet = FALSE,
  ...
)
}
\arguments{
\item{object}{Stock-and-flow model, object of class \code{\link{stockflow}}.}

\item{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 \code{n = 1}. Defaults to \code{n = 10}.}

\item{conditions}{A named list specifying \strong{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 = \code{TRUE} (default), all combinations of values are generated. For
example, \code{list(param1 = c(1, 2), param2 = c(10, 20))} creates 4 conditions:
\verb{(1,10), (1,20), (2,10), (2,20)}.

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

\item{cross}{If \code{TRUE}, cross the parameters in the conditions list to
generate all possible combinations of parameters. Defaults to \code{TRUE}.}

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

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

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

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

\item{...}{Optional arguments passed to \code{\link[=sim_settings]{sim_settings()}}; these can be used to override the simulation specifications set in the model object.}
}
\value{
Object of class \code{\link[=ensemble]{ensemble_stockflow}}, which is a list
containing:
\describe{
\item{success}{If \code{TRUE}, simulation was successful. If \code{FALSE}, simulation
failed.}

\item{error_message}{If success is \code{FALSE}, contains the error message.}
\item{df}{data.frame with simulation results in long format, if save_sims
is \code{TRUE}. The iteration number is indicated by column "sim". If conditions
was specified, the condition is indicated by column "condition".}
\item{summary}{data.frame with summary statistics of the ensemble. Contains
the statistics requested via \code{central} and \code{spread} (as columns named after
each statistic, plus \code{quant1}, \code{quant2}, ... when \code{spread} includes
\code{"quantile"}), as well as a \code{missing_count} column. If conditions was
specified, summary statistics are calculated for each condition in the
ensemble.}
\item{n}{Number of simulations run in the ensemble (per condition if
conditions is specified).}
\item{n_total}{Total number of simulations run in the ensemble (across all
conditions if conditions is specified).}
\item{n_conditions}{Total number of conditions.}
\item{conditions}{data.frame with the conditions used in the ensemble, if
conditions was specified.}
\item{init}{List with df (if save_sims = TRUE) and summary, containing
data.frame with the initial values of the stocks used in the ensemble.}
\item{constants}{List with df (if save_sims = TRUE) and summary,
containing data.frame with the constant parameters used in the ensemble.}
\item{script}{Script used for the ensemble simulation.}
\item{duration}{Duration of the simulation in seconds.}
\item{...}{Other parameters passed to ensemble}
}
}
\description{
Run large-scale (i.e., ensemble) simulations of stock-and-flow models, varying initial
conditions and/or constants specified in \code{conditions}.
}
\details{
It is strongly recommended to reduce the size of the simulation output by
saving fewer values with \code{save_by}, \code{save_times}, or \code{save_length} in
\code{\link[=sim_settings]{sim_settings()}}.

By default, only summary statistics across simulations are returned.
To return individual simulations, set \code{save_sims = TRUE} in \code{\link[=sim_settings]{sim_settings()}} or
pass \code{save_sims = TRUE} via \code{...} in \code{\link[=ensemble]{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 \code{nthreads} in \code{\link[=use_julia]{use_julia()}}. For simulations in R, use
\code{\link[future:plan]{future::plan()}} to control parallel execution.

To create a reproducible ensemble simulation, set a seed using \code{\link[=sim_settings]{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 model
sfm <- stockflow("predator_prey")

# Ensemble simulations can only show variation 
# if there is some randomness in the model. 
# For example, we can initialize both stocks with
# random values between 20 and 80:
sfm <- update(sfm, c(predator, prey),
  eqn = runif(1, min = 20, max = 80)
)

# Saving all timepoints is computationally expensive, 
# so we save only 20 values per simulation:
sfm <- sim_settings(sfm, save_length = 20)

# Run ensemble simulation
sims <- ensemble(sfm, n = 3)
plot(sims)

\dontshow{if (Sys.getenv("NOT_CRAN") == "true") withAutoprint(\{ # examplesIf}
# 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)
plot(sims, which = "sims")

# Specify which trajectories to plot
plot(sims, which = "sims", sim = 1:2)

# Don't plot the central tendency 
# with darker individual trajectories
plot(sims, central = "none", which = "sims", alpha = 0.7)

# We can speed up ensemble simulations using parallelization
future::plan(future::multisession, workers = 2)
sims <- ensemble(sfm, n = 25, save_sims = TRUE)

# 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))
)

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)
  )
)
plot(sims, nrows = 3)

# Stop parallelization after use
future::plan(future::sequential)
\dontshow{\}) # examplesIf}
}
\seealso{
\code{\link[=update]{update()}}, \code{\link[=stockflow]{stockflow()}}, \code{\link[=sim_settings]{sim_settings()}}, \code{\link[=use_julia]{use_julia()}},
\code{\link[future:plan]{future::plan()}}
}
\concept{ensemble}
