spectrum
spectrum

Reputation: 61

scipy.optimize.minimize with matrix constraints

I am new to scipy.optimize module. I am using its minimize function trying to find a x to minimize a multivariate function, which takes matrix input but return a scalar value. I have one equality constraint and one inequality constraint, both taking vector input and return vector values. Particularly, here is the list of constraints:

sum(x) = 1 ;

AST + np.log2(x) >= 0

where AST is just a parameter. I defined my constraint functions as below:

For equality constraint: lambda x: sum(x) - 1

For inequality constraint:

def asset_cons(x):

      #global AST

      if np.logical_and.reduce( (AST + np.log2(x)) >= 0):
        return 0.01
      else:
        return -1   

Then I call

cons = ({'type':'eq', 'fun': lambda x: sum(x) - 1},

            {'type':'ineq', 'fun': asset_cons})

res = optimize.minize(test_obj, [0.2, 0.8], constraints = cons)

But I still got error complaining my constraint function. Is it allowed to return vector value for constraint function or I have to return a scalar in order to use this minimize function?

Could anyone help me to see if the way I specify the constraints has any problems?

Upvotes: 1

Views: 2023

Answers (1)

DrV
DrV

Reputation: 23480

In principle this does not look that wrong at all. However, it is a bit difficult to say without seeing something about test_obj and the actual error. Does it throw an exception (which hints at a programming error) or complain about convergence (which hints at a mathematical challenge)?

You have the basic idea right; you need to have a function accepting an input vector with N elements and returning the value to be minimized. Your boundary conditions should also accept the same input vector and return a single scalar as their output.

To my eye there is something wrong with your boundary conditions. The first one (sum(x) - 1) is fine, but the second one is mathematically challenging, as you have defined it as a stepwise function. Many optimization algorithms want to have continuous functions with preferable quite smooth behaviour. (I do not know if the algorithms used by this function handle stepwise functions well, so this is just a guess.

If the above holds true, you might make things easier by, for example:

np.amin(AST + np.log2(x))

The function will be non-negative if all AST + log2(x[n]) >= 0. (It is still not extremely smooth, but if that is a problem it is easy to improve.) And now it'll also fit into one lambda.

If you have difficulties in convergence, you should probably try both COBYLA and SLSQP, unless you already know that one of them is better for your problem.

Upvotes: 0

Related Questions