astamm / nloptr

nloptr provides an R interface to NLopt, a free/open-source library for nonlinear optimization providing a common interface to a number of different optimization routines which can handle nonlinear constraints and lower and upper bounds for the controls.

Home Page:https://astamm.github.io/nloptr/

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Equality constraint with COBYLA

fangzhou-xie opened this issue · comments

Hi, the NLopt documentation mentions that "Only some of the NLopt algorithms (AUGLAG, SLSQP, COBYLA, and ISRES) currently support nonlinear equality constraints".

However, the following example will run into error:

f <- function(x) {
  return(sum(x^2))
}

eq <- function(x) {
  return(sum(x)-1)
}


sol <- nloptr::nloptr(
  x0 = c(.1, .4),
  eval_f = f,
  lb = c(0, -Inf),
  ub = c(Inf, Inf),
  eval_g_eq = eq,
  opts = list("algorithm" = "NLOPT_LN_COBYLA")
)
#> Warning in nloptr.add.default.options(opts.user = opts, x0 = x0,
#> num_constraints_ineq = num_constraints_ineq, : No termination criterium
#> specified, using default (relative x-tolerance = 1e-04)
#> Error in is.nloptr(ret): If you want to use equality constraints, then you should use one of these algorithms 
# NLOPT_LD_AUGLAG, NLOPT_LN_AUGLAG, NLOPT_LD_AUGLAG_EQ, NLOPT_LN_AUGLAG_EQ, NLOPT_GN_ISRES, NLOPT_LD_SLSQP

Created on 2023-03-14 with reprex v2.0.2

I am not sure why this is the case and I greatly appreciate any help. Thank you very much!

For my naive example, I could pack the COBYLA algorithm as the local algo for AUGLAG to make it work. But I am still curious why directly using COBYLA wouldn't work.

f <- function(x) {
  return(sum(x^2))
}

eq <- function(x) {
  return(sum(x)-1)
}


sol <- nloptr::nloptr(
  x0 = c(.1, .4),
  eval_f = f,
  lb = c(0, -Inf),
  ub = c(Inf, Inf),
  eval_g_eq = eq,
  opts = list(
    "algorithm" = "NLOPT_LN_AUGLAG_EQ",
    "xtol_rel" = 1.0e-8,
    "maxeval"    = 1000,
    "local_opts" = list(
      "algorithm" = "NLOPT_LN_COBYLA",
      "maxeval"    = 1000,
      "xtol_rel" = 1.0e-8
    )
  )
)

sol$solution
#> [1] 0.4999605 0.4999605

Created on 2023-03-14 with reprex v2.0.2

It's kicked out by lines 193–203 in is.nlopt. While it isn't in the help there, it is in the help for cobyla. Specifically "COBYLA supports equality constraints by transforming them into two inequality constraints. As this does not give full satisfaction with the implementation in NLOPT, it has not been made available here." I presume @jyypma and @hwborchers agreed not to implement it using nlopt as well.

This is worth looking into. I'll take a look soon. If it is possible to use nonlinear equality constraints in COBYLA from nlopt, I do not see why this would not be supported by nloptr.

commented

Thanks @jyypma and @aadler. I will make the fix in is.nloptr.