views:

314

answers:

1
import numpy 
from numpy import asarray

Initial = numpy.asarray [2.0, 4.0, 5.0, 3.0, 5.0, 6.0]       # Initial values to start with


bounds = [(1, 5000), (1, 6000), (2, 100000), (1, 50000), (1.0, 5000), (2, 1000000)] 

# actual passed bounds

b1 = lambda x: numpy.asarray([1.4*x[0] - x[0]])  
b2 = lambda x: numpy.asarray([1.4*x[1] - x[1]])  
b3 = lambda x: numpy.asarray([x[2] - x[3]])     
constraints = numpy.asarray([b1, b2, b3])

opt= optimize.fmin_slsqp(func,Initial,ieqcons=constraints,bounds=bounds, full_output=True,iter=200,iprint=2, acc=0.01)

Problem: I want to pass in inequality constraints. Consider that I have 6 parameters

[ a, b, c, d, e, f]

in the Initial values, and my constraints are:

a<=e<=1.4*a   ('e' varies from a to 1.4*a)
b<=f<=1.4*b   ('f' varies from b to 1.4*b)
c>d           ('c' must always be greater than d)

But this is not working properly. I don't know what the mistake is. Is there any better way to pass my constraints as a function? Please help me.

A: 

Based on the comment from Robert Kern, I have removed my previous answer. Here are the constraints as continuous functions:

b1 = lambda x: x[4]-x[0] if x[4]<1.2*x[0] else 1.4*x[0]-x[4]
b2 = lambda x: x[5]-x[1] if x[5]<1.2*x[1] else 1.4*x[1]-x[5]
b3 = lambda x: x[2]-x[3]

Note: Python 2.5 or greater is required for this syntax.1

To get the constraint a<=e<=1.4*a, note that 1.2*a is the halfway point between a and 1.4*a.

Below this point, that is, all e<1.2*a, we use the continuous function e-a. Thus the overall constraint function is negative when e<a, handling the lower out-of-bounds condition, zero on the lower boundary e==a, and then positive for e>a up to the halfway point.

Above the halfway point, that is, all e>1.2*a, we use instead the continuous function 1.4*a-e. This means the overall constraint function is is negative when e>1.4*a, handling the upper out-of-bounds condition, zero on the upper boundary e==1.4*a, and then positive when e<1.4*a, down to the halfway point.

At the halfway point, where e==1.2*a, both functions have the same value. This means that the overall function is continuous.

Reference: documentation for ieqcons.

1 - Here is pre-Python 2.5 syntax: b1 = lambda x: (1.4*x[0]-x[4], x[4]-x[0])[x[4]<1.2*x[0]]

system PAUSE
No, this will not work. The constraint functions should be continuous as much as possible, >0 when they are satisfied, <0 when they are not, and ==0 when they are precisely on the boundary.
Robert Kern
system Pause, as Robert says function has to continuous. so i have made lambda x: ([1.4*x[0] - x[0]]), ie.,lambda x:(max-min). But what am i made is correct or not i don't know.
@pear, I don't think that can be correct, as it does not use *e* (aka `x[4]`) at all in the expression. That expression is equivalent to `1.4*a - a` which is always going to have the value `0.4a`.
system PAUSE
@system Pause, Thank you, it seems b1 and b2 are working good, but b3 = lambda x: x[2]-x[3] not working as expected.For example some times func() passes [150, 192, 1.8487, 2.07364, 194, 216], here b1 and b2 are well defined, but b3 is violated. Like this it happens couple of times.what to do? any better way of defining 'b2'?
@pear, Sorry, I don't know why `b3` is violated. Subtracting `c-d` (aka `x[2]-x[3]`) is a continuous function that is be positive when `c>d` and zero/negative when `c<=d`. But clearly 1.8487 < 2.07364, so I am stumped.
system PAUSE