-
Notifications
You must be signed in to change notification settings - Fork 85
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
fix: Correct handling of strategy 0 for Minuit optimizer #2277
fix: Correct handling of strategy 0 for Minuit optimizer #2277
Conversation
The relevant line is supposed to set the strategy of minuit to one of the supported values 0, 1, 2. Since the strategy `0` evaluates to `False`, the strategy `0` couldn't be set when creating the optimizer. The default value in the case of no specified strategy is `None`, meaning that the statement `is not None` solves the issue.
Codecov ReportPatch and project coverage have no change.
Additional details and impacted files@@ Coverage Diff @@
## main #2277 +/- ##
=======================================
Coverage 98.30% 98.30%
=======================================
Files 69 69
Lines 4534 4534
Branches 801 801
=======================================
Hits 4457 4457
Misses 45 45
Partials 32 32
Flags with carried forward coverage won't be shown. Click here to find out more.
☔ View full report in Codecov by Sentry. |
Thanks for the PR @wernerd-cern. This should have been caught in the If you have time to add a test that will speed things up in getting this approved. If not, then the core devs can add one later this week and get this in. |
In the case that no strategy is specified it should default to `not do_grad`. This is tested in the test `test_minuit_strategy_do_grad`. In the test `test_minuit_strategy_global` a strategy is specified, when the minimizer is set. In the case of strategy `0` and no strategy passed to the `fit` function, however, the strategy defaults again to `not do_grad`. This doesn't seem to be the desired behaviour as a strategy was passed in the beginning. Therefore, I changed this assert to fail, if the final strategy is different from the one assigned in the beginning. With this change one test case fails before applying this fix. The fix in this pull request fixes the test failure. (The failing case is strategy `0` with the `numpy` backend as `default_do_grad` is `False` for this backend.)
In the case that no strategy is specified, it should default to In the test With this change one test case fails before applying the fix in this PR. |
Rereading the guide on contributing I found the part about adding ones name to the list of contributors. Since this is my first PR to this repository, I suppose it is the correct thing to include my name as part of this PR.
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.
Thanks for your PR @wernerd-cern — your contributions are appreciated! This all LGTM. 👍
We'll go ahead and merge this in, and I'll work on getting a patch release out in hopefully the next day. Though given that this bug was found I think I should probably address Issue #1785 as well so that can go into the same patch release.
For future us, here's a simple example of what was going wrong: # pr_2777_example.py
import itertools
strategies = [None, 0, 1]
grad_option = [False, True]
for strategy, do_grad in itertools.product(strategies, grad_option):
print(f"\n# strategy: {strategy}")
if strategy is not None:
print(f"# do_grad: {do_grad}")
else:
print(f"# int(not do_grad): {int(not do_grad)}")
print(f"v0.7.2: {strategy if strategy else not do_grad}")
print(f"PR #2277: {strategy if strategy is not None else not do_grad}")
if strategy is None:
print(
f"PR #2277 cast to int: {strategy if strategy is not None else int(not do_grad)}"
) $ python pr_2777_example.py
# strategy: None
# int(not do_grad): 1
v0.7.2: True
PR #2277: True
PR #2277 cast to int: 1
# strategy: None
# int(not do_grad): 0
v0.7.2: False
PR #2277: False
PR #2277 cast to int: 0
# strategy: 0
# do_grad: False
v0.7.2: True
PR #2277: 0
# strategy: 0
# do_grad: True
v0.7.2: False
PR #2277: 0
# strategy: 1
# do_grad: False
v0.7.2: 1
PR #2277: 1
# strategy: 1
# do_grad: True
v0.7.2: 1
PR #2277: 1 |
* Guard Minuit optimizer strategy from None by first attempting to get a not-None result from the options kwargs and then falling back to assigning the strategy through the equivalent of `int(not do_grad)`. In the process this simplifies the logic required and supersedes PR #2277. - Cast the truthiness of `do_grad` as an integer for human readability in debugging. * Update the comments on `do_grad` strategy with definitions from iMinuit v2.24.0 docs. * Add tests to test_minuit_strategy_global for strategy=None and strategy=2 (2 is a valid iminuit.Minuit.strategy strategy but not used often). * Add brief explanation to docs of what using strategy=None means in terms of evaluation to 0 or 1 from `int(pyhf.tensorlib.default_do_grad)`.
@wernerd-cern |
Description
The relevant line is supposed to set the strategy of minuit to one of the supported values
0
,1
, or2
. Since the strategy0
evaluates toFalse
, this strategy couldn't be set when creating the optimizer ifdo_grad
wasFalse
pyhf/src/pyhf/optimize/opt_minuit.py
Lines 104 to 106 in f8f3c96
. The default value in the case of no specified strategy is
None
pyhf/src/pyhf/optimize/opt_minuit.py
Line 39 in f8f3c96
meaning that the statement
is not None
solves the issue with.
Amends PR #1183.
Checklist Before Requesting Reviewer
Before Merging
For the PR Assignees: