rnonlinear-optimizationnlopt

nloptr Algorithm Explanation


Is anyone able to provide a layman's explanation for why the nloptr algorithm should terminate when an optimisation step changes every parameter by less than xtol_rel multiplied by the absolute value of the parameter? Why is this a good condition to draw the conclusion that this iteration is the local optimum? I am finding it difficult to understand the intuition behind it.

I can provide an example of the optimisation that I am working on:

eval_f0 <- function(x){
  return(-((plogis(-2.15083 + 0.0000471*x[1])*exp(9.87243)*(x[1])^0.468)+
             (plogis(-2.15083 + 0.0000471*x[2])*exp(9.87243)*(x[2])^0.468)+
             (plogis(-2.15083 + 0.0000471*x[3])*exp(9.87243)*(x[3])^0.468)+
             (plogis(-2.15083 + 0.0000471*x[4])*exp(9.87243)*(x[4])^0.468)+
             (plogis(-1.86183 + 0.0000471*x[5])*exp(9.04243)*(x[5])^0.468)+
             (plogis(-1.86183 + 0.0000471*x[6])*exp(9.04243)*(x[6])^0.468)+
             (plogis(-1.86183 + 0.0000471*x[7])*exp(9.04243)*(x[7])^0.468)+
             (plogis(-1.86183 + 0.0000471*x[8])*exp(9.04243)*(x[8])^0.468)+
             (plogis(-1.06983 + 0.0000471*x[9])*exp(9.23543)*(x[9])^0.468)+
             (plogis(-1.06983 + 0.0000471*x[10])*exp(9.23543)*(x[10])^0.468)+
             (plogis(-1.06983 + 0.0000471*x[11])*exp(9.23543)*(x[11])^0.468)+
             (plogis(-1.06983 + 0.0000471*x[12])*exp(9.23543)*(x[12])^0.468)))
}

# constraint function
eval_g0 <- function(x)
{
  return(x[1]+x[2]+x[3]+x[4]+x[5]+x[6]+x[7]+x[8]+x[9]+x[10]+x[11]+x[12]-50000)
}

# Set optimization options.
opts <- list( "algorithm"= "NLOPT_LN_COBYLA",
              "xtol_rel"= 1.0e-7,
              "maxeval"= 1000000,
              "print_level" = 3 )

# Solve 
res2 <- nloptr( x0=c(10000,3666,2000,1000,10000,3666,2000,1000,10000,3666,2000,1000),
                eval_f=eval_f0,
                lb = c(0,0,0,0,0,0,0,0,0,0,0,0),
                ub = c(80000,80000,80000,80000,80000,80000,80000,80000,80000,80000,80000,80000),
                eval_g_ineq = eval_g0,
                opts = opts)

Solution

  • Generally speaking, the maximum absolute error is given by

    abs(y[k+1] - y[k]) < abs_tol
    

    and the maximum relative error is given by

    abs((y[k+1] - y[k])/y[k]) < rel_tol
    abs(y[k+1] - y[k]) < rel_tol * abs(y[k])
    

    Therefore, it makes sense to use the relative error multiplied by the absolute value of the iteration y[k].

    abs(y[k+1] - y[k]) < abs_tol
    abs(y[k+1] - y[k]) < rel_tol * abs(y[k])
    

    or

    abs(y[k+1] - y[k]) < max( rel_tol * abs(y[k]), abs_tol )
    

    nloptr::nloptr has two values for the relative tolerance, xtol_rel and ftol_rel. See the vignette, section Description of options. Or, in R, run

    vignette("nloptr", package = "nloptr")