# >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> ----
# >>>> This whole file is commented out <<<<<<<< ----
# >>>> because for compatibility with other projects <<<<<<<< ----
# >>>> we chose the dlill/conveniencefunctions <<<<<<<< ----
# >>>> implementation of norm_indiv <<<<<<<< ----
# >>>> However, to keep this code readily available <<<<<<<< ----
# >>>> we still have it in the main R folder <<<<<<<< ----
# >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> ----
#
# # normIndiv ----
#
# # @export
# # @rdname normL2
# normIndiv <- function(data,
# prd0,
# errmodel = NULL,
# forcings = NULL,
# iiv = NULL,
# conditional = NULL,
# fixed.grid,
# nauxtimes = 500,
# cores = 1,
# deriv = TRUE,
# attr.name = "data"
# ) {
#
# # .. 1 Conditions ----- #
# x.conditions <- names(fixed.grid)[-(1:2)]
# e.conditions <- names(attr(errmodel, "mappings"))
# prd0.conditions <- dMod::getConditions(prd0)
# data.conditions <- names(data)
#
#
# if (!all(data.conditions %in% x.conditions))
# stop("The prediction function does not provide predictions for all conditions in the data.")
#
# cn_prd <- NULL
# if (length(prd0.conditions) > 0) {
# cn_prd <- prd0.conditions[1]
# warning("prd0 contains named conditions. Only ", cn_prd, "will be used.\n",
# "Preferably, use a general prediction function with no specific conditions.")
# }
#
# # .. 2 Simulation times ----- #
# timesD <- sort(unique(c(0, do.call(c, lapply(data, function(d) d$time)))))
# timesD <- sort(union(timesD, seq(min(timesD), max(timesD), length.out = nauxtimes)))
#
# # .. 3 Optimization options ----- #
# if (Sys.info()["sysname"] == "Windows" & cores > 1) {
# warning("Parallelization of conditions on Windows not yet implemented. Unsing only 1 core.")
# cores <- 1
# }
# # [] If more optizers come, one might want to define global variable with derivative-based/free optimizers
# useDerivs <- deriv
#
# # .. 4 BLOQ options ----- #
# opt.BLOQ = c("M3", "M4NM", "M4BEAL", "M1")
# opt.hessian = c(
# ALOQ_part1 = TRUE, ALOQ_part2 = TRUE, ALOQ_part3 = TRUE,
# BLOQ_part1 = TRUE, BLOQ_part2 = TRUE, BLOQ_part3 = TRUE,
# PD = TRUE # enforce Hessian to be positive semidefinite, by setting nearest negative eigenvalues to zero
# )
#
# # .. 5 Construct est.grid ----- #
# est.grid <- build_est.grid(prd0 = prd0, fixed.grid = fixed.grid, conditional = conditional, condition.grid = attr(data, "condition.grid"), iiv = iiv)
# parameters <- getParameters_est.grid(est.grid)
#
# # .. 6 Controls ----- #
# controls <- list(timesD = timesD, attr.name = attr.name,
# conditions = x.conditions,
# opt.BLOQ = opt.BLOQ, opt.hessian = opt.hessian)
#
# # -------------------------------------------------------------------------#
# # Objective Function ---- #
# # -------------------------------------------------------------------------#
# myfn <- function(...,
# fixed = NULL,
# deriv=useDerivs,
# conditions = controls$conditions,
# # env = NULL,
# opt.BLOQ = controls$opt.BLOQ,
# opt.hessian = controls$opt.hessian,
# returnResiduals = FALSE) {
#
# # .. 1 BLOQ options ----- #
# opt.hessian <- c(opt.hessian, controls$opt.hessian[setdiff(names(controls$opt.hessian), names(opt.hessian))])
# opt.BLOQ <- opt.BLOQ[1]
#
# # .. 2 Passed parameters ----- #
# arglist <- list(...)
# arglist <- arglist[dMod::match.fnargs(arglist, "pars")]
# parsouter <- arglist[[1]]
# fixedouter <- fixed
#
# if (!is.null(attr(parsouter, "deriv"))){
# parsouter <- unclass(parsouter)
# attr(parsouter, "deriv") <- NULL
# # TODO
# # Implement chain rule for this function to allow function concatenation with to the right:
# # obj_indiv*p(pars) does not work
# # warning("The 'deriv' attribute of the pars-argument to obj_data has been set to NULL")
# }
#
# # .. 3 Evaluate norm ----- #
# outlist <- parallel::mclapply(conditions, function(cn) {
# # outlist <- lapply(conditions, function(cn) {
#
# # .... 1 Parameters ------ #
# # Fill general pars with individual values
# dummy <- make_pars(parsouter = parsouter, fixedouter = fixedouter, condition = cn, est.grid = est.grid, fixed.grid = fixed.grid)
# pars0 <- dummy$pars
# fixed0 <- dummy$fixed
#
#
# # .... 2 Prediction ------ #
# prediction <- prd0(times = controls$timesD, pars = pars0, fixed = fixed0, deriv = deriv, conditions = cn_prd)
#
# if (nrow(prediction[[1]]) < length(timesD))
# warning("Integrator has problems reaching tmax. Try increasing nauxtimes")
#
#
# # .... 3 Calculate residuals ------ #
#
# # Skip condition if the data does not provide any observation for the prediction of the prd function.
# if (length(intersect(data[[cn]][["name"]], colnames(prediction[[1]]))) == 0){
# mywrss <- init_empty_objlist(pars0, deriv = deriv)
# mywrss <- rename_objlist(mywrss, cn, est.grid)
# return(mywrss)
# }
# err <- NULL
# if (!is.null(errmodel) && (is.null(e.conditions) | (cn %in% e.conditions)))
# err <- errmodel(out = prediction[[1]], pars = dMod::getParameters(prediction[[1]]), conditions = cn)
# nout <- res(data[[cn]], prediction[[1]], err[[cn]])
# mywrss <- nll(nout = nout, pars = pars0, deriv = deriv)
# chisquare <- attr(mywrss, "chisquare")
# # .... 4 Rename general parnames into individual parnames ------ #
# mywrss <- rename_objlist(mywrss, cn, est.grid)
# if (returnResiduals) attr(mywrss, "residuals") <- cbind(condition = cn, nout)
# return(mywrss)
# # })
# }, mc.cores = cores)
#
# # Remove list elements which could not be evaluated
# failed <- vapply(outlist, is.character, FUN.VALUE = FALSE)
# if (any(failed))
# warning("Objective function could not be evaluated for conditions", paste0(conditions[failed], collapse = ", "))
# outlist <- outlist[!failed]
# if (length(outlist) == 0)
# stop("Objective function could not be evaluated for any of the conditions.")
#
# # Extract values, gradients and hessians
# values <- lapply(outlist, function(x) x[["value"]]+1e6*sum(failed))
# gradients <- lapply(outlist, function(x) x[["gradient"]])
# hessians <- lapply(outlist, function(x) x[["hessian"]])
# residuals <- do.call(rbind, lapply(outlist, function(x) attr(x, "residuals")))
#
# # Generate output list with combined value, gradient and hessian
# out <- init_empty_objlist(parsouter, deriv = deriv)
# out[["value"]] <- Reduce("+", values)
# if (deriv) {
# for (grad in gradients) out$gradient[names(grad)] <- out$gradient[names(grad)] + grad
# for (hes in hessians) out$hessian[rownames(hes), colnames(hes)] <- out$hessian[rownames(hes), colnames(hes)] + hes
# }
#
#
# nearPD2 <- function (x, corr = FALSE){
# # Ensure symmetry
# X <- 0.5*(x+t(x))
# # Eigenvalue decomposition
# e <- eigen(X)
# # Determine eigenvalues
# # If all >0 then do nothing
# # If minimum smaller than -1e-4 then do nothing
# # If minimum larger than -1e-4 then do the algorithm
# eV <- e$values
# if (min(eV) > 0) return(X)
# # Adjust negative eigenvalues to 0
# eV[eV<0] <- 0
# Xout <- e$vectors %*% diag(eV) %*% ginv(e$vectors)
# if (corr) diag(Xout) <- 1
# return(Xout)
# }
#
# if (opt.hessian["PD"] & deriv) {
# dn <- dimnames(out$hessian)
# out$hessian <- nearPD2(out$hessian)
# dimnames(out$hessian) <- dn
# }
#
# # Combine contributions and attach attributes
# attr(out, controls$attr.name) <- out$value
#
# # Add residuals if available
# out[["residuals"]] <- residuals
#
# # Add chisquare to outputs
# attr(out, "chisquare") <- Reduce("+", c(0, do.call(c,lapply(outlist, attr, which = "chisquare"))))
#
# return(out)
# }
#
#
# # -------------------------------------------------------------------------#
# # Other Indiv functions ---- #
# # -------------------------------------------------------------------------#
# myparfn <- Reduce("+", lapply(controls$conditions, function(cn) {
# parfn(
# p2p = function(pars, fixed, deriv) {
# dummy <- make_pars(parsouter = pars, fixedouter = fixed, condition = cn, est.grid = est.grid, fixed.grid = fixed.grid)
# pars0 <- dummy$pars
# fixed0 <- dummy$fixed
# as.parvec(c(pars0, fixed0))
# },
# parameters = parameters,
# condition = cn
# )
# }))
#
# class(myfn) <- c("objfn", "fn")
# attr(myfn, "conditions") <- data.conditions
# attr(myfn, "parameters") <- parameters
# attr(myfn, "modelname") <- dMod::modelname(prd0, errmodel)
# attr(myfn, "p_indiv") <- myparfn
#
# return(myfn)
#
#
# }
#
#
# # Grid-related functions ----
#
# # Build the est.grid from prd, fixed.grid, conditional and condition.grid
# #
# # Performs indiviudalization and localization of parameters
# #
# # @param prd0 prdfn for 1 condition. Extracts parameters via dMod::getParameters
# # @param fixed.grid As specified in template_project_sysfit.R: data.frame(parname, partask, ids...)
# # @param conditional As specified in template_project_sysfit.R: data.frame(parname, covname, covvalue)
# # @param condition.grid from datalist
# #
# # @return est.grid data.frame(parname, ids...)
# #
# # @examples
# # prd0 <- dMod::P(c(a = "exp(a + ETA_a)", "b" = "b", d = "d"))
# # fixed.grid <- stats::setNames(data.frame(parname = "d", partask = "Cond_specific", "1" = 1, "2" = NA, "3" = NA, stringsAsFactors = FALSE), c("parname", "partask", as.character(1:3)))
# # conditional <- data.frame(parname = c("b", "b", "d"), covname = "SEX", covvalue = c("male", "female", "male"), stringsAsFactors = FALSE)
# # condition.grid <- data.frame(ID = 1:3, SEX = c("female", "male", "male"), stringsAsFactors = FALSE)
# # iiv <- "ETA_a"
# # build_est.grid(prd0, fixed.grid, conditional, condition.grid, iiv)
# build_est.grid <- function(prd0, fixed.grid, conditional, condition.grid, iiv = NULL) {
# # [] unit test?
# check_cond(conditional, condition.grid)
#
# parameters <- dMod::getParameters(prd0)
# parameters_est <- setdiff(parameters, fixed.grid$parname)
# parameters_est <- union(parameters_est, conditional$parname)
# ids <- condition.grid$condition
#
# est.grid <- matrix(parameters_est, nrow = length(parameters_est), ncol = nrow(condition.grid), dimnames = list(parameters_est, ids))
# # 1 ETAs - iiv
# if (length(iiv))
# est.grid[iiv,] <- matrix(paste0(t(est.grid[iiv,,drop = FALSE]), "_", ids), ncol = length(ids), byrow = TRUE)
# # 2 LOCmodel
# if (length(conditional$parname)){
# for (x in seq_along(conditional$parname)) {
# # 1 Replace est pars by localized pars
# cn <- conditional[x,, drop = FALSE]
# ids_est <- as.character(condition.grid$condition[as.character(condition.grid[[cn$covname]]) == as.character(cn$covvalue)])
# est.grid[cn$parname,ids_est] <- paste0(est.grid[cn$parname,ids_est], "_", cn$covname, "_", cn$covvalue)
#
# if (length(intersect(cn$parname, fixed.grid$parname))){
# # 2 Replace fixed localized pars by NA
# ids_fix <- vapply(fixed.grid[fixed.grid$parname == cn$parname, -c(1:2)], function(y) !is.na(y), TRUE)
# ids_fix <- names(ids_fix)[ids_fix]
# est.grid[cn$parname,ids_fix] <- NA
# }
# }
# }
# # 3 Output data.frame
# # [] Handle partask properly
# est.grid <- cbind(data.frame(parname = parameters_est, partask = parameters_est, stringsAsFactors = FALSE),
# est.grid, stringsAsFactors = FALSE)
# rownames(est.grid) <- NULL
#
# check_grids(fixed.grid, est.grid)
#
# est.grid
# }
#
#
# # Extract parameter names from est.grid
# #
# # @param est.grid data.frame(parname, partask, ids...)
# #
# # @return character of outer parameter names
# #
# # @examples
# # eg_good <- stats::setNames(data.frame(parname = "d", partask = "Cond_specific", "1" = NA, "2" = "dummy", "3" = "dummy", stringsAsFactors = FALSE), c("parname", "partask", as.character(1:3)))
# # getParameters_est.grid(eg_good)
# getParameters_est.grid <- function(est.grid) {
# parameters <- unique(unlist(est.grid[-(1:2)], use.names = FALSE))
# parameters <- parameters[!is.na(parameters)]
# parameters <- sort(parameters)
# parameters
# }
#
#
#
#
# # Extract individualized parameters for one ID
# #
# # From the outer individualized parsouter and fixedouter, get the generalized parsouter0, fixedouter0 to supply to prd0
# #
# # Catch the following two cases:
# # * Entry in est.grid is NA => Parameter value present in fixed.grid
# # * Parameter name not present in parsouter => Parameter value present in fixed_outer
# #
# # @param parsouter,fixedouter Arguments which are passed to the function returned by [normIndiv]
# # @param condition The specific condition for which the parameters should be extracted
# # @param est.grid,fixed.grid Lookup tables.
# #
# # @md
# # @return list(pars, fixed) to put into prd0
# #
# # @importFrom stats setNames
# make_pars <- function(parsouter, fixedouter, condition, est.grid, fixed.grid) {
#
# # 1 Generate lookup for outer parameters
# outer_lookup <- stats::setNames(est.grid[[condition]], est.grid[["parname"]])
# outer_lookup <- outer_lookup[!is.na(outer_lookup)]
#
# # 2 Generate vector of all supplied "outer pars" to look things up
# outer.vec <- c(parsouter, fixedouter)
#
# # 3.1 Look up est parameters
# pars_lookup <- outer_lookup[outer_lookup %in% names(parsouter)]
# pars0 <- NULL
# if (length(pars_lookup))
# pars0 <- stats::setNames(parsouter[pars_lookup], names(pars_lookup))
#
# # 3.2 Look up fixed parameters
# fixed_lookup <- outer_lookup[outer_lookup %in% names(fixedouter)]
# fixedouter <- NULL
# if (length(fixed_lookup))
# fixedouter <- stats::setNames(fixedouter[fixed_lookup], names(fixed_lookup))
#
# # 4 Get fixed parameters from fixed.grid and combine with fixedouter
# fixed0 <- NULL
# if (nrow(fixed.grid)){
# fixed0 <- stats::setNames(fixed.grid[[condition]], fixed.grid[["parname"]])
# fixed0 <- fixed0[!is.na(fixed0)]
# }
# fixed0 <- c(fixed0, fixedouter)
#
# # 5 Output
# list(pars = pars0, fixed = fixed0)
# }
#
#
# # Do some consistency checks on conditional and condition.grid
# #
# # @param conditional see [normL2]
# # @param condition.grid condition.grid from data
# # @md
# check_cond <- function(conditional, condition.grid) {
# if (length(setdiff(conditional$covname, names(condition.grid))))
# stop("The following covariates to individualize parameters are not available: ", paste0(setdiff(conditional$covname, names(condition.grid)), collapse = ", "))
#
# cov_values <- unique(unlist(condition.grid[conditional$covname], use.names = FALSE))
# if (length(setdiff(conditional$covvalue, cov_values)))
# stop("The following covariate values to individualize parameters are not available: ", paste0(setdiff(conditional$covvalue, cov_values), collapse = ", "))
# }
#
#
#
# # Some consistency checks for fixed.grid and est.grid
# #
# # * Checks for localized parameters appearing in both grids that exactly one NA is in either of the grids
# # * More to come ...
# #
# # @param fixed.grid,est.grid data.frame(parname, partask, ids...)
# #
# # @return TRUE: All tests passed, else an error is thrown
# #
# # @examples
# # fg <- stats::setNames(data.frame(parname = "d", partask = "Cond_specific", "1" = 1, "2" = NA, "3" = NA, stringsAsFactors = FALSE), c("parname", "partask", as.character(1:3)))
# # eg_good <- stats::setNames(data.frame(parname = "d", partask = "Cond_specific", "1" = NA, "2" = "dummy", "3" = "dummy", stringsAsFactors = FALSE), c("parname", "partask", as.character(1:3)))
# # eg_bad1 <- stats::setNames(data.frame(parname = "d", partask = "Cond_specific", "1" = NA, "2" = NA, "3" = "dummy", stringsAsFactors = FALSE), c("parname", "partask", as.character(1:3)))
# # eg_bad2 <- stats::setNames(data.frame(parname = "d", partask = "Cond_specific", "1" = "dummy", "2" = "dummy", "3" = "dummy", stringsAsFactors = FALSE), c("parname", "partask", as.character(1:3)))
# #
# # check_grids(fg, eg_good)
# # check_grids(fg, eg_bad1)
# # check_grids(fg, eg_bad2)
# check_grids <- function(fixed.grid, est.grid) {
# par_overlap <- intersect(fixed.grid$parname, est.grid$parname)
# if (length(par_overlap)){
# # NA in both grids
# both_na_check <- lapply(stats::setNames(nm = par_overlap), function(x) {
# f <- fixed.grid[fixed.grid$parname == x, -(1:2)]
# e <- est.grid[est.grid$parname == x, -(1:2)]
# two_nas <- c(names(f)[is.na(f)], names(e)[is.na(e)])
# two_nas[duplicated(two_nas)]
# })
# both_na_check <- do.call(c, both_na_check)
# if (length(both_na_check)) stop("Parameter is NA in both fixed.grid and est.grid. The following parameters and conditions are affected", "\n", "\n", deparse(both_na_check))
#
# # Not NA in both grids
# none_na_check <- lapply(stats::setNames(nm = par_overlap), function(x) {
# f <- fixed.grid[fixed.grid$parname == x, -(1:2)]
# e <- est.grid[est.grid$parname == x, -(1:2)]
# no_nas <- c(names(f)[!is.na(f)], names(e)[!is.na(e)])
# no_nas[duplicated(no_nas)]
# })
# none_na_check <- do.call(c, none_na_check)
# if (length(none_na_check)) stop("Parameter is not NA in both fixed.grid and est.grid. The following parameters and conditions affected", "\n", "\n", deparse(none_na_check))
# }
# }
#
#
#
#
# # Indiv-objlist related functions ----
#
#
#
# # Rename the derivatives of an objective function according to a lookup table
# #
# # @param myobjlist dMod objective list
# # @param condition a specific condition (ID)
# # @param est.grid estimation grid
# #
# # @return objective list
# #
# # @author Daniel Lill
# rename_objlist <- function(myobjlist, condition, est.grid) {
# est_lookup <- stats::setNames(est.grid[[condition]], est.grid[["parname"]])
#
# if (!is.null(myobjlist$gradient)){
# grad_names <- stats::setNames(names(myobjlist$gradient), names(myobjlist$gradient))
#
# est_lookup_used <- names(est_lookup)[names(est_lookup) %in% grad_names]
# grad_names[est_lookup_used] <- est_lookup[est_lookup_used]
#
# names(myobjlist$gradient) <- grad_names
# }
# if (!is.null(myobjlist$hessian))
# dimnames(myobjlist$hessian) <- list(grad_names, grad_names)
#
# return(myobjlist)
# }
#
#
#
# # Create an objlist with zeros as entries
# # @param pars named vector. Only names and length are used
# # @param deriv TRUE or FALSE
# # @examples
# # init_empty_objlist(setNames(rnorm(5), letters[1:5]))
# init_empty_objlist <- function(pars, deriv = TRUE) {
#
# if (!deriv)
# return(dMod::objlist(0,NULL,NULL))
#
# dMod::objlist(value = 0,
# gradient = setNames(rep(0, length(pars)), names(pars)),
# hessian = matrix(0, nrow = length(pars), ncol = length(pars),
# dimnames = list(names(pars), names(pars))))
# }
#
#
#
# # Generalized Inverse of a Matrix
# #
# # Calculates the Moore-Penrose generalized inverse of a matrix X.
# #
# # @param X Matrix for which the Moore-Penrose inverse is required.
# # @param tol A relative tolerance to detect zero singular values.
# # @return A MP generalized inverse matrix for X.
# # @family Auxiliary
# # @export
# ginv <- function(X, tol = sqrt(.Machine$double.eps)) {
# if(length(dim(X)) > 2L || !(is.numeric(X) || is.complex(X)))
# stop("'X' must be a numeric or complex matrix")
# if(!is.matrix(X)) X <- as.matrix(X)
# Xsvd <- svd(X)
# if(is.complex(X)) Xsvd$u <- Conj(Xsvd$u)
# Positive <- Xsvd$d > max(tol * Xsvd$d[1L], 0)
# if (all(Positive)) Xsvd$v %*% (1/Xsvd$d * t(Xsvd$u))
# else if(!any(Positive)) array(0, dim(X)[2L:1L])
# else Xsvd$v[, Positive, drop=FALSE] %*% ((1/Xsvd$d[Positive]) * t(Xsvd$u[, Positive, drop=FALSE]))
# }
Add the following code to your website.
For more information on customizing the embed code, read Embedding Snippets.