Skip to contents

verify_convergence() re-runs the fit under the engine's bounded verification workflow and reports whether the extra runs agree with the fitted optimum: a restart from the optimum, one or more jittered restarts, and (LMM-only, opt-in) an alternate-optimizer consensus pass. Agreement is judged by the engine against the objective/theta/beta tolerances below; the verdict (status), the per-run deltas, and the wording are all owned by the Rust contract — R only formats them.

Usage

verify_convergence(fit, ...)

# Default S3 method
verify_convergence(fit, ...)

# S3 method for class 'mm_lmm'
verify_convergence(
  fit,
  ...,
  restart = TRUE,
  jitter_starts = 1L,
  jitter_scale = 1e-04,
  consensus = FALSE,
  max_feval = 500L,
  objective_tolerance = 1e-05,
  theta_tolerance = 0.001,
  beta_tolerance = 1e-04
)

# S3 method for class 'mm_glmm'
verify_convergence(
  fit,
  ...,
  restart = TRUE,
  jitter_starts = 1L,
  jitter_scale = 1e-04,
  consensus = FALSE,
  max_feval = 1000L,
  objective_tolerance = 1e-04,
  theta_tolerance = 0.001,
  beta_tolerance = 0.001
)

Arguments

fit

A fitted mm_lmm from lmm() or mm_glmm from glmm().

...

Reserved for future methods.

restart

Logical; re-optimize starting from the fitted optimum and compare against it.

jitter_starts

Number of restarts from jittered copies of the fitted covariance parameters.

jitter_scale

Relative scale of the jitter applied to theta.

consensus

Logical; also refit with an engine-chosen alternate optimizer and compare. Default FALSE: this vendored build compiles without the optional nlopt backend, and for some models the engine's alternate choice is an nlopt optimizer — its absence would then be reported as a non-agreeing run (status fragile) that reflects the build, not the fit. Enable it when you want the consensus pass and will read the per-run diagnostics.

max_feval

Positive integer cap on objective evaluations per verification run.

objective_tolerance, theta_tolerance, beta_tolerance

Positive agreement tolerances on the objective value, the covariance parameters, and the fixed effects.

Value

An object of class mm_convergence_verification carrying:

status

the engine verdict: not_run, restart_agrees, optimizer_consensus, fragile, or unstable

message

the engine's one-line summary

table

a data frame with one row per verification run (label, optimizer, return code, objective/theta/beta deltas, agreement)

reference

the reference optimum the runs were compared to

tolerances

the agreement tolerances that were applied

raw

the parsed engine payload

Details

The verifier refits the model from the stored specification before it starts, so a call costs roughly 2 + jitter_starts fits (plus consensus runs when enabled). GLMM verification uses wider default tolerances than the LMM route (objective 1e-4, beta 1e-3): each objective evaluation carries inner-PIRLS noise, and the joint path's derivative-free beta search bounds beta reproducibility at its ftol stop. A GLMM whose requested joint_laplace estimator was substituted by the labelled fast-PIRLS fallback (see optimizer_certificate()) re-requests the joint route; when the verification refit falls back the same way — the expected case — every run verifies the profiled objective the fitted numbers came from, with ordinary objective deltas. Runs are only reported as substitution runs (no objective delta) in the asymmetric case where the reference refit certifies the joint route but an individual verification run falls back.

See also

optimizer_certificate() for what the original fit ran; mm_control() to refit with a different optimizer or tolerances.

Examples

set.seed(1)
df <- data.frame(t = rep(0:4, 8), s = factor(rep(1:8, each = 5)))
df$y <- 1 + 0.5 * df$t + rnorm(8)[df$s] + rnorm(40)
fit <- lmm(y ~ t + (1 | s), df, control = mm_control(verbose = -1))
verify_convergence(fit)
#> Convergence verification (status: restart_agrees)
#>   restart from fitted theta agrees with the recorded optimum
#> Runs:
#>                 label      optimizer return_code objective_value
#>  restart_from_optimum pattern_search     SUCCESS         112.048
#>      jitter_restart_1 pattern_search     SUCCESS         112.048
#>  objective_delta theta_delta  beta_delta agrees
#>      0.00000e+00 0.00000e+00 0.00000e+00   TRUE
#>      9.08287e-10 5.90301e-06 1.33227e-15   TRUE
#> Tolerances: objective 1e-05; theta 0.001; beta 1e-04