<p dir="auto">I am using SciPy (version 1.2.0) for some reasons with a simulation software.<br>
In my case, I need to model the structure in the simulation software based on the results of calculation on variables. The results from the simulation software is the objective function.<br>
However, mostly the design variables can not form the structure. If these infeasible variables pass into simulation software, it will generate a mistake which causes the optimization stop. How can I ask SLSQP to reject infeasible varibales strictly untill the feasible one generate and then pass the feasible one into simulation software to provide the objective value for optimization?</p>
<p dir="auto">Given a constrained optimisation problem, the <code class="notranslate">L-BFGS-B</code> routine (and perhaps others) step outside the prescribed bounds to estimate the gradient despite <code class="notranslate">keep_feasible = True</code>. Is this the correct usage of this parameter in <code class="notranslate">Bounds</code>?</p>
<p dir="auto">Reprex below of a function where <code class="notranslate">ub + eps</code> results in an exception. I would have thought that when estimating the gradient at the upper bound, this should be done <em>below</em> the bound rather than always <em>adding</em> <code class="notranslate">eps</code>?</p>
<p dir="auto">The workaround would be to manually specify <code class="notranslate">eps</code> as per this example and then redefine the bounds as <code class="notranslate">Bounds(lb, ub - eps)</code> however I wouldn't have thought this is ideal?</p>
<h3 dir="auto">Reproducing code example:</h3>
<div class="highlight highlight-source-python notranslate position-relative overflow-auto" dir="auto" data-snippet-clipboard-copy-content="import numpy as np
from math import log
from scipy.optimize import minimize, Bounds

eps = 1e-8

def f(x):
    print(x)
    return log(1 + eps - x)

f(0)
f(1)

x0 = np.array([0])
x_bounds = Bounds(np.array([0.]), np.array([1.]), keep_feasible = True)
res = minimize(fun = f, x0 = x0, method = 'L-BFGS-B', bounds = x_bounds, options = {'eps': eps})"><pre class="notranslate"><span class="pl-k">import</span> <span class="pl-s1">numpy</span> <span class="pl-k">as</span> <span class="pl-s1">np</span>
<span class="pl-k">from</span> <span class="pl-s1">math</span> <span class="pl-k">import</span> <span class="pl-s1">log</span>
<span class="pl-k">from</span> <span class="pl-s1">scipy</span>.<span class="pl-s1">optimize</span> <span class="pl-k">import</span> <span class="pl-s1">minimize</span>, <span class="pl-v">Bounds</span>

<span class="pl-s1">eps</span> <span class="pl-c1">=</span> <span class="pl-c1">1e-8</span>

<span class="pl-k">def</span> <span class="pl-en">f</span>(<span class="pl-s1">x</span>):
    <span class="pl-en">print</span>(<span class="pl-s1">x</span>)
    <span class="pl-k">return</span> <span class="pl-en">log</span>(<span class="pl-c1">1</span> <span class="pl-c1">+</span> <span class="pl-s1">eps</span> <span class="pl-c1">-</span> <span class="pl-s1">x</span>)

<span class="pl-en">f</span>(<span class="pl-c1">0</span>)
<span class="pl-en">f</span>(<span class="pl-c1">1</span>)

<span class="pl-s1">x0</span> <span class="pl-c1">=</span> <span class="pl-s1">np</span>.<span class="pl-en">array</span>([<span class="pl-c1">0</span>])
<span class="pl-s1">x_bounds</span> <span class="pl-c1">=</span> <span class="pl-v">Bounds</span>(<span class="pl-s1">np</span>.<span class="pl-en">array</span>([<span class="pl-c1">0.</span>]), <span class="pl-s1">np</span>.<span class="pl-en">array</span>([<span class="pl-c1">1.</span>]), <span class="pl-s1">keep_feasible</span> <span class="pl-c1">=</span> <span class="pl-c1">True</span>)
<span class="pl-s1">res</span> <span class="pl-c1">=</span> <span class="pl-en">minimize</span>(<span class="pl-s1">fun</span> <span class="pl-c1">=</span> <span class="pl-s1">f</span>, <span class="pl-s1">x0</span> <span class="pl-c1">=</span> <span class="pl-s1">x0</span>, <span class="pl-s1">method</span> <span class="pl-c1">=</span> <span class="pl-s">'L-BFGS-B'</span>, <span class="pl-s1">bounds</span> <span class="pl-c1">=</span> <span class="pl-s1">x_bounds</span>, <span class="pl-s1">options</span> <span class="pl-c1">=</span> {<span class="pl-s">'eps'</span>: <span class="pl-s1">eps</span>})</pre></div>
<h3 dir="auto">Error message:</h3>
<div class="snippet-clipboard-content notranslate position-relative overflow-auto" data-snippet-clipboard-copy-content="0
1
[0.]
[1.e-08] # lb + eps
[1.]
[1.00000001] # ub + eps is infeasible
Traceback ... in f
    return log(1 + eps - x)
ValueError: math domain error"><pre class="notranslate"><code class="notranslate">0
1
[0.]
[1.e-08] # lb + eps
[1.]
[1.00000001] # ub + eps is infeasible
Traceback ... in f
    return log(1 + eps - x)
ValueError: math domain error
</code></pre></div>
<h3 dir="auto">Scipy/Numpy/Python version information:</h3>
<div class="snippet-clipboard-content notranslate position-relative overflow-auto" data-snippet-clipboard-copy-content="1.1.0 1.14.5 sys.version_info(major=3, minor=6, micro=6, releaselevel='final', serial=0)"><pre class="notranslate"><code class="notranslate">1.1.0 1.14.5 sys.version_info(major=3, minor=6, micro=6, releaselevel='final', serial=0)
</code></pre></div>