-
Notifications
You must be signed in to change notification settings - Fork 289
Fix issue when AMPGO method is aborted due to reaching max_nfev #1020
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
base: master
Are you sure you want to change the base?
Conversation
|
thansk @dangarciahe for pointing out the issue and providing a solution! And, yes, we should certainly fix this. I am just not sure whether that should be done in the actual _ampgo.py implementation or whether it can be done somehow in the ampgo finction minimizer.py. The latter would be preferable - I'll need to look. |
|
@dangarciahe @reneeotten Thanks! I would probably have a slight preference for doing this in minimizer.py, but wouldn't be adamant about that. |
|
Hi @newville @reneeotten. I would be happy to make those changes, but have no idea on how to, given that, from what I underestand, if _ampgo.py aborts, minizer.py has no idea of the current best value, so I don't see how could I catch those values. Hence why I added the try-except block to _ampgo. Some guidance in this would be appreciated. |
| pass | ||
|
|
||
| if not result.aborted: | ||
| if 'ret' in locals(): |
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.
please have AbortFitException set ret = None
and then make the test here be if ret is not None.
| for i, par in enumerate(result.var_names): | ||
| result.params[par].value = float(result.ampgo_x0[i]) | ||
|
|
||
| if not result.aborted: |
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.
result.nfev -= 2 if result.aborted else 1
might be worth considering here
| res = minimize(tunnel, x0, args=tunnel_args, method=local, | ||
| bounds=bounds, tol=local_tol, options=options) | ||
| except Exception as e: | ||
| if e.__class__.__name__ == "AbortFitException": |
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.
except Exception as exc:
if isinstance(exc, AbortFitException):
...
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.
.... or bettter....
except AbortFitException:
do things....
except Exception as exc:
do other things...
|
@dangarciahe Thanks - I think a few small changes and this will be a great addition. Happy to hear others thoughts |
Description
This PR adds a fix to the AMPGO method for the
minize()function. Previously, when AMPGO is aborted due to reachingmax_nfev, it will return the last evaluated values, instead of the best value found so far, an incorrect behavior per AMPGO paper. This was discussed in #1017. The new behavior fixes this, and will return the best value found so far, even if the process is aborted due tomax_nfev.Additionally, a new test is added: It verifies against a known case to exhibit this troubled behavior in the current version, but returns a correct value under the newer version proposed by this PR.
This should improve AMPGO method, specially when minimizing computationally slow functions where an arbitrarily big
max_nfevis not feasible, and a test to prevent future code to accidentally re-introduce this behavior.Type of Changes
Tested on
Python: 3.14.0 | packaged by Anaconda, Inc. | (main, Oct 8 2025, 17:15:28) [GCC 11.2.0]
lmfit: 1.3.4, scipy: 1.16.2, numpy: 2.3.4, asteval: 1.0.6, uncertainties: 3.2.3
Verification
Have you
Minimal reproducible example
Here's a minimal example that allows to see the improvements:
Under the older version, the fit will return
x: 0.30768323despite the existence of several evaluations of x in the order ofx=-4.99985e-08, as evidenced by the prints; new version will correctly returnx: -4.9999e-08