library(magrittr)
library(unittest)
library(gadget3)
actions <- list(
g3a_time(
start_year = 1990,
end_year = 1994,
c(3,3,3,3)),
g3l_random_dnorm('dnorm_log',
~g3_param('dnorm_log', value = 0, random = TRUE),
mean_f = ~g3_param('dnorm_log_mean', value = 0, optimise = FALSE),
sigma_f = ~g3_param('dnorm_log_sigma', value = 1, optimise = FALSE),
weight = ~g3_param('dnorm_log_enabled', value = 0, optimise = FALSE)),
g3l_random_dnorm('dnorm_lin',
~g3_param('dnorm_lin', value = 0, random = TRUE),
mean_f = ~g3_param('dnorm_lin_mean', value = 0, optimise = FALSE),
sigma_f = ~g3_param('dnorm_lin_sigma', value = 1, optimise = FALSE),
log_f = FALSE,
weight = ~g3_param('dnorm_lin_enabled', value = 0, optimise = FALSE)),
g3l_random_walk('walk_year',
~g3_param_table('walk_year', expand.grid(cur_year = seq(start_year, end_year)), value = 0, random = TRUE),
sigma_f = ~g3_param('walk_year_sigma', value = 1, optimise = FALSE),
weight = ~g3_param('walk_year_enabled', value = 0, optimise = FALSE)),
g3l_random_walk('walk_step',
~g3_param_table('walk_step', expand.grid(
cur_year = seq(start_year, end_year),
cur_step = 1:4), value = 0, random = TRUE),
sigma_f = ~g3_param('walk_step_sigma', value = 1, optimise = FALSE),
weight = ~g3_param('walk_step_enabled', value = 0, optimise = FALSE)),
list('999' = ~{}))
model_fn <- g3_to_r(actions)
# model_fn <- edit(model_fn)
if (nzchar(Sys.getenv('G3_TEST_TMB'))) {
model_cpp <- g3_to_tmb(actions, trace = FALSE)
# model_cpp <- edit(model_cpp)
model_tmb <- g3_tmb_adfun(model_cpp, compile_flags = c("-O0", "-g"))
} else {
writeLines("# skip: not compiling TMB model")
model_cpp <- c()
}
ok_group('g3l_random_dnorm', {
params <- attr(model_fn, 'parameter_template')
params['dnorm_log'] <- runif(1, 0, 10)
params['dnorm_log_mean'] <- runif(1, 0, 10)
params['dnorm_log_sigma'] <- runif(1, 0, 10)
params['dnorm_log_enabled'] <- 1
params['dnorm_lin'] <- runif(1, 0, 10)
params['dnorm_lin_mean'] <- runif(1, 0, 10)
params['dnorm_lin_sigma'] <- runif(1, 0, 10)
params['dnorm_lin_enabled'] <- 1
result <- model_fn(params)
ok(ut_cmp_equal(
as.vector(attr(result, "nll_random_dnorm_dnorm_log__dnorm")),
-dnorm(params$dnorm_log, params$dnorm_log_mean, params$dnorm_log_sigma, TRUE),
tolerance = 1e-7), "dnorm_log matches dnorm")
ok(ut_cmp_equal(
as.vector(attr(result, "nll_random_dnorm_dnorm_lin__dnorm")),
dnorm(params$dnorm_lin, params$dnorm_lin_mean, params$dnorm_lin_sigma, FALSE),
tolerance = 1e-7), "dnorm_lin matches dnorm")
ok(ut_cmp_equal(
as.vector(result),
sum(c(
-dnorm(params$dnorm_log, params$dnorm_log_mean, params$dnorm_log_sigma, TRUE),
dnorm(params$dnorm_lin, params$dnorm_lin_mean, params$dnorm_lin_sigma, FALSE),
0)),
tolerance = 1e-7), "nll matches both (and has been included only once)")
if (nzchar(Sys.getenv('G3_TEST_TMB'))) {
param_template <- attr(model_cpp, "parameter_template")
param_template$value <- params[param_template$switch]
# Reproduce model to include any unoptimised parameters
model_tmb <- g3_tmb_adfun(model_cpp, param_template, compile_flags = c("-O0", "-g"))
ok(ut_cmp_identical(names(model_tmb$env$last.par)[model_tmb$env$random], c(
'dnorm_lin',
'dnorm_log',
'walk_step__1990__1',
'walk_step__1991__1',
'walk_step__1992__1',
'walk_step__1993__1',
'walk_step__1994__1',
'walk_step__1990__2',
'walk_step__1991__2',
'walk_step__1992__2',
'walk_step__1993__2',
'walk_step__1994__2',
'walk_step__1990__3',
'walk_step__1991__3',
'walk_step__1992__3',
'walk_step__1993__3',
'walk_step__1994__3',
'walk_step__1990__4',
'walk_step__1991__4',
'walk_step__1992__4',
'walk_step__1993__4',
'walk_step__1994__4',
'walk_year__1990',
'walk_year__1991',
'walk_year__1992',
'walk_year__1993',
'walk_year__1994',
NULL)), "env$random: TMB got expected random variables")
gadget3:::ut_tmb_r_compare(model_fn, model_tmb, param_template)
} else {
writeLines("# skip: not running TMB tests")
}
})
ok_group('g3l_random_walk', {
params <- attr(model_fn, 'parameter_template')
params['walk_year_enabled'] <- 1
params[grepl('walk_year\\.199', names(params))] <- runif(5, 1, 10)
params['walk_step_enabled'] <- 1
params[grepl('walk_step\\.199', names(params))] <- runif(5 * 4, 1, 10)
result <- model_fn(params)
# Calculate the sum of a random walk along values
sum_walk_dnorm <- function (vals, sigma, is_log) {
vals <- vals[order(names(vals))] # Sort by name, so 1991.1 is before 1991.2
lead <- head(vals, -1)
lag <- tail(vals, -1)
sum(vapply(
seq_along(lead),
function (i) -dnorm(lead[[i]], lag[[i]], sigma, is_log),
numeric(1)))
}
ok(ut_cmp_equal(
as.vector(attr(result, "nll_random_walk_walk_year__dnorm")),
sum_walk_dnorm(params[grepl('walk_year\\.199', names(params))], params$walk_year_sigma, TRUE),
tolerance = 1e-7), "nll_random_walk_walk_year__dnorm")
ok(ut_cmp_equal(
as.vector(attr(result, "nll_random_walk_walk_step__dnorm")),
sum_walk_dnorm(params[grepl('walk_step\\.199', names(params))], params$walk_step_sigma, TRUE),
tolerance = 1e-7), "nll_random_walk_walk_step__dnorm")
ok(ut_cmp_equal(
as.vector(result),
as.vector(sum(
attr(result, "nll_random_walk_walk_year__dnorm"),
attr(result, "nll_random_walk_walk_step__dnorm"),
0)),
tolerance = 1e-7), "nll matches both")
if (nzchar(Sys.getenv('G3_TEST_TMB'))) {
param_template <- attr(model_cpp, "parameter_template")
param_template$value <- params[param_template$switch]
# Reproduce model to include any unoptimised parameters
model_tmb <- g3_tmb_adfun(model_cpp, param_template, compile_flags = c("-O0", "-g"))
gadget3:::ut_tmb_r_compare(model_fn, model_tmb, param_template)
} else {
writeLines("# skip: not running TMB tests")
}
})
if (nzchar(Sys.getenv('G3_TEST_TMB'))) {
# An end-to-end test, too complex to be a vignette example
in_param <- g3_parameterized('par', by_year = TRUE, random = TRUE, value = 50)
out_stock <- g3_stock('output', 1) |> g3s_time(year = 1990:2000)
simple_code <- g3_to_tmb(list(
g3a_time(1990, 2000),
gadget3:::g3_step(g3_formula(
quote( stock_iterate(out_stock, stock_ss(out_stock__val) <- force_type * in_param) ),
out_stock = out_stock,
# NB: We need to set an array<Type>
force_type = as.array(1),
out_stock__val = g3_stock_instance(out_stock, 0),
in_param = in_param )),
g3l_random_dnorm(
'rdnorm_par',
param_f = in_param,
# These need to be Types, not (double), thus g3_formula()
mean_f = g3_formula(cur_year * m, m = 0.001),
sigma_f = g3_formula(s, s = 1) ),
gadget3:::g3a_report_var(
'out_stock__val',
g3_stock_instance(out_stock, 0),
stock = out_stock,
out_prefix = NULL),
NULL))
obj.fn <- g3_tmb_adfun(simple_code)
out <- suppressWarnings(optim(obj.fn$par, obj.fn$fn, obj.fn$gr, method = "BFGS", control = list(maxit = 10)))
ok(ut_cmp_equal(
as.vector(obj.fn$report()$output__val),
c(1.99, 1.991, 1.992, 1.993, 1.994, 1.995, 1.996, 1.997, 1.998, 1.999, 2),
filter = NULL), "output__val: Found mean for each year")
}
Add the following code to your website.
For more information on customizing the embed code, read Embedding Snippets.