stevengj / nlopt

library for nonlinear optimization, wrapping many algorithms for global and local, constrained or unconstrained, optimization
Other
1.89k stars 588 forks source link

Misleading output from COBYLA / SLSQP with infeasible start value #254

Open ashander opened 5 years ago

ashander commented 5 years ago

This is a 2d toy problem with no feasible region within the constraints (x-y > 0 and -1 > x - y; reported as a bug in scipy here https://github.com/scipy/scipy/issues/7618 )

Using the R interface the problem is:

library(nloptr)
cost <- function(x) -1 * x[1] + 4 * x[2]
in1 <- function(x) x[2] - x[1] - 1
in2 <- function(x) x[1] - x[2]
xl <- c(-5 ,-5)
xu <- c(5, 5)
x_con <- function(x) c(in1(x), in2(x))
x0 <- c(1, 5) # infeasible, as there is no feasible region

Both SLSQP and COBYLA return apparent convergence

SLSQP

slsqp(x0=x0, fn=cost, hin=x_con, lower=xl, upper=xu)
$par
[1] -5 -4

$value
[1] -11

$iter
[1] 5

$convergence
[1] 4

$message
[1] "NLOPT_XTOL_REACHED: Optimization stopped because xtol_rel or xtol_abs
(above) was reached." 

COBYLA

cobyla(x0=x0, fn=cost, hin=x_con, lower=xl, upper=xu)
$par
[1] -4.999999 -4.500001

$value
[1] -13.00001

$iter
[1] 70

$convergence
[1] 4

$message
[1] "NLOPT_XTOL_REACHED: Optimization stopped because xtol_rel or xtol_abs
(above) was reached."
stevengj commented 5 years ago

Yes, the algorithms get confused here. In general, most algorithms only guarantee convergence to a local optimum if they are given a feasible starting point.

It would be nicer to return an error code here. The trick is reliably detecting this case, since in the case of an active constraint some algorithms may approach the feasible set from the outside. An extreme case would be nonlinear equality constraint h(x)=0, in which case the converged value will usually be at best within O(xtol) of the feasible set. So returning an error code simply because the error is infeasible wouldn't be good.

If the user specifies a positive tolerance for the constraint, I suppose we could return an error if the optimum is infeasible within this tolerance. But since the default tolerance is zero I don't know that we should return an error in that case if the return value is slightly infeasible.

smjaberl commented 5 years ago

Well a workaround is, to check manually, if the solution respect the constrains or not. Checking manually means, to check it after you get the solution of the optimizer.

It would be very nice to get well-defined output.