param_project.RdAdd time-based random deviates / projections
g3_param_project_dlnorm(
lmean_f = g3_parameterized("proj.dlnorm.mean",
value = 1e-5, optimise = FALSE, type = "LOG",
prepend_extra = quote(param_name) ),
lstddev_f = g3_parameterized("proj.dlnorm.stddev",
value = 0.2, optimise = FALSE, type = "LOG",
prepend_extra = quote(param_name) ),
from_year_f = NULL,
to_year_f = NULL )
g3_param_project_dnorm(
mean_f = g3_parameterized("proj.dnorm.mean",
value = 0, optimise = FALSE,
prepend_extra = quote(param_name) ),
stddev_f = g3_parameterized("proj.dnorm.stddev",
value = 1, optimise = FALSE,
prepend_extra = quote(param_name) ),
from_year_f = NULL,
to_year_f = NULL )
g3_param_project_rwalk(
mean_f = g3_parameterized("proj.rwalk.mean",
value = 0, optimise = FALSE,
prepend_extra = quote(param_name) ),
stddev_f = g3_parameterized("proj.rwalk.stddev",
value = 1, optimise = FALSE,
prepend_extra = quote(param_name) ))
g3_param_project_ar1(
phi_f = g3_parameterized(
"proj.ar1.phi",
value = 0.8, lower = 0, upper = 1, optimise = FALSE,
prepend_extra = quote(param_name) ),
stddev_f = g3_parameterized(
"proj.ar1.stddev",
value = 1, optimise = FALSE,
prepend_extra = quote(param_name) ),
level_f = g3_parameterized(
"proj.ar1.level",
value = 0,
prepend_extra = quote(param_name) ),
from_year_f = NULL,
to_year_f = NULL )
g3_param_project_logar1(
phi_f = g3_parameterized(
"proj.logar1.phi",
value = 0.8, lower = 0, upper = 1, optimise = FALSE,
prepend_extra = quote(param_name) ),
lstddev_f = g3_parameterized(
"proj.logar1.stddev",
value = 0.2, optimise = FALSE, type = "LOG",
prepend_extra = quote(param_name) ),
loglevel_f = g3_parameterized(
"proj.logar1.level",
value = 1, type = "LOG",
prepend_extra = quote(param_name) ),
from_year_f = NULL,
to_year_f = NULL )
g3_param_project_bootstrap(
from_year_f = quote(start_year),
to_year_f = quote(end_year),
block_size_f = 1L )
g3_param_project(
param_name,
project_fs = g3_param_project_rwalk(),
by_step = TRUE,
by_stock = FALSE,
weight = g3_parameterized(
paste("proj", project_fs$name, param_name, "weight", sep = "_"),
optimise = FALSE, value = 1),
scale = 1,
offset = 0,
random = TRUE )mean / stddev in normal / logspace used for both the likelihood of deviates & to project future values.
Defaults to parameters with names (by_stock).(param_name).proj.(mean|stddev)
(logspace) level (or offset) applied on top of ar1/logar1 regression.
Defaults to parameter with name (by_stock).(param_name).proj.(level|loglevel),
First / last year (inclusive) of existing values to sample from (g3_param_project_bootstrap),
or to use the mean of (g3_param_project_dlnorm, g3_param_project_dnorm,
g3_param_project_ar1, g3_param_project_logar1).
Years from to_year_f onwards that are projected (e.g. removed by retro_years) are never used.
For g3_param_project_bootstrap, defaults to the whole non-projected model period.
For the others, defaults to NULL, i.e. use lmean_f / mean_f / level_f / loglevel_f.
If either is set, lmean_f / mean_f / level_f / loglevel_f is ignored,
and the other defaults to the start / end of the model period.
Number of consecutive years to copy for each sample, i.e. a block bootstrap. Defaults to 1L, i.e. each year sampled independently.
Character string used to name the parameters.
Results of either g3_param_project_dnorm, g3_param_project_rwalk.
Boolean, generate per-step or per-year values.
Prepend stock name to the projection variable, i.e. param_name.
Unlike g3_parameterized, can only be FALSE or g3_stock objects,
TRUE or "species" isn't supported.
A weighting to give to the likelhood when generating total nll.
Number, formula or string. Scale / offset to add to parameter values.
If string, then the scale/offset will also be a parameter, equivalent to setting
scale = g3_parameterized(c(param_name, "proj", "scale")).
Boolean, tell TMB to treat the deviates as random variables by default. Can be changed in the parameter template.
The actions will define the following variables in your model, which could be reported with g3a_report_history:
Vector of all values, both parameters & projected, by time
Vector of all values, both parameters & projected, by time (logarithmic scale)
Likelihood of each value
Returns a "nll" & "project" formula objects for use as project_fs.
The functions compare / generate normally-distributed deviates around a mean, i.e: $$ V_t = \epsilon_{M - \frac{e^{2*\Sigma}}{2},\Sigma} $$ $$ v = exp(V) $$
lmean_f / (by_stock).(param_name).proj.lmean parameter,
or if from_year_f / to_year_f are set, \(log(mean(v_t))\) for existing values between them
lstddev_f / (by_stock).(param_name).proj.lstddev parameter
Normally distributed noise generated using rnorm
Output time series
With from_year_f / to_year_f and a lstddev_f of 0 (i.e. \(\Sigma = -\infty\)), projected values are a constant arithmetic mean of existing values. The nll is then infinite, so this is only useful for projections, not fitting. When computing nll, the mean also includes any projected values within from_year_f / to_year_f.
Compare values against dnorm(x, mean_f, stddev_f)
Generate new values with rnorm(mean_f, stddev_f)
Returns a "nll" & "project" formula objects for use as project_fs.
The functions compare / generate log-normal deviates around a mean, i.e: $$ v_t = \epsilon_{\mu,\sigma} $$
mean_f / (by_stock).(param_name).proj.mean parameter,
or if from_year_f / to_year_f are set, the mean of existing values between them
stddev_f / (by_stock).(param_name).proj.stddev parameter
Normally distributed noise generated using rnorm
Output time series
With from_year_f / to_year_f and a stddev_f of 0, projected values are a constant mean of existing values. The nll is then infinite, so this is only useful for projections, not fitting. When computing nll, the mean also includes any projected values within from_year_f / to_year_f.
Compare values against dnorm(x, mean_f, stddev_f)
Generate new values with rnorm(mean_f, stddev_f)
Returns a "nll" & "project" formula objects for use as project_fs.
The functions compare / generate to a random walk, i.e: $$ v_t = v_{t-1} + \epsilon_{\mu,\sigma} $$
mean_f / (by_stock).(param_name).proj.mean parameter
stddev_f / (by_stock).(param_name).proj.stddev parameter
Normally distributed noise generated using rnorm
Output time series
Compare difference between values dnorm(x, mean_f, stddev_f)
Generate new values with a delta of rnorm(mean_f, stddev_f)
Returns a "nll" & "project" formula objects for use as project_fs.
The functions compare / generate a AR1 process projecting from any existing values, i.e: $$ v_t = \phi v_{t-1} + (1 - \phi) \theta + \epsilon_{0,\sigma} $$
phi_f / (by_stock).(param_name).proj.phi parameter
level_f / (by_stock).(param_name).proj.level parameter,
or if from_year_f / to_year_f are set, the mean of existing values between them
stddev_f / (by_stock).(param_name).proj.stddev parameter, if 0 1e-7 is used, so we don't return Inf
Normally distributed noise generated using rnorm
Output time series
Returns a "nll" & "project" formula objects for use as project_fs.
The functions compare / generate a log-AR1 process projecting from any existing values, i.e: $$ V_t = \Phi V_{t-1} + (1 - \Phi) \Theta + \epsilon_{0 - \frac{e^{2*\Sigma}}{2},\Sigma} $$ $$ v = exp(V) $$
phi_f / (by_stock).(param_name).proj.phi parameter
loglevel_f / (by_stock).(param_name).proj.loglevel parameter,
or if from_year_f / to_year_f are set, \(log(mean(v_t))\) for existing values between them
lstddev_f / (by_stock).(param_name).proj.lstddev parameter, if 0 1e-7 is used, so we don't return Inf
Normally distributed noise generated using rnorm
Output time series
Returns a "nll" & "project" formula objects for use as project_fs.
Projected values are generated by resampling blocks of block_size_f consecutive years from existing values between from_year_f and to_year_f, i.e: $$ v_{t+j} = v_{s+j} \quad j = 0 .. b - 1 $$
Random start year, chosen uniformly between from_year_f & \(to_year_f - b + 1\) using runif
block_size_f, or the number of years between from_year_f & to_year_f if smaller
Output time series
i.e. a moving block bootstrap, as tseries::tsbootstrap(type = "block").
Blocks never extend past to_year_f, so years at either end of the pool are sampled less often.
Whole years are copied, so if by_step = TRUE the per-step values within a year are preserved.
0, i.e. no likelihood
Generate new values by resampling existing values
Returns a formula to choose the current value from the __var / __lvar vector.
An extra G3 action will:
Populate the array with random deviates from parameters (see examples)
Project for any projection years (see g3a_time)
Add likelihood comparing random deviates to expected values
Returns a formula for use as function_f:
$$ \sum_{\it i}^{rows} w (\frac{\nu_{i}}{P_{i}} - N_{i})^2 $$
"mean" column from obs_df
Total predicted values, i.e. nll_spabund_name__model_sum
Number of data points, i.e. nll_spabund_name__model_n
weighting parameter, either:
\(1 / \sigma^2\), using stddev of model predicted values if weighting = "model_stddev"
\(1 / \sigma^2\), using stddev column from obs_df if weighting = "obs_stddev"
A custom forumla provided for weighting
st <- list(
imm = g3_stock(c("fish", maturity = "imm"), c(10, 20, 30)),
mat = g3_stock(c("fish", maturity = "mat"), c(10, 20, 30)) )
st2 <- g3_stock("other", c(10, 20, 30))
# Set up a projected parameter to share over both stocks
st_Mdn <- g3_param_project(
"Mdn",
g3_param_project_dnorm(),
# Append common part of stock names to parameter name
by_stock = st )
actions <- list(
g3a_time(1990, 1994, c(6,6)),
gadget3:::g3a_initialconditions_manual(st$imm,
quote( 100 + stock__minlen ),
quote( 1e4 + 0 * stock__minlen ) ),
gadget3:::g3a_initialconditions_manual(st$mat,
quote( 100 + stock__minlen ),
quote( 1e4 + 0 * stock__minlen ) ),
gadget3:::g3a_initialconditions_manual(st2,
quote( 100 + stock__minlen ),
quote( 1e4 + 0 * stock__minlen ) ),
# Natural mortality with per-step deviates
g3a_naturalmortality(st$imm, g3a_naturalmortality_exp(st_Mdn)),
g3a_naturalmortality(st$mat, g3a_naturalmortality_exp(st_Mdn)),
# Natural mortality with per-year random walk
g3a_naturalmortality(st2, g3a_naturalmortality_exp(
g3_param_project(
"Mrw",
g3_param_project_rwalk(),
# The same value will be used for each step
by_step = FALSE,
# by_stock means the stock name will be included in parameter names
by_stock = st2 ))),
NULL )
model_fn <- g3_to_r(c(actions, list(
g3a_report_history(actions, 'proj_.*', out_prefix = NULL),
NULL )))
# Mdn has a parameter for each year/step, as well as mean/sd (added above) & likelihood weighting
grep("^fish.Mdn", names(attr(model_fn, 'parameter_template')), value = TRUE)
#> [1] "fish.Mdn.proj.dnorm.mean" "fish.Mdn.proj.dnorm.stddev"
#> [3] "fish.Mdn.1990.1" "fish.Mdn.1991.1"
#> [5] "fish.Mdn.1992.1" "fish.Mdn.1993.1"
#> [7] "fish.Mdn.1994.1" "fish.Mdn.1990.2"
#> [9] "fish.Mdn.1991.2" "fish.Mdn.1992.2"
#> [11] "fish.Mdn.1993.2" "fish.Mdn.1994.2"
# Mrw has parameters for each year
grep("^other.Mrw", names(attr(model_fn, 'parameter_template')), value = TRUE)
#> [1] "other.Mrw.proj.rwalk.mean" "other.Mrw.proj.rwalk.stddev"
#> [3] "other.Mrw.1990" "other.Mrw.1991"
#> [5] "other.Mrw.1992" "other.Mrw.1993"
#> [7] "other.Mrw.1994"
attr(model_fn, 'parameter_template') |>
g3_init_val("stst.Mdn.#.#", 0.5, lower = 0.1, upper = 0.9, random = TRUE) |>
g3_init_val("stst.Mdn.proj.dnorm.lmean", 0.1) |>
g3_init_val("stst.Mdn.proj.dnorm.lstddev", 0.001) |>
g3_init_val("other.Mrw.proj.rwalk.mean", 0) |>
g3_init_val("other.Mrw.proj.rwalk.stddev", 0.001) |>
g3_init_val("other.Mrw.#", 0.5, lower = 0.1, upper = 0.9, random = TRUE) |>
# Project forwards 20 years
g3_init_val("project_years", 20) |>
# Don't include projections in nll calculations:
# allows a stddev to be supplied for projections, but estimated freely
g3_init_val("proj_rwalk_fish_Mrw_weight", 0) |>
g3_init_val("proj_dnorm_fish_Mdn_weight", 0) |>
identity() -> params
#> Warning: g3_init_val('stst.Mdn.#.#') didn't match any parameters
#> Warning: g3_init_val('stst.Mdn.proj.dnorm.lmean') didn't match any parameters
#> Warning: g3_init_val('stst.Mdn.proj.dnorm.lstddev') didn't match any parameters
#> Warning: g3_init_val('proj_rwalk_fish_Mrw_weight') didn't match any parameters
#> Warning: g3_init_val('proj_dnorm_fish_Mdn_weight') didn't match any parameters
r <- attributes(model_fn(params))
# Values used for dnorm
plot(r$proj_dnorm_fish_Mdn__var)
# Values used for random walk
plot(r$proj_rwalk_other_Mrw__var)
### Plot values for an individual projection function
actions <- list( g3a_time(1990, 1991), g3_param_project("M", g3_param_project_dlnorm()) )
model_fn <- g3_to_r(c(actions, list(
g3a_report_history(actions, 'proj_.*', out_prefix = NULL),
NULL )))
attr(model_fn, 'parameter_template') |>
g3_init_val("M.proj.dlnorm.lmean", log(20)) |>
g3_init_val("M.proj.dlnorm.lstddev", log(1e-6)) |>
g3_init_val("M.#.#", 20) |>
g3_init_val("project_years", 100) |>
identity() -> params
#> Warning: g3_init_val('M.proj.dlnorm.lmean') didn't match any parameters
#> Warning: g3_init_val('M.proj.dlnorm.lstddev') didn't match any parameters
par(mfrow=c(3, 1))
plot(attr(model_fn(params |>
g3_init_val("M.proj.dlnorm.lstddev", log(1.001)) ), "proj_dlnorm_M__lvar"), ylim = c(15, 25))
#> Warning: g3_init_val('M.proj.dlnorm.lstddev') didn't match any parameters
plot(attr(model_fn(params |>
g3_init_val("M.proj.dlnorm.lstddev", log(1e-1)) ), "proj_dlnorm_M__lvar"), ylim = c(15, 25))
#> Warning: g3_init_val('M.proj.dlnorm.lstddev') didn't match any parameters
plot(attr(model_fn(params |>
g3_init_val("M.proj.dlnorm.lstddev", log(1e-2)) ), "proj_dlnorm_M__lvar"), ylim = c(15, 25))
#> Warning: g3_init_val('M.proj.dlnorm.lstddev') didn't match any parameters
### Recruitment projected by (block) bootstrap of estimated recruitment
st_fish <- g3_stock("fish", c(10, 20, 30)) |> g3s_age(1, 5)
rec_actions <- list(
g3a_time(1990, 2009),
g3a_initialconditions_normalparam(st_fish),
g3a_age(st_fish),
g3a_renewal_normalparam(st_fish,
# Recruitment from per-year parameters, projected by resampling
# blocks of 3 consecutive years of recruitment from 1995 onwards
factor_f = g3_param_project(
"rec",
g3_param_project_bootstrap(
from_year_f = 1995,
block_size_f = 3L ),
# Recruitment parameters are estimated directly, not as random effects
random = FALSE,
scale = "scalar",
by_step = FALSE,
by_stock = st_fish )),
NULL )
model_fn <- g3_to_r(c(rec_actions, list(
g3a_report_history(rec_actions, 'proj_.*', out_prefix = NULL),
NULL )))
# The bootstrap adds no parameters of its own, just per-year recruitment & scalar
# (sd is from g3a_renewal_normalparam)
grep("^fish\\.rec\\.", names(attr(model_fn, 'parameter_template')), value = TRUE)
#> [1] "fish.rec.1990" "fish.rec.1991" "fish.rec.1992" "fish.rec.1993"
#> [5] "fish.rec.1994" "fish.rec.1995" "fish.rec.1996" "fish.rec.1997"
#> [9] "fish.rec.1998" "fish.rec.1999" "fish.rec.2000" "fish.rec.2001"
#> [13] "fish.rec.2002" "fish.rec.2003" "fish.rec.2004" "fish.rec.2005"
#> [17] "fish.rec.2006" "fish.rec.2007" "fish.rec.2008" "fish.rec.2009"
#> [21] "fish.rec.scalar" "fish.rec.sd"
attr(model_fn, 'parameter_template') |>
g3_init_val("fish.rec.#", rlnorm(20, log(1e3), 0.5)) |>
g3_init_val("fish.rec.scalar", 1) |>
g3_init_val("project_years", 30) |>
identity() -> params
r <- attributes(model_fn(params))
# Recruitment for 1990..2009 from parameters, 2010..2039 resampled from 1995..2009
plot(1990:2039, exp(r$proj_bootstrap_fish_rec__lvar), type = "b")
abline(v = 2009.5, lty = 2)