Skip to content

Commit

Permalink
make iterate feature in migrad configurable, better explain effect of…
Browse files Browse the repository at this point in the history
… precision keyword (#488)
  • Loading branch information
HDembinski authored Sep 24, 2020
1 parent 21d9809 commit 11742d5
Show file tree
Hide file tree
Showing 2 changed files with 18 additions and 7 deletions.
17 changes: 14 additions & 3 deletions src/iminuit/_libiminuit.pyx
Original file line number Diff line number Diff line change
Expand Up @@ -795,7 +795,7 @@ cdef class Minuit:
return cls(fcn, **kwds)


def migrad(self, ncall=None, resume=True, precision=None, **deprecated_kwargs):
def migrad(self, ncall=None, resume=True, precision=None, iterate=5, **deprecated_kwargs):
"""Run MIGRAD.
MIGRAD is a robust minimisation algorithm which earned its reputation
Expand All @@ -814,7 +814,15 @@ cdef class Minuit:
the previous minimiser attempt(True) or should start from the
beginning(False). Default True.
* **precision**: override miniut own's internal precision.
* **precision**: override Minuit precision estimate for the cost function.
Default: None (= use epsilon of a C++ double). If the cost function has a
lower precision (e.g. of a C++ float), setting this to a lower value will
accelerate convergence and reduce the rate of unsuccessful convergence.
* **iterate**: automatically call Migrad up to N times if convergence
was not reached. Default: 5. This simple heuristic makes Migrad converge
more often even if the numerical precision of the cost function is low.
Setting this to 1 disables the feature.
**Return:**
Expand All @@ -823,6 +831,9 @@ cdef class Minuit:
if ncall is None:
ncall = 0 # tells C++ Minuit to use its internal heuristic

if iterate < 1:
raise ValueError("iterate must be at least 1")

if "nsplit" in deprecated_kwargs:
warn("`nsplit` keyword has been removed and is ignored",
RuntimeWarning,
Expand Down Expand Up @@ -869,7 +880,7 @@ cdef class Minuit:

# Automatically call Migrad up to five times if minimum is not valid.
# This simple heuristic makes Migrad converge more often.
for _ in range(5):
for _ in range(iterate):
if self.cfmin:
del self.cfmin
# self.cfmin must be always set to NULL after it was deleted,
Expand Down
8 changes: 4 additions & 4 deletions src/iminuit/tests/test_iminuit.py
Original file line number Diff line number Diff line change
Expand Up @@ -1151,11 +1151,11 @@ def test_parameter_at_limit(sign):
assert m.fmin.has_parameters_at_limit is False


def test_inaccurate_fcn():
@pytest.mark.parametrize("iterate,valid", ((1, False), (5, True)))
def test_inaccurate_fcn(iterate, valid):
def f(x):
return abs(x) ** 10 + 1e7

m = Minuit(f, x=2, errordef=1)
m.migrad()
assert m.valid
assert m.values["x"] == approx(0, abs=0.5)
m.migrad(iterate=iterate)
assert m.valid == valid

0 comments on commit 11742d5

Please sign in to comment.