Skip to content

Commit 287fb35

Browse files
roninsightrxclaude
andcommitted
Scale omega by weight_prior_var in FOCE Hessian computation
The MAP estimation objective uses omega/weight_prior_var as the prior covariance. The FOCE Hessian must match: H = (Omega/w)^{-1} + F'S^{-1}F. CWRES continues to use the unscaled omega (model-based diagnostic). Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
1 parent d61804f commit 287fb35

5 files changed

Lines changed: 20 additions & 5 deletions

File tree

R/calc_cwres.R

Lines changed: 11 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,9 @@
3838
#' @param A_init initial state vector
3939
#' @param t_init initialization time
4040
#' @param steady_state_analytic steady state settings (or NULL)
41+
#' @param weight_prior_var prior weight variance scaling factor (default 1).
42+
#' Used to scale omega in the FOCE Hessian computation to match the
43+
#' estimation objective. CWRES uses the unscaled omega (model diagnostic).
4144
#' @param delta perturbation size for finite differences
4245
#' @param ... additional arguments passed to PKPDsim::sim_ode
4346
#'
@@ -69,6 +72,7 @@ calc_cwres <- function(
6972
A_init = NULL,
7073
t_init = 0,
7174
steady_state_analytic = NULL,
75+
weight_prior_var = 1,
7276
delta = 1e-4,
7377
...
7478
) {
@@ -136,14 +140,16 @@ calc_cwres <- function(
136140
)
137141
}
138142

139-
# FOCE Hessian: H = Omega^{-1} + F' * Sigma^{-1} * F
140-
# vcov of etas = H^{-1}
143+
# FOCE Hessian: H = (Omega/w)^{-1} + F' * Sigma^{-1} * F
144+
# where w = weight_prior_var, matching the scaled omega used during MAP
145+
# estimation. vcov of etas = H^{-1}.
141146
# This reuses the Jacobian F already computed for CWRES, so no extra
142147
# simulations are needed (replaces the numDeriv::hessian computation).
143-
omega_est_inv <- tryCatch(solve(omega_est), error = function(e) NULL)
148+
omega_scaled <- omega_est / weight_prior_var
149+
omega_scaled_inv <- tryCatch(solve(omega_scaled), error = function(e) NULL)
144150
vcov <- NULL
145-
if (!is.null(omega_est_inv)) {
146-
H_foce <- omega_est_inv +
151+
if (!is.null(omega_scaled_inv)) {
152+
H_foce <- omega_scaled_inv +
147153
t(F_matrix) %*% diag(1 / sigma_diag, nrow = n_obs) %*% F_matrix
148154
vcov <- tryCatch(solve(H_foce), error = function(e) {
149155
warning("FOCE variance-covariance computation failed.")

R/calc_residuals.R

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,7 @@ calc_residuals <- function(
3939
nonfixed = NULL,
4040
as_eta = c(),
4141
steady_state_analytic = NULL,
42+
weight_prior_var = 1,
4243
...
4344
) {
4445

@@ -139,6 +140,7 @@ calc_residuals <- function(
139140
A_init = A_init_individual,
140141
t_init = t_init,
141142
steady_state_analytic = steady_state_analytic,
143+
weight_prior_var = weight_prior_var,
142144
...
143145
),
144146
error = function(e) {

R/get_map_estimates.R

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -434,6 +434,7 @@ get_map_estimates <- function(
434434
nonfixed = omega$nonfixed,
435435
as_eta = as_eta,
436436
steady_state_analytic = steady_state_analytic,
437+
weight_prior_var = weight_prior_var,
437438
...
438439
)
439440
}

man/calc_cwres.Rd

Lines changed: 5 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

man/calc_residuals.Rd

Lines changed: 1 addition & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

0 commit comments

Comments
 (0)