roptimizationmathematical-optimization

R optimx, recovering internally stored values after interruption


My optimization code runs for several days, and for external reasons, I have from time to time to interrupt/abort the code, by clicking on "stop" with R-studio. Is there a possibility to see what is the content of the last optimization iteration, which has not been saved in an object (but must be in the computers' memory), or is this information definitively lost? traceback() is not helpful. I use the optimx package.

The following simple code can be run (and has to be interrupted by hand) to illustrate my question.

require(optimx) 
# genrose function code
genrose.f<- function(x, gs=NULL){ # objective function
  ## One generalization of the Rosenbrock banana valley function (n parameters)
  n <- length(x)
  if(is.null(gs)) { gs=100.0 }
  fval<-1.0 + sum (gs*(x[1:(n-1)]^2 - x[2:n])^2 + (x[2:n] - 1)^2)
  return(fval)
}

startx <- seq(1:100) / 5
n <- length( startx )

# Here is the command which has to be stopped by hand after few seconds
ans = optimx( startx, fn=genrose.f, gr=NULL, hess=NULL, 
              method=c("Nelder-Mead"),
              control=list( maxit=5000000, save.failures=TRUE, trace=3), gs=10)

Solution

  • You can modify your objective function to store the information about the last call (not exactly the same as the last iteration of the optimization algorithm, as an iteration usually involves several calls to the objective function) in the function's environment, e.g.

    library(optimx) 
    last_it <- 0
    last_pars <- NA_real_
    last_val <- NA_real_
    genrose.f <- function(x, gs=100) {
      last_pars <<- x
      last_it <<- last_it + 1
      n <- length(x)
      fval <- 1.0 + sum (gs*(x[1:(n-1)]^2 - x[2:n])^2 + (x[2:n] - 1)^2)
      last_val <<- fval
      return(fval)
    }
    
    startx <- seq(1:100) / 5
    n <- length( startx )
    
    ans = optimx( startx, fn=genrose.f, gr=NULL, hess=NULL, 
                  method=c("Nelder-Mead"),
                  control=list( maxit=5000000, save.failures=TRUE,
                  trace=3), gs=10)
    

    After stopping:

    > last_val
    [1] 9954591
    > last_it
    [1] 88872
    > head(last_pars)
    [1]  8.071216  6.878062 -4.777840  6.682326  7.567179  7.840888
    

    In this case the environment of the function is the global workspace. If you're going to use <<- you need to make sure that the last_* variables are defined externally before you run the function. If you want to be slightly more careful, or if you were going to include this code in a package being submitted to CRAN (who disapprove of <<- in package code), you would use assign("last_pars", x, parent.frame()) instead.