-
-
Notifications
You must be signed in to change notification settings - Fork 5.4k
MAINT: optimize.bracket: don't fail silently #17704
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Some self-review to aid the reviewer.
scipy/optimize/_optimize.py
Outdated
args : tuple, optional | ||
Additional arguments (if present), passed to `func`. | ||
grow_limit : float, optional | ||
Maximum grow limit. Defaults to 110.0 | ||
maxiter : int, optional | ||
Maximum number of iterations to perform. Defaults to 1000. | ||
|
||
Raises |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Think this should be between returns and notes as per https://numpydoc.readthedocs.io/en/latest/format.html#sections
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ugh I even looked at the standards to confirm; then I went and put it in the wrong place. I'll fix it.
scipy/optimize/_optimize.py
Outdated
if np.any(np.isnan([xs, fs])): | ||
x, fun = np.nan, np.nan | ||
else: | ||
imin = np.argmin(xs) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Possible mistake?
imin = np.argmin(xs) | |
imin = np.argmin(fs) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Unfortunately, I'm having trouble coming up with a realistic test case that exercises this with minimize_scalar
. Sure, we could simulate calling _recover_from_backet_error
with an artificial solve
argument that raises a BracketError
with out-of-order xs
and fs
and show that this picks the right one, but I don't think it's worth it.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM, thanks @mdhaber
Reference issue
Closes gh-14858
What does this implement/fix?
gh-14858 reported that
scipy.optimize.bracket
may silently return an invalid bracket, causing scalar minimization functions to fail. This PR resolves the issue by checking for failure before returning. It also begins to improve the function documentation and tests.Update:
bracket
is used inbrent
,golden
, andminimize_scalar
with methods'brent'
and'golden'
. It's probably appropriate forbrent
andgolden
to raise errors whenbracket
fails, butminimize_scalar
should terminate gracefully withsuccess=False
. This requires plumbing the status information frombracket
through the optimizers, which could this PR quite a bit more complex than intended - see a6aa40d. I ended up refactoring it that makes it much simpler, albeit a bit unorthodox.Additional information
In main,
bracket
is not tested outside ofminimize_scalar
, and the documentation is not explicit about the function's behavior. This is intended to be an improvement, but more work is certainly needed in followup PRs. For instance, this function still needs:minimize_scalar
)For this PR, let's stick within the existing scope of fixing gh-14858 and these doc improvements so as not to delay progress.