Skip to content
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
87 changes: 71 additions & 16 deletions R/fimsfit.R
Original file line number Diff line number Diff line change
Expand Up @@ -566,15 +566,49 @@ fit_fims <- function(input,
## optimize and compare
cli::cli_inform(c("v" = "Starting optimization ..."))
t0 <- Sys.time()
opt <- with(
obj,
nlminb(
start = par,
objective = fn,
gradient = gr,
control = control
)
opt <- tryCatch(
{
with(
obj,
nlminb(
start = par,
objective = fn,
gradient = gr,
control = control
)
)
},
error = function(e) {
cli::cli_warn(c(
"!" = "nlminb failed: {e$message}",
"i" = "Returning partial results."
))
return(NULL)
}
)

if (is.null(opt)) {

timing <- c(
time_optimization = Sys.time() - t0,
time_sdreport = as.difftime(0, units = "secs"),
time_total = Sys.time() - t0
)

fit <- FIMSFit(
input = input,
obj = obj,
opt = list(
par = obj[["par"]],
objective = NA_real_,
convergence = 1L
),
sdreport = list(),
timing = timing
)

return(fit)
}
maxgrad0 <- maxgrad <- max(abs(obj$gr(opt[["par"]])))
if (number_of_loops > 0) {
cli::cli_inform(c(
Expand All @@ -585,15 +619,36 @@ fit_fims <- function(input,
# differences in values printed out using control$trace will be
# negligible between these different runs and is not worth printing
control$trace <- 0
opt <- with(
obj,
nlminb(
start = opt[["par"]],
objective = fn,
gradient = gr,
control = control
)
# store the previous optimization result
prev_opt <- opt
opt <- tryCatch(
{
with(
obj,
nlminb(
start = opt[["par"]],
objective = fn,
gradient = gr,
control = control
)
)
},
error = function(e) {
cli::cli_warn(c(
"!" = "nlminb failed during loop: {e$message}",
"i" = "Using previous optimization result."
))
return(NULL)
}
)

if (is.null(opt)) {
# fallback to last successful result
opt <- prev_opt
# exit loop early, keep valid opt
break
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should this just break or should it return the same style of non-converged item that is returned above? If this loop doesn't converge does it go back to the previous object that did converge? I am confused on what the outcome of break leads to here.

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You are right, using break with a NULL opt can lead to ambiguity. I will update the logic to retain the last successful optimization result and use that as a fallback if a failure occurs during the loop. This ensures that the returned object remains consistent.

}

maxgrad <- max(abs(obj[["gr"]](opt[["par"]])))
}
div_digit <- cli::cli_div(theme = list(.val = list(digits = 5)))
Expand Down