[SciPy-User] fmin_slsqp- Bounds are not obeyed

josef.pktd at gmail.com josef.pktd at gmail.com
Tue Nov 3 22:40:47 EST 2009


On Tue, Nov 3, 2009 at 3:09 PM, Zachary Pincus <zachary.pincus at yale.edu> wrote:
> Hello,
>
>> Problem is " Bounded with inequality constrains", in slssqp often
>> Bounds are not obeyed, its deviates the bounds. So if deviates i
>> made it to come back with in the region(bounds). But i face a
>> problem in execution. i get error like,
>>
>> File "/usr/lib/python2.5/site-packages/scipy/optimize/slsqp.py",
>> line 277, in fmin_slsqp
>>     c_ieq = array([ ieqcons[i](x) for i in range(len(ieqcons)) ])
>>   File "/usr/lib/python2.5/site-packages/scipy/optimize/
>> optimize.py", line 97, in function_wrapper
>>     return function(x, *args)
>> TypeError: <lambda>() takes exactly 1 argument (2 given)
>
> I can't help with the bounds not being obeyed... but I can say that
> you'll probably need to provide more detail about what you mean by
> this for others to help though -- is it that the optimizer will
> occasionally evaluate the objective outside of the bounds (which I
> understand is normal?) or that the final results are out-of-bounds?
>
> Anyhow, the traceback explains exactly what the problem with the
> execution is. You define your inequality constraint as:
> con1 = lambda x:numpy.asarray(x[1]-x[0], x[2]-x[1])
>
> but from the traceback, you can see that it is being called like:
> function(x, *args)
>
> The error is quite clear on the problem: your lambda takes one
> argument, but it is called with two.
>
> I assume that x is the current position, and args is just what you
> passed to the slsqp. So you should rewrite con1 as lambda x, args:
> whatever...
>
> Zach
>
>
>
> On Nov 3, 2009, at 2:58 PM, jagan prabhu wrote:
>
>> Dear users,
>>
>> Problem is " Bounded with inequality constrains", in slssqp often
>> Bounds are not obeyed, its deviates the bounds. So if deviates i
>> made it to come back with in the region(bounds). But i face a
>> problem in execution. i get error like,
>>
>> File "/usr/lib/python2.5/site-packages/scipy/optimize/slsqp.py",
>> line 277, in fmin_slsqp
>>     c_ieq = array([ ieqcons[i](x) for i in range(len(ieqcons)) ])
>>   File "/usr/lib/python2.5/site-packages/scipy/optimize/
>> optimize.py", line 97, in function_wrapper
>>     return function(x, *args)
>> TypeError: <lambda>() takes exactly 1 argument (2 given)
>>
>> program will look like,
>>
>>
>> #import os
>> #import scipy.optimize
>> from scipy import *
>> import numpy
>> from scipy import optimize
>> from numpy import asarray
>> from math import *
>>
>>
>> def cst(aParams,bounds):
>>   aParams = numpy.asarray(aParams)
>>   for par in range(len(aParams)):
>>    if ((bounds[par][0]<= aParams[par]<= bounds[par][1])):
>>      pass
>>    else:
>>      if (aParams[par]< bounds[par][0]): aParams[par] = bounds[par][0]
>>      if (aParams[par]> bounds[par][1]): aParams[par] = bounds[par][1]
>>
>>   x = aParams[0]
>>   y = aParams[1]
>>   z = aParams[2]
>> # objective function
>>   eqn = -cos(x)*cos(y)*cos(z)*log(-((x-pi)**2-(y-pi)**2-(z-pi)**2))
>>   return eqn
>>
>>
>> #Initial guess
>> Init = numpy.array([5.0,15.0,17.0]) # parameters x,y,z
>> bounds = [(2.0, 20000.0),(4.0, 50000.0),(5.0, 60000.0)]
>> # inequality constraints x must be least,y larger than x smaller
>> than z,and z the largest of all
>> con1 = lambda x:numpy.asarray(x[1]-x[0], x[2]-x[1])
>>
>>
>> opt = fmin_slsqp(cst,Init,ieqcons= [con1] , bounds=bounds, fprime =
>> None, args=(bounds,), full_output=True, iter=20000, iprint=2,
>> acc=0.001)
>>
>> print '****************************************'
>>
>> print opt[0]
>> print opt[1]
>> print opt[2]
>> print opt[4]
>>
>> Problems are,
>> 1, bounds i could not able to pass to the function as args( ).
>> 2, Whether implementation of the ineq. constraints are correct? any
>> better way?
>> 3, How to avoid bounds deviation?
>>
>> Please help me.
>>
>> Regards,
>> Prabhu
>>

According to the slsqp help   inequality constraints are supposed to
be a list of functions

running your example with the args as mentioned by Zachary, produced a
result that violated the second inequality

changing to this

con1 = [lambda x,args: x[1]-x[0],
        lambda x,args: x[2]-x[1]]


opt = optimize.fmin_slsqp(cst, Init, ieqcons= con1 , bounds=bounds,
fprime = None, args=(bounds,), full_output=True, iter=20000, iprint=2,
acc=0.001)

gives results with second ineq constraint binding:

****************************************
[6.2838144667527311, 15.724071907665964, 15.724071907665964]
-5.72459190155
6
Optimization terminated successfully.


I don't know why in your example

np.asarray(x[1]-x[0], x[2]-x[1])

doesn't raise an exception,  the second argument to asarray is dtype,
so this should be wrong. (missing [])

>>> xx=opt[0]
>>> xx
[6.2838144667527311, 15.724071907665964, 15.724071907665964]
>>> np.asarray(xx[1]-xx[0], xx[2]-xx[1])
array(9.440257440913232)

There was also recently a nice example for slsqp on the mailing list.

Josef



More information about the SciPy-User mailing list