hjli
hjli

Reputation: 3

Why do constraints fail in scipy.optimize.minimize

    def get_cons(self, ub, lb):
        cons = []
        for i in range(len(ub)):
            cons.append({'type':'ineq','fun':lambda x0:ub[i]-x0[i]})
            cons.append({'type':'ineq','fun':lambda x0:x0[i]-lb[i]})
        return cons
    ub = [1,3,1,1]
    lb = [0,0,0,0]
    cons = self.get_cons(self.ub, self.lb)
    res = minimize(fun, x0[:,i], method='SLSQP', constraints=cons)

Here fun is custom loss function initial parameter is [0.08024884 0.14003958 0.0786131 0.00157402]. I expect all parameter>0,but after optimize parmeter is [-0.45684621 0.02531972 -0.10755587 0.2108312].

Whether this constraint fails?

Upvotes: 0

Views: 100

Answers (1)

joni
joni

Reputation: 7157

There's no need to use generic constraints for adding simple bounds on the variables. Instead, pass the variable bounds via minimize's bound argument:

bounds = [(l, u) for (l, u) in zip(lb, ub)]

res = minimize(fun, x0[:, i], bounds=bounds, method="SLSQP") 

However, if you really want to pass the bounds as generic constraints, you need to capture the value of the loop variable i:

for i in range(len(ub)):
    cons.append({'type':'ineq','fun': lambda x0, i=i: ub[i]-x0[i]})
    cons.append({'type':'ineq','fun': lambda x0: i=i: x0[i]-lb[i]})
return cons

Otherwise, each constraint shares the value of i of the last loop iteration, see here for further details.

Upvotes: 1

Related Questions