aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--R/mkinfit.R50
-rw-r--r--tests/testthat/test_error_models.R50
2 files changed, 86 insertions, 14 deletions
diff --git a/R/mkinfit.R b/R/mkinfit.R
index 224dc7bd..e0a0e525 100644
--- a/R/mkinfit.R
+++ b/R/mkinfit.R
@@ -35,6 +35,7 @@ mkinfit <- function(mkinmod, observed,
atol = 1e-8, rtol = 1e-10, n.outtimes = 100,
error_model = c("const", "obs", "tc"),
error_model_algorithm = c("direct", "twostep", "threestep", "fourstep", "IRLS"),
+ reweight.tol = 1e-8, reweight.max.iter = 10,
trace_parms = FALSE,
...)
{
@@ -285,7 +286,7 @@ mkinfit <- function(mkinmod, observed,
# Trace parameter values if requested and if we are actually optimising
if(trace_parms & update_data) cat(P, "\n")
- if (fixed_degparms[1] != FALSE) {
+ if (is.numeric(fixed_degparms)) {
degparms <- fixed_degparms
errparms <- P # This version of errparms is local to the function
degparms_fixed = TRUE
@@ -293,7 +294,7 @@ mkinfit <- function(mkinmod, observed,
degparms_fixed = FALSE
}
- if (fixed_errparms[1] != FALSE) {
+ if (is.numeric(fixed_errparms)) {
degparms <- P
errparms <- fixed_errparms # Local to the function
errparms_fixed = TRUE
@@ -364,7 +365,8 @@ mkinfit <- function(mkinmod, observed,
sum(dnorm(x = value.observed, mean = value.predicted, sd = std, log = TRUE)))
}
- # We update the current likelihood and data during the optimisation, not during hessian calculations
+ # We update the current likelihood and data during the optimisation, not
+ # during hessian calculations
if (update_data) {
assign("out_predicted", out_long, inherits = TRUE)
@@ -434,11 +436,10 @@ mkinfit <- function(mkinmod, observed,
# Show parameter names if tracing is requested
if(trace_parms) cat(names_optim, "\n")
+ # browser()
+
# Do the fit and take the time until the hessians are calculated
fit_time <- system.time({
- # In the inital run, we assume a constant standard deviation and do
- # not optimise it, as this is unnecessary and leads to instability of the
- # fit (most obvious when fitting the IORE model)
degparms <- c(state.ini.optim, transparms.optim)
if (err_mod == "const" | error_model_algorithm != "direct") {
@@ -463,7 +464,7 @@ mkinfit <- function(mkinmod, observed,
fit <- nlminb(errparms, nlogLik, control = control,
lower = lower[names(errparms)],
upper = upper[names(errparms)],
- degparms_fixed = degparms, ...)
+ fixed_degparms = degparms, ...)
errparms <- fit$par
}
if (error_model_algorithm == "fourstep") {
@@ -471,10 +472,11 @@ mkinfit <- function(mkinmod, observed,
fit <- nlminb(degparms, nlogLik, control = control,
lower = lower[names(degparms)],
upper = upper[names(degparms)],
- errparms_fixed = errparms, ...)
+ fixed_errparms = errparms, ...)
degparms <- fit$par
}
- if (error_model_algorithm %in% c("direct", "twostep", "threestep", "fourstep")) {
+ if (error_model_algorithm %in% c("direct", "twostep", "threestep", "fourstep") &
+ err_mod != "const") {
if (!quiet) message("Optimising the complete model")
parms.start <- c(degparms, errparms)
fit <- nlminb(parms.start, nlogLik,
@@ -483,6 +485,36 @@ mkinfit <- function(mkinmod, observed,
control = control, ...)
fit$logLik <- - nlogLik.current
}
+ if (err_mod != "const" & error_model_algorithm == "IRLS") {
+ reweight.diff <- 1
+ n.iter <- 0
+ errparms_last <- errparms
+
+ while (reweight.diff > reweight.tol &
+ n.iter < reweight.max.iter) {
+
+ if (!quiet) message("Optimising the error model")
+ fit <- nlminb(errparms, nlogLik, control = control,
+ lower = lower[names(errparms)],
+ upper = upper[names(errparms)],
+ fixed_degparms = degparms, ...)
+ errparms <- fit$par
+
+ if (!quiet) message("Optimising the degradation model")
+ fit <- nlminb(degparms, nlogLik, control = control,
+ lower = lower[names(degparms)],
+ upper = upper[names(degparms)],
+ fixed_errparms = errparms, ...)
+ degparms <- fit$par
+
+ reweight.diff <- dist(rbind(errparms, errparms_last))
+ errparms_last <- errparms
+
+ fit$par <- c(fit$par, errparms)
+ nlogLik.current <- nlogLik(c(degparms, errparms), OLS = FALSE)
+ fit$logLik <- - nlogLik.current
+ }
+ }
# We include the error model in the parameter uncertainty analysis, also
# for constant variance, to get a confidence interval for it
diff --git a/tests/testthat/test_error_models.R b/tests/testthat/test_error_models.R
index 94703e7f..c656f7d2 100644
--- a/tests/testthat/test_error_models.R
+++ b/tests/testthat/test_error_models.R
@@ -180,7 +180,6 @@ test_that("Reweighting method 'tc' produces reasonable variance estimates", {
test_that("The two-component error model finds the best known AIC values for parent models", {
skip_on_cran()
- experimental_data_for_UBA_2019
library(parallel)
source("~/git/mkin/R/mkinfit.R")
source("~/git/mkin/R/mmkin.R")
@@ -195,27 +194,68 @@ test_that("The two-component error model finds the best known AIC values for par
error_model = "tc", error_model_algorithm = "fourstep")
f_9 <- mkinfit("SFO", experimental_data_for_UBA_2019[[9]]$data,
error_model = "tc", error_model_algorithm = "IRLS")
+ f_9 <- mkinfit("SFO", experimental_data_for_UBA_2019[[9]]$data,
+ error_model = "tc", error_model_algorithm = "d_3")
AIC(f_9)
- f_tc_exp <- mmkin(c("SFO"),
+ f_10 <- mkinfit("DFOP", experimental_data_for_UBA_2019[[10]]$data,
+ error_model = "tc", error_model_algorithm = "IRLS")
+ f_tc_exp_direct <- mmkin(c("SFO", "DFOP", "HS"),
lapply(experimental_data_for_UBA_2019, function(x) x$data),
error_model = "tc",
error_model_algorithm = "direct",
quiet = TRUE)
- f_tc_exp <- mmkin(c("SFO"),
+ f_tc_exp_twostep <- mmkin(c("SFO", "DFOP", "HS"),
lapply(experimental_data_for_UBA_2019, function(x) x$data),
error_model = "tc",
error_model_algorithm = "twostep",
quiet = TRUE)
- f_tc_exp <- mmkin(c("SFO"),
+ f_tc_exp_threestep <- mmkin(c("SFO", "DFOP", "HS"),
lapply(experimental_data_for_UBA_2019, function(x) x$data),
error_model = "tc",
error_model_algorithm = "threestep",
quiet = TRUE)
+ f_tc_exp_fourstep <- mmkin(c("SFO", "DFOP", "HS"),
+ lapply(experimental_data_for_UBA_2019, function(x) x$data),
+ error_model = "tc",
+ error_model_algorithm = "fourstep",
+ quiet = TRUE)
+ f_tc_exp_IRLS <- mmkin(c("SFO", "DFOP", "HS"),
+ lapply(experimental_data_for_UBA_2019, function(x) x$data),
+ error_model = "tc",
+ error_model_algorithm = "IRLS",
+ quiet = TRUE)
+
+ AIC_exp_direct <- lapply(f_tc_exp_direct, AIC)
+ AIC_exp_direct <- lapply(AIC_exp_direct, round, 1)
+ dim(AIC_exp_direct) <- dim(f_tc_exp_direct)
+ dimnames(AIC_exp_direct) <- dimnames(f_tc_exp_direct)
+
+ AIC_exp_twostep <- lapply(f_tc_exp_twostep, AIC)
+ AIC_exp_twostep <- lapply(AIC_exp_twostep, round, 1)
+ dim(AIC_exp_twostep) <- dim(f_tc_exp_twostep)
+ dimnames(AIC_exp_twostep) <- dimnames(f_tc_exp_twostep)
+
+ AIC_exp_threestep <- lapply(f_tc_exp_threestep, AIC)
+ AIC_exp_threestep <- lapply(AIC_exp_threestep, round, 1)
+ dim(AIC_exp_threestep) <- dim(f_tc_exp_threestep)
+ dimnames(AIC_exp_threestep) <- dimnames(f_tc_exp_threestep)
+
+ AIC_exp_fourstep <- lapply(f_tc_exp_fourstep, AIC)
+ AIC_exp_fourstep <- lapply(AIC_exp_fourstep, round, 1)
+ dim(AIC_exp_fourstep) <- dim(f_tc_exp_fourstep)
+ dimnames(AIC_exp_fourstep) <- dimnames(f_tc_exp_fourstep)
+
+ AIC_exp_IRLS <- lapply(f_tc_exp_IRLS, AIC)
+ AIC_exp_IRLS <- lapply(AIC_exp_IRLS, round, 1)
+ dim(AIC_exp_IRLS) <- dim(f_tc_exp_IRLS)
+ dimnames(AIC_exp_IRLS) <- dimnames(f_tc_exp_IRLS)
AIC_exp <- lapply(f_tc_exp, AIC)
dim(AIC_exp) <- dim(f_tc_exp)
dimnames(AIC_exp) <- dimnames(f_tc_exp)
- expect_equivalent(round(AIC_exp["SFO", c(9, 11, 12)], 1), c(134.9, 125.5, 82.0))
+ unlist(AIC_exp["SFO", c(9, 11, 12)])
+ expect_equivalent(round(unlist(AIC_exp["SFO", c(9, 11, 12)]), 1),
+ c(134.9, 125.5, 82.0))
})

Contact - Imprint