I have an optimization problem where I want to use the scipy.optimize.minimize
package, namely one of the methods that do not foresee any constraints or bounds, like 'nelder-mead', 'powell', 'cg', 'bfgs', newton-cg', 'dogleg', 'trust-ncg' - see: minimize exception about bounds and constraints.
I would like to introduce bounds by myself by adding a wrapper around my cost function:
This wrapper gets called by the optimizer and passes the parameters to the cost function I would like to optimize. The cost function than returns a value to the wrapper.
If the optimizer has called the wrapper with a parameter that is outside of the allowed range of the parameter, the wrapper afterwards adds some extra 'penalty' to the result of the cost function and passes the sum of the penalty and the result of the cost function back to the optimizer.
My question is:
Will the optimization work properly (that means: will it find my absolute minimum of my cost function with a higher probability), if I have a binary penalty function like this one (only shown for the upper limit of the bound):
if parameter > upperBound:
penalty = 1.e6
else:
penalty = 0.0
Or is it better to use a penalty function that works smoother (to simulate something like a lipschitz continuous function), like e. g. a shifted square function:
if parameter > upperBound:
penalty = VERY_HIGH_NUMBER * (parameter - upperBound)**2
else:
penalty = 0.0
If it is better to use a smoother penalty function, are there any 'best practizes' for these kind of functions (like using a sigmoid function or a square function etc.)?