Search code examples
pythonscipyscipy-optimize-minimize

Scipy minimize iterating past bounds


I am trying to minimize a function of 3 input variables using scipy. The function reads like so-

def myfunc(x):
    x[0] = a
    x[1] = b
    x[2] = c
    n = f(a,b,c)
    return n

bound1 = (80,100)
bound2 = (10,20)
bound3 = (312,740)
guess = [a0,b0,c0]
bds = (bound1,bound2,bound3)
result = minimize(myfunc, guess,method='L-BFGS-B',bounds=bds)

The function I am trying to currently run reaches a minimum at a=100,b=10,c=740, which is at the end of the bounds.

The minimize function keeps trying to iterate past the end of bound 3 (gets to c0 value of 740.0000000149012 on its last iteration.

Is there any way to stop this from happening? i.e. stop the iteration at the actual end of my bound?


Solution

  • This happens due to numerical-differentiation, which itself is not only needed to infer the step-direction and size, but also to reason about termination.

    In general you can't do much without being very careful in regards to whatever solver (and there are many backend-solvers) being used. The basic idea is to replace the automatic numerical-differentiation with one provided by you: this one then respects those bounds and must be careful about the solvers-internals, e.g. "how to reason about termination at this end".

    Fix A:

    Your problem should vanish automatically when using: Pull-request #10673, which touches your configuration: L-BFGS-B.

    It seems, this PR is not part of the current release SciPy 1.4.1 (as this was 2 months before the PR).

    See also #6026, where a milestone of 1.5.0 is mentioned in regards to some changes including respecting bounds in num-diff.

    For above PR, you will need to install scipy from the sources, which is:

    • quite doable on linux (and maybe os x)
    • not something you should try on windows!
      • trust me...

    See the documentation if needed.

    Fix B:

    Apart from that, as you are doing unconstrained-optimization (with variable-bounds) where more solver-backends are available (compared to constrained-optimization), you might try another solver, trust-constr, which has explicit support for this, see #9098.

    Be careful to recognize, that you need to signal this explicitly when setting up the bounds!