diff options
author | Johannes Ranke <jranke@uni-bremen.de> | 2019-10-21 12:11:34 +0200 |
---|---|---|
committer | Johannes Ranke <jranke@uni-bremen.de> | 2019-10-21 12:11:34 +0200 |
commit | 7624a2b8398b4ad665a3b0b622488e1893a5ee7c (patch) | |
tree | 30e5bc32adc77de6540e68fa80a157f893c7770d /R | |
parent | 8ce251e5ee619a240da2381eda58bc94a554ca37 (diff) |
Refactor mkinfit, infrastructure work
mkinfit objects now include an ll() function to calculate the
log-likelihood. Part of the code was refactored, hopefully making it
easier to read and maintain. IRLS is currently the default algorithm for
the error model "obs", for no particular reason. This may be subject
to change when I get around to investigate.
Slow tests are now in a separate subdirectory and will probably
only be run by my own Makefile target.
Formatting of test logs is improved.
Roundtripping error model parameters works with a precision of 10% when
we use lots of replicates in the synthetic data (see slow tests). This
is not new in this commit, but as I think it is reasonable this
closes #7.
Diffstat (limited to 'R')
-rw-r--r-- | R/mkinerrmin.R | 7 | ||||
-rw-r--r-- | R/mkinfit.R | 328 |
2 files changed, 178 insertions, 157 deletions
diff --git a/R/mkinerrmin.R b/R/mkinerrmin.R index c0c6fad7..ce4877d2 100644 --- a/R/mkinerrmin.R +++ b/R/mkinerrmin.R @@ -1,4 +1,4 @@ -# Copyright (C) 2010-2014 Johannes Ranke +# Copyright (C) 2010-2019 Johannes Ranke # Contact: jranke@uni-bremen.de # This file is part of the R package mkin @@ -62,9 +62,8 @@ mkinerrmin <- function(fit, alpha = 0.05) n.k.optim <- n.k.optim + length(grep(paste("^log_k", obs_var, sep="_"), names(parms.optim))) n.k__iore.optim <- length(grep(paste("^k__iore", obs_var, sep="_"), names(parms.optim))) - n.k__iore.optim <- n.k__iore.optim + length(grep(paste("^log_k__iore", obs_var, - sep = "_"), - names(parms.optim))) + n.k__iore.optim <- n.k__iore.optim + length(grep(paste("^log_k__iore", + obs_var, sep = "_"), names(parms.optim))) n.N.optim <- length(grep(paste("^N", obs_var, sep="_"), names(parms.optim))) diff --git a/R/mkinfit.R b/R/mkinfit.R index b5e69e67..7e2b8cac 100644 --- a/R/mkinfit.R +++ b/R/mkinfit.R @@ -34,7 +34,7 @@ mkinfit <- function(mkinmod, observed, quiet = FALSE,
atol = 1e-8, rtol = 1e-10, n.outtimes = 100,
error_model = c("const", "obs", "tc"),
- error_model_algorithm = c("d_3", "direct", "twostep", "threestep", "fourstep", "IRLS", "OLS"),
+ error_model_algorithm = c("auto", "d_3", "direct", "twostep", "threestep", "fourstep", "IRLS", "OLS"),
reweight.tol = 1e-8, reweight.max.iter = 10,
trace_parms = FALSE,
...)
@@ -244,13 +244,21 @@ mkinfit <- function(mkinmod, observed, }
}
- # Get the error model
+ # Get the error model and the algorithm for fitting
err_mod <- match.arg(error_model)
error_model_algorithm = match.arg(error_model_algorithm)
+ if (error_model_algorithm == "OLS") {
+ if (err_mod != "const") stop("OLS is only appropriate for constant variance")
+ }
+ if (error_model_algorithm == "auto") {
+ error_model_algorithm = switch(err_mod,
+ const = "OLS", obs = "IRLS", tc = "d_3")
+ }
errparm_names <- switch(err_mod,
"const" = "sigma",
"obs" = paste0("sigma_", obs_vars),
"tc" = c("sigma_low", "rsd_high"))
+ errparm_names_optim <- if (error_model_algorithm == "OLS") NULL else errparm_names
# Define starting values for the error model
if (err.ini[1] != "auto") {
@@ -271,6 +279,11 @@ mkinfit <- function(mkinmod, observed, }
names(errparms) <- errparm_names
}
+ if (error_model_algorithm == "OLS") {
+ errparms_optim <- NULL
+ } else {
+ errparms_optim <- errparms
+ }
# Define outtimes for model solution.
# Include time points at which observed data are available
@@ -278,49 +291,51 @@ mkinfit <- function(mkinmod, observed, max(observed$time),
length.out = n.outtimes))))
- # Define log-likelihood function for optimisation, including (back)transformations
- nlogLik <- function(P, trans = TRUE, OLS = FALSE, fixed_degparms = FALSE, fixed_errparms = FALSE, update_data = TRUE, ...)
+ # Define the objective function for optimisation, including (back)transformations
+ cost_function <- function(P, trans = TRUE, OLS = FALSE, fixed_degparms = FALSE, fixed_errparms = FALSE, update_data = TRUE, ...)
{
assign("calls", calls + 1, inherits = TRUE) # Increase the model solution counter
# Trace parameter values if requested and if we are actually optimising
if(trace_parms & update_data) cat(P, "\n")
+ # Determine local parameter values for the cost estimation
if (is.numeric(fixed_degparms)) {
- degparms <- fixed_degparms
- errparms <- P # This version of errparms is local to the function
+ cost_degparms <- fixed_degparms
+ cost_errparms <- P
degparms_fixed = TRUE
} else {
degparms_fixed = FALSE
}
if (is.numeric(fixed_errparms)) {
- degparms <- P
- errparms <- fixed_errparms # Local to the function
+ cost_degparms <- P
+ cost_errparms <- fixed_errparms
errparms_fixed = TRUE
} else {
errparms_fixed = FALSE
}
if (OLS) {
- degparms <- P
+ cost_degparms <- P
+ cost_errparms <- numeric(0)
}
if (!OLS & !degparms_fixed & !errparms_fixed) {
- degparms <- P[1:(length(P) - length(errparms))]
- errparms <- P[(length(degparms) + 1):length(P)]
+ cost_degparms <- P[1:(length(P) - length(errparms))]
+ cost_errparms <- P[(length(cost_degparms) + 1):length(P)]
}
# Initial states for t0
if(length(state.ini.optim) > 0) {
- odeini <- c(degparms[1:length(state.ini.optim)], state.ini.fixed)
+ odeini <- c(cost_degparms[1:length(state.ini.optim)], state.ini.fixed)
names(odeini) <- c(state.ini.optim.boxnames, state.ini.fixed.boxnames)
} else {
odeini <- state.ini.fixed
names(odeini) <- state.ini.fixed.boxnames
}
- odeparms.optim <- degparms[(length(state.ini.optim) + 1):length(degparms)]
+ odeparms.optim <- cost_degparms[(length(state.ini.optim) + 1):length(cost_degparms)]
if (trans == TRUE) {
odeparms <- c(odeparms.optim, transparms.fixed)
@@ -342,53 +357,55 @@ mkinfit <- function(mkinmod, observed, out_long <- mkin_wide_to_long(out, time = "time")
if (err_mod == "const") {
- observed$std <- errparms["sigma"]
+ observed$std <- if (OLS) NA else cost_errparms["sigma"]
}
if (err_mod == "obs") {
std_names <- paste0("sigma_", observed$name)
- observed$std <- errparms[std_names]
+ observed$std <- cost_errparms[std_names]
}
if (err_mod == "tc") {
tmp <- merge(observed, out_long, by = c("time", "name"))
tmp$name <- ordered(tmp$name, levels = obs_vars)
tmp <- tmp[order(tmp$name, tmp$time), ]
- observed$std <- sqrt(errparms["sigma_low"]^2 + tmp$value.y^2 * errparms["rsd_high"]^2)
+ observed$std <- sqrt(cost_errparms["sigma_low"]^2 + tmp$value.y^2 * cost_errparms["rsd_high"]^2)
}
- data_log_lik <- merge(observed[c("name", "time", "value", "std")], out_long,
+ cost_data <- merge(observed[c("name", "time", "value", "std")], out_long,
by = c("name", "time"), suffixes = c(".observed", ".predicted"))
if (OLS) {
- nlogLik <- with(data_log_lik, sum((value.observed - value.predicted)^2))
+ # Cost is the sum of squared residuals
+ cost <- with(cost_data, sum((value.observed - value.predicted)^2))
} else {
- nlogLik <- - with(data_log_lik,
+ # Cost is the negative log-likelihood
+ cost <- - with(cost_data,
sum(dnorm(x = value.observed, mean = value.predicted, sd = std, log = TRUE)))
}
- # We update the current likelihood and data during the optimisation, not
+ # We update the current cost and data during the optimisation, not
# during hessian calculations
if (update_data) {
assign("out_predicted", out_long, inherits = TRUE)
- assign("data_errmod", data_log_lik, inherits = TRUE)
+ assign("current_data", cost_data, inherits = TRUE)
- if (nlogLik < nlogLik.current) {
- assign("nlogLik.current", nlogLik, inherits = TRUE)
+ if (cost < cost.current) {
+ assign("cost.current", cost, inherits = TRUE)
if (!quiet) cat(ifelse(OLS, "Sum of squared residuals", "Negative log-likelihood"),
- " at call ", calls, ": ", nlogLik.current, "\n", sep = "")
+ " at call ", calls, ": ", cost.current, "\n", sep = "")
}
}
- return(nlogLik)
+ return(cost)
}
- n_optim <- length(c(state.ini.optim, transparms.optim, errparm_names))
names_optim <- c(names(state.ini.optim),
names(transparms.optim),
- errparm_names)
+ errparm_names_optim)
+ n_optim <- length(names_optim)
# Define lower and upper bounds other than -Inf and Inf for parameters
# for which no internal transformation is requested in the call to mkinfit
- # and for error model parameters
+ # and for optimised error model parameters
lower <- rep(-Inf, n_optim)
upper <- rep(Inf, n_optim)
names(lower) <- names(upper) <- names_optim
@@ -416,7 +433,9 @@ mkinfit <- function(mkinmod, observed, }
if (err_mod == "const") {
- lower["sigma"] <- 0
+ if (error_model_algorithm != "OLS") {
+ lower["sigma"] <- 0
+ }
}
if (err_mod == "obs") {
index_sigma <- grep("^sigma_", names(lower))
@@ -427,11 +446,11 @@ mkinfit <- function(mkinmod, observed, lower["rsd_high"] <- 0
}
- # Counter for likelihood evaluations
+ # Counter for cost function evaluations
calls = 0
- nlogLik.current <- Inf
+ cost.current <- Inf
out_predicted <- NA
- data_errmod <- NA
+ current_data <- NA
# Show parameter names if tracing is requested
if(trace_parms) cat(names_optim, "\n")
@@ -441,132 +460,127 @@ mkinfit <- function(mkinmod, observed, # Do the fit and take the time until the hessians are calculated
fit_time <- system.time({
degparms <- c(state.ini.optim, transparms.optim)
-
- if (err_mod == "const") {
- error_model_algorithm = "OLS"
+ n_degparms <- length(degparms)
+ degparms_index <- seq(1, n_degparms)
+ errparms_index <- seq(n_degparms + 1, length.out = length(errparms))
+
+ if (error_model_algorithm == "d_3") {
+ if (!quiet) message("Directly optimising the complete model")
+ parms.start <- c(degparms, errparms)
+ fit_direct <- nlminb(parms.start, cost_function,
+ lower = lower[names(parms.start)],
+ upper = upper[names(parms.start)],
+ control = control, ...)
+ fit_direct$logLik <- - cost.current
+ if (error_model_algorithm == "direct") {
+ degparms <- fit_direct$par[degparms_index]
+ errparms <- fit_direct$par[errparms_index]
+ } else {
+ cost.current <- Inf # reset to avoid conflict with the OLS step
+ }
+ }
+ if (error_model_algorithm != "direct") {
if (!quiet) message("Ordinary least squares optimisation")
- fit <- nlminb(degparms, nlogLik, control = control,
+ fit <- nlminb(degparms, cost_function, control = control,
lower = lower[names(degparms)],
upper = upper[names(degparms)], OLS = TRUE, ...)
degparms <- fit$par
# Get the maximum likelihood estimate for sigma at the optimum parameter values
- data_errmod$residual <- data_errmod$value.observed - data_errmod$value.predicted
- sigma_mle <- sqrt(sum(data_errmod$residual^2)/nrow(data_errmod))
+ current_data$residual <- current_data$value.observed - current_data$value.predicted
+ sigma_mle <- sqrt(sum(current_data$residual^2)/nrow(current_data))
- errparms <- c(sigma = sigma_mle)
- nlogLik.current <- nlogLik(c(degparms, errparms), OLS = FALSE)
- fit$logLik <- - nlogLik.current
- } else {
- if (error_model_algorithm == "d_3") {
- if (!quiet) message("Directly optimising the complete model")
- parms.start <- c(degparms, errparms)
- fit_direct <- nlminb(parms.start, nlogLik,
- lower = lower[names(parms.start)],
- upper = upper[names(parms.start)],
- control = control, ...)
- fit_direct$logLik <- - nlogLik.current
- nlogLik.current <- Inf # reset to avoid conflict with the OLS step
+ # Use that estimate for the constant variance, or as first guess if err_mod = "obs"
+ if (err_mod != "tc") {
+ errparms[names(errparms)] <- sigma_mle
}
- if (error_model_algorithm != "direct") {
- if (!quiet) message("Ordinary least squares optimisation")
- fit <- nlminb(degparms, nlogLik, control = control,
- lower = lower[names(degparms)],
- upper = upper[names(degparms)], OLS = TRUE, ...)
- degparms <- fit$par
- # Get the maximum likelihood estimate for sigma at the optimum parameter values
- data_errmod$residual <- data_errmod$value.observed - data_errmod$value.predicted
- sigma_mle <- sqrt(sum(data_errmod$residual^2)/nrow(data_errmod))
+ fit$par <- c(fit$par, errparms)
+
+ cost.current <- cost_function(c(degparms, errparms), OLS = FALSE)
+ fit$logLik <- - cost.current
+ }
+ if (error_model_algorithm %in% c("threestep", "fourstep", "d_3")) {
+ if (!quiet) message("Optimising the error model")
+ fit <- nlminb(errparms, cost_function, control = control,
+ lower = lower[names(errparms)],
+ upper = upper[names(errparms)],
+ fixed_degparms = degparms, ...)
+ errparms <- fit$par
+ }
+ if (error_model_algorithm == "fourstep") {
+ if (!quiet) message("Optimising the degradation model")
+ fit <- nlminb(degparms, cost_function, control = control,
+ lower = lower[names(degparms)],
+ upper = upper[names(degparms)],
+ fixed_errparms = errparms, ...)
+ degparms <- fit$par
+ }
+ if (error_model_algorithm %in%
+ c("direct", "twostep", "threestep", "fourstep", "d_3")) {
+ if (!quiet) message("Optimising the complete model")
+ parms.start <- c(degparms, errparms)
+ fit <- nlminb(parms.start, cost_function,
+ lower = lower[names(parms.start)],
+ upper = upper[names(parms.start)],
+ control = control, ...)
+ degparms <- fit$par[degparms_index]
+ errparms <- fit$par[errparms_index]
+ fit$logLik <- - cost.current
- nlogLik.current <- nlogLik(c(degparms, errparms), OLS = FALSE)
- fit$logLik <- - nlogLik.current
+ if (error_model_algorithm == "d_3") {
+ d_3_messages = c(
+ same = "Direct fitting and three-step fitting yield approximately the same likelihood",
+ threestep = "Three-step fitting yielded a higher likelihood than direct fitting",
+ direct = "Direct fitting yielded a higher likelihood than three-step fitting")
+ rel_diff <- abs((fit_direct$logLik - fit$logLik))/-mean(c(fit_direct$logLik, fit$logLik))
+ if (rel_diff < 0.0001) {
+ if (!quiet) message(d_3_messages["same"])
+ fit$d_3_message <- d_3_messages["same"]
+ } else {
+ if (fit$logLik > fit_direct$logLik) {
+ if (!quiet) message(d_3_messages["threestep"])
+ fit$d_3_message <- d_3_messages["threestep"]
+ } else {
+ if (!quiet) message(d_3_messages["direct"])
+ fit <- fit_direct
+ fit$d_3_message <- d_3_messages["direct"]
+ }
+ }
}
- if (error_model_algorithm %in% c("threestep", "fourstep", "d_3")) {
+ }
+ 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,
+ fit <- nlminb(errparms, cost_function, control = control,
lower = lower[names(errparms)],
upper = upper[names(errparms)],
fixed_degparms = degparms, ...)
errparms <- fit$par
- }
- if (error_model_algorithm == "fourstep") {
+
if (!quiet) message("Optimising the degradation model")
- fit <- nlminb(degparms, nlogLik, control = control,
+ fit <- nlminb(degparms, cost_function, control = control,
lower = lower[names(degparms)],
upper = upper[names(degparms)],
fixed_errparms = errparms, ...)
degparms <- fit$par
- }
- if (error_model_algorithm %in% c("direct", "twostep", "threestep",
- "fourstep", "d_3")) {
- if (!quiet) message("Optimising the complete model")
- parms.start <- c(degparms, errparms)
- fit <- nlminb(parms.start, nlogLik,
- lower = lower[names(parms.start)],
- upper = upper[names(parms.start)],
- control = control, ...)
- fit$logLik <- - nlogLik.current
- d_3_messages = c(
- same = "Direct fitting and three-step fitting yield approximately the same likelihood",
- threestep = "Three-step fitting yielded a higher likelihood than direct fitting",
- direct = "Direct fitting yielded a higher likelihood than three-step fitting")
- if (error_model_algorithm == "d_3") {
- rel_diff <- abs((fit_direct$logLik - fit$logLik))/-mean(c(fit_direct$logLik, fit$logLik))
- if (rel_diff < 0.0001) {
- if (!quiet) message(d_3_messages["same"])
- fit$d_3_message <- d_3_messages["same"]
- } else {
- if (fit$logLik > fit_direct$logLik) {
- if (!quiet) message(d_3_messages["threestep"])
- fit$d_3_message <- d_3_messages["threestep"]
- } else {
- if (!quiet) message(d_3_messages["direct"])
- fit <- fit_direct
- fit$d_3_message <- d_3_messages["direct"]
- }
- }
- }
- }
- if (err_mod != "const" & error_model_algorithm == "IRLS") {
- reweight.diff <- 1
- n.iter <- 0
+ reweight.diff <- dist(rbind(errparms, errparms_last))
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
- }
+ fit$par <- c(fit$par, errparms)
+ cost.current <- cost_function(c(degparms, errparms), OLS = FALSE)
+ fit$logLik <- - cost.current
}
}
- fit$error_model_algorithm <- error_model_algorithm
- # We include the error model in the parameter uncertainty analysis, also
- # for constant variance, to get a confidence interval for it
- if (err_mod == "const") {
- fit$par <- c(fit$par, sigma = sigma_mle)
- }
- fit$hessian <- try(numDeriv::hessian(nlogLik, fit$par, update_data = FALSE), silent = TRUE)
+ fit$hessian <- try(numDeriv::hessian(cost_function, c(degparms, errparms), OLS = FALSE,
+ update_data = FALSE), silent = TRUE)
# Backtransform parameters
bparms.optim = backtransform_odeparms(fit$par, mkinmod,
@@ -575,10 +589,12 @@ mkinfit <- function(mkinmod, observed, bparms.fixed = c(state.ini.fixed, parms.fixed)
bparms.all = c(bparms.optim, parms.fixed)
- fit$hessian_notrans <- try(numDeriv::hessian(nlogLik, c(bparms.optim, fit$par[names(errparms)]),
- trans = FALSE, update_data = FALSE), silent = TRUE)
+ fit$hessian_notrans <- try(numDeriv::hessian(cost_function, c(bparms.all, errparms),
+ OLS = FALSE, trans = FALSE, update_data = FALSE), silent = TRUE)
})
+ fit$error_model_algorithm <- error_model_algorithm
+
if (fit$convergence != 0) {
fit$warning = paste0("Optimisation did not converge:\n", fit$message)
warning(fit$warning)
@@ -604,18 +620,24 @@ mkinfit <- function(mkinmod, observed, fit$obs_vars <- obs_vars
fit$predicted <- out_predicted
- # Attach the negative log-likelihood function for post-hoc parameter uncertainty analysis
- fit$nlogLik <- nlogLik
+ # Residual sum of squares as a function of the fitted parameters
+ fit$rss <- function(P) cost_function(P, OLS = TRUE, update_data = FALSE)
+
+ # Log-likelihood with possibility to fix degparms or errparms
+ fit$ll <- function(P, fixed_degparms = FALSE, fixed_errparms = FALSE) {
+ - cost_function(P, fixed_degparms = fixed_degparms,
+ fixed_errparms = fixed_errparms, OLS = FALSE, update_data = FALSE)
+ }
# Collect initial parameter values in three dataframes
fit$start <- data.frame(value = c(state.ini.optim,
- parms.optim, errparms))
+ parms.optim, errparms_optim))
fit$start$type = c(rep("state", length(state.ini.optim)),
rep("deparm", length(parms.optim)),
- rep("error", length(errparms)))
+ rep("error", length(errparms_optim)))
fit$start_transformed = data.frame(
- value = c(state.ini.optim, transparms.optim, errparms),
+ value = c(state.ini.optim, transparms.optim, errparms_optim),
lower = lower,
upper = upper)
@@ -624,14 +646,14 @@ mkinfit <- function(mkinmod, observed, rep("deparm", length(parms.fixed)))
# Sort observed, predicted and residuals
- data_errmod$name <- ordered(data_errmod$name, levels = obs_vars)
+ current_data$name <- ordered(current_data$name, levels = obs_vars)
- data <- data_errmod[order(data_errmod$name, data_errmod$time), ]
+ ordered_data <- current_data[order(current_data$name, current_data$time), ]
- fit$data <- data.frame(time = data$time,
- variable = data$name,
- observed = data$value.observed,
- predicted = data$value.predicted)
+ fit$data <- data.frame(time = ordered_data$time,
+ variable = ordered_data$name,
+ observed = ordered_data$value.observed,
+ predicted = ordered_data$value.predicted)
fit$data$residual <- fit$data$observed - fit$data$predicted
@@ -649,8 +671,8 @@ mkinfit <- function(mkinmod, observed, state.ini.fixed)
names(fit$bparms.state) <- gsub("_0$", "", names(fit$bparms.state))
- fit$errparms.optim <- fit$par[names(errparms)]
- fit$df.residual <- n_observed - n_optim
+ fit$errparms <- errparms
+ fit$df.residual <- n_observed - length(c(degparms, errparms))
fit$date <- date()
fit$version <- as.character(utils::packageVersion("mkin"))
@@ -664,7 +686,7 @@ summary.mkinfit <- function(object, data = TRUE, distimes = TRUE, alpha = 0.05, param <- object$par
pnames <- names(param)
bpnames <- names(object$bparms.optim)
- epnames <- names(object$errparms.optim)
+ epnames <- names(object$errparms)
p <- length(param)
mod_vars <- names(object$mkinmod$diffs)
covar <- try(solve(object$hessian), silent = TRUE)
@@ -736,9 +758,9 @@ summary.mkinfit <- function(object, data = TRUE, distimes = TRUE, alpha = 0.05, use_of_ff = object$mkinmod$use_of_ff,
error_model_algorithm = object$error_model_algorithm,
df = c(p, rdf),
- cov.unscaled = covar,
+ covar = covar,
+ covar_notrans = covar_notrans,
err_mod = object$err_mod,
- #cov.scaled = covar * resvar,
niter = object$iterations,
calls = object$calls,
time = object$time,
@@ -760,8 +782,8 @@ summary.mkinfit <- function(object, data = TRUE, distimes = TRUE, alpha = 0.05, ans$errmin <- mkinerrmin(object, alpha = 0.05)
if (object$calls > 0) {
- if (!is.null(ans$cov.unscaled)){
- Corr <- cov2cor(ans$cov.unscaled)
+ if (!is.null(ans$covar)){
+ Corr <- cov2cor(ans$covar)
rownames(Corr) <- colnames(Corr) <- rownames(ans$par)
ans$Corr <- Corr
} else {
@@ -831,7 +853,7 @@ print.summary.mkinfit <- function(x, digits = max(3, getOption("digits") - 3), . if (x$calls > 0) {
cat("\nParameter correlation:\n")
- if (!is.null(x$cov.unscaled)){
+ if (!is.null(x$covar)){
print(x$Corr, digits = digits, ...)
} else {
cat("No covariance matrix")
|