Scipy maximization by changing only some parameters

Viewed 181

I have a function that takes in a number of input parameters and returns a single result

def objective(a, b, c, d, e, f):
...
return result

I would like to find the values of a, b, and c within certain ranges that maximize result, while keeping d, e, and f constant.

I have been browsing around to understand how scipy.optimize.minimize works, but I am not sure I get how I could achieve this.

What I don't understand how to do is:

  1. How to pass the constraints for a, b, and c separately (say, a needs to be within [-1, 0], b needs to be within [0, 1], etc.)
  2. How to make sure d, e, and f are kept exogenous to the maximization exercise (i.e. they are not flexed) - and I suppose conversely, how to instruct the minimize function to flex a, b, and c.
1 Answers

To 2: You could simply create a new objective function that has only three parameters. A simple way to do this is to use lambda-functions:

d = ...
e = ...
f = ...
myNewObjective = lambda a, b, c: -objective(a, b, c, d, e, f)
scipy.optimize.minimize(objective, [0, 0, 0], method = 'L-BFGS-B')

As you want to maximise your objective and scipy only supports minimisation you should minimise -objective, hence the additional minus in the definition of myNewObjective.

To 1: You can pass scipy.optimize.Bounds objects to some of the optimiser functions, for example

bounds = scipy.optimize.Bounds([-1.0, 0.0, 0.0], [0.0, 1.0, 1.0])
scipy.optimize.minimize(myNewObjective, x0, bounds = bounds, method = 'L-BFGS-B')

You simply have to pass the lower and upper bounds when building the bounds. Please note that only some of the optimiser types can actually deal with this kind of constraints, for example L-BFGS-B or TNC so you have to choose the right optimiser using the method argument.

Related