8

I'm using the algorithm 'COBYLA' in scipy's optimize.minimize function (v.0.11 build for cygwin). I observed that the parameter bounds seems not to be used in this case. For instance, the simple example:

from scipy.optimize import minimize

def f(x):
    return -sum(x)

minimize(f, x0=1, method='COBYLA', bounds=(-2,2))

returns:

status: 2.0
nfev: 1000
maxcv: 0.0
success: False
fun: -1000.0
x: array(1000.0)
message: 'Maximum number of function evaluations has been exceeded.'

instead of the expected 2 for x.

Did anyone perceived the same problem? Is there a known bug or documentation error? In the scipy 0.11 documentation, this option is not excluded for the COBYLA algorithm. In fact the function fmin_cobyla doesn't have the bounds parameter. Thanks for any hint.

Pedro Romano
  • 10,973
  • 4
  • 46
  • 50
saxophonian
  • 81
  • 1
  • 2
  • Sounds like it should work, but maybe you have to use `bounds=[(-2,2)]`. I don't have a new scipy with minimize to try though. – seberg Oct 08 '12 at 12:59

2 Answers2

13

You can formulate the bounds in the form of constraints

import scipy
#function to minimize
def f(x):
    return -sum(x)
#initial values
initial_point=[1.,1.,1.]    
#lower and upper bound for variables
bounds=[ [-2,2],[-1,1],[-3,3]   ]

#construct the bounds in the form of constraints
cons = []
for factor in range(len(bounds)):
    lower, upper = bounds[factor]
    l = {'type': 'ineq',
         'fun': lambda x, lb=lower, i=factor: x[i] - lb}
    u = {'type': 'ineq',
         'fun': lambda x, ub=upper, i=factor: ub - x[i]}
    cons.append(l)
    cons.append(u)

#similarly aditional constrains can be added

#run optimization
res = scipy.optimize.minimize(f,initial_point,constraints=cons,method='COBYLA')
#print result
print res

Note that the minimize function will give the design variables to the function. In this case 3 input variables are given with 3 upper and lower bounds. the result yields:

   fun: -6.0
   maxcv: -0.0
 message: 'Optimization terminated successfully.'
    nfev: 21
  status: 1
 success: True
       x: array([ 2.,  1.,  3.])
5

The original COBYLA(2) FORTRAN algorithm does not support variable bounds explicitly, you have to formulate the bounds in the context of the general constraints.

Looking at the current source code for the SciPy minimize interface here, it is apparent that no measures has yet been taken in SciPy to handle this limitation.

Thus, in order to apply bounds for the cobyla algorithm in the SciPy minimize function, you will need to formulate the variable bounds as inequality constraints and contain them in the associated constraints parameter.

(source code excerpt)

// bounds set to anything else than None yields warning
if meth is 'cobyla' and bounds is not None:
    warn('Method %s cannot handle bounds.' % method,
         RuntimeWarning)
...
// No bounds argument in the internal call to the COBYLA function
elif meth == 'cobyla':
    return _minimize_cobyla(fun, x0, args, constraints, **options)
Anders Gustafsson
  • 15,837
  • 8
  • 56
  • 114