prompt: You will be provided with a partial code base and an issue statement explaining a problem to resolve.
  <issue>
  What's the correct value for errordef in iminuit?
  see https://github.com/gammapy/gammapy/blob/master/gammapy/utils/fitting/iminuit.py#L88
  
  Reminder:
  out fit statistic is -2 log (likelihood)
  https://github.com/gammapy/gammapy/blob/master/gammapy/stats/fit_statistics.py#L58
  
  </issue>
  <code>
  [start of gammapy/utils/fitting/iminuit.py]
  1 # Licensed under a 3-clause BSD style license - see LICENSE.rst
  2 """iminuit fitting functions.
  3 """
  4 from __future__ import absolute_import, division, print_function, unicode_literals
  5 import numpy as np
  6 
  7 __all__ = [
  8     'fit_iminuit',
  9 ]
  10 
  11 
  12 def fit_iminuit(parameters, function, opts_minuit=None):
  13     """iminuit optimization
  14 
  15     Parameters
  16     ----------
  17     parameters : `~gammapy.utils.modeling.ParameterList`
  18         Parameters with starting values
  19     function : callable
  20         Likelihood function
  21     opts_minuit : dict (optional)
  22         Options passed to `iminuit.Minuit` constructor
  23 
  24     Returns
  25     -------
  26     parameters : `~gammapy.utils.modeling.ParameterList`
  27         Parameters with best-fit values
  28     minuit : `~iminuit.Minuit`
  29         Minuit object
  30     """
  31     from iminuit import Minuit
  32 
  33     minuit_func = MinuitFunction(function, parameters)
  34 
  35     if opts_minuit is None:
  36         opts_minuit = {}
  37     opts_minuit.update(make_minuit_par_kwargs(parameters))
  38 
  39     minuit = Minuit(minuit_func.fcn,
  40                     forced_parameters=parameters.names,
  41                     **opts_minuit)
  42 
  43     minuit.migrad()
  44     parameters.covariance = _get_covar(minuit)
  45 
  46     return parameters, minuit
  47 
  48 
  49 class MinuitFunction(object):
  50     """Wrapper for iminuit
  51 
  52     Parameters
  53     ----------
  54     parameters : `~gammapy.utils.modeling.ParameterList`
  55         Parameters with starting values
  56     function : callable
  57         Likelihood function
  58     """
  59 
  60     def __init__(self, function, parameters):
  61         self.function = function
  62         self.parameters = parameters
  63 
  64     def fcn(self, *values):
  65         for value, parameter in zip(values, self.parameters.parameters):
  66             parameter.value = value
  67         return self.function(self.parameters)
  68 
  69 
  70 def make_minuit_par_kwargs(parameters):
  71     """Create *Parameter Keyword Arguments* for the `Minuit` constructor.
  72 
  73     See: http://iminuit.readthedocs.io/en/latest/api.html#iminuit.Minuit
  74     """
  75     kwargs = {}
  76     for par in parameters.parameters:
  77         kwargs[par.name] = par.value
  78         if par.frozen:
  79             kwargs['fix_{}'.format(par.name)] = True
  80         min_ = None if np.isnan(par.min) else par.min
  81         max_ = None if np.isnan(par.max) else par.max
  82         kwargs['limit_{}'.format(par.name)] = (min_, max_)
  83 
  84         if parameters.covariance is None:
  85             kwargs['error_{}'.format(par.name)] = 1
  86         else:
  87             kwargs['error_{}'.format(par.name)] = parameters.error(par.name)
  88 
  89         # TODO: Check if we need 0.5 or 1
  90         kwargs['errordef'] = 1
  91 
  92     return kwargs
  93 
  94 
  95 def _get_covar(minuit):
  96     """Get full covar matrix as Numpy array.
  97 
  98     This was added as `minuit.np_covariance` in `iminuit` in v1.3,
  99     but we still want to support v1.2
  100     """
  101     n = len(minuit.parameters)
  102     m = np.zeros((n, n))
  103     for i1, k1 in enumerate(minuit.parameters):
  104         for i2, k2 in enumerate(minuit.parameters):
  105             if set([k1, k2]).issubset(minuit.list_of_vary_param()):
  106                 m[i1, i2] = minuit.covariance[(k1, k2)]
  107     return m
  108
  [end of gammapy/utils/fitting/iminuit.py]
  </code>
  
  I need you to solve this issue by generating a single patch file that I can apply directly to this repository using git apply. Please respond with a single patch file in the following format.
  <patch>
  diff --git a/file.py b/file.py
  --- a/file.py
  +++ b/file.py
  @@ -1,27 +1,35 @@
   def euclidean(a, b):
  -    while b:
  -        a, b = b, a % b
  -    return a
  +    if b == 0:
  +        return a
  +    return euclidean(b, a % b)
   
   
   def bresenham(x0, y0, x1, y1):
       points = []
       dx = abs(x1 - x0)
       dy = abs(y1 - y0)
  -    sx = 1 if x0 < x1 else -1
  -    sy = 1 if y0 < y1 else -1
  -    err = dx - dy
  +    x, y = x0, y0
  +    sx = -1 if x0 > x1 else 1
  +    sy = -1 if y0 > y1 else 1
   
  -    while True:
  -        points.append((x0, y0))
  -        if x0 == x1 and y0 == y1:
  -            break
  -        e2 = 2 * err
  -        if e2 > -dy:
  -            err -= dy
  -            x0 += sx
  -        if e2 < dx:
  -            err += dx
  -            y0 += sy
  +    if dx > dy:
  +        err = dx / 2.0
  +        while x != x1:
  +            points.append((x, y))
  +            err -= dy
  +            if err < 0:
  +                y += sy
  +                err += dx
  +            x += sx
  +    else:
  +        err = dy / 2.0
  +        while y != y1:
  +            points.append((x, y))
  +            err -= dx
  +            if err < 0:
  +                x += sx
  +                err += dy
  +            y += sy
  +
  +    points.append((x, y))
       return points
  
  </patch>
golden_diff: diff --git a/gammapy/utils/fitting/iminuit.py b/gammapy/utils/fitting/iminuit.py
  --- a/gammapy/utils/fitting/iminuit.py
  +++ b/gammapy/utils/fitting/iminuit.py
  @@ -36,6 +36,10 @@
           opts_minuit = {}
       opts_minuit.update(make_minuit_par_kwargs(parameters))
   
  +    # In Gammapy, we have the factor 2 in the likelihood function
  +    # This means `errordef=1` in the Minuit interface is correct
  +    opts_minuit.setdefault('errordef', 1)
  +
       minuit = Minuit(minuit_func.fcn,
                       forced_parameters=parameters.names,
                       **opts_minuit)
  @@ -75,8 +79,7 @@
       kwargs = {}
       for par in parameters.parameters:
           kwargs[par.name] = par.value
  -        if par.frozen:
  -            kwargs['fix_{}'.format(par.name)] = True
  +
           min_ = None if np.isnan(par.min) else par.min
           max_ = None if np.isnan(par.max) else par.max
           kwargs['limit_{}'.format(par.name)] = (min_, max_)
  @@ -86,8 +89,8 @@
           else:
               kwargs['error_{}'.format(par.name)] = parameters.error(par.name)
   
  -        # TODO: Check if we need 0.5 or 1
  -        kwargs['errordef'] = 1
  +        if par.frozen:
  +            kwargs['fix_{}'.format(par.name)] = True
   
       return kwargs
  
verification_info: {"golden_diff": "diff --git a/gammapy/utils/fitting/iminuit.py b/gammapy/utils/fitting/iminuit.py\n--- a/gammapy/utils/fitting/iminuit.py\n+++ b/gammapy/utils/fitting/iminuit.py\n@@ -36,6 +36,10 @@\n         opts_minuit = {}\n     opts_minuit.update(make_minuit_par_kwargs(parameters))\n \n+    # In Gammapy, we have the factor 2 in the likelihood function\n+    # This means `errordef=1` in the Minuit interface is correct\n+    opts_minuit.setdefault('errordef', 1)\n+\n     minuit = Minuit(minuit_func.fcn,\n                     forced_parameters=parameters.names,\n                     **opts_minuit)\n@@ -75,8 +79,7 @@\n     kwargs = {}\n     for par in parameters.parameters:\n         kwargs[par.name] = par.value\n-        if par.frozen:\n-            kwargs['fix_{}'.format(par.name)] = True\n+\n         min_ = None if np.isnan(par.min) else par.min\n         max_ = None if np.isnan(par.max) else par.max\n         kwargs['limit_{}'.format(par.name)] = (min_, max_)\n@@ -86,8 +89,8 @@\n         else:\n             kwargs['error_{}'.format(par.name)] = parameters.error(par.name)\n \n-        # TODO: Check if we need 0.5 or 1\n-        kwargs['errordef'] = 1\n+        if par.frozen:\n+            kwargs['fix_{}'.format(par.name)] = True\n \n     return kwargs\n", "issue": "What's the correct value for errordef in iminuit?\nsee https://github.com/gammapy/gammapy/blob/master/gammapy/utils/fitting/iminuit.py#L88\r\n\r\nReminder:\r\nout fit statistic is -2 log (likelihood)\r\nhttps://github.com/gammapy/gammapy/blob/master/gammapy/stats/fit_statistics.py#L58\n", "before_files": [{"content": "# Licensed under a 3-clause BSD style license - see LICENSE.rst\n\"\"\"iminuit fitting functions.\n\"\"\"\nfrom __future__ import absolute_import, division, print_function, unicode_literals\nimport numpy as np\n\n__all__ = [\n    'fit_iminuit',\n]\n\n\ndef fit_iminuit(parameters, function, opts_minuit=None):\n    \"\"\"iminuit optimization\n\n    Parameters\n    ----------\n    parameters : `~gammapy.utils.modeling.ParameterList`\n        Parameters with starting values\n    function : callable\n        Likelihood function\n    opts_minuit : dict (optional)\n        Options passed to `iminuit.Minuit` constructor\n\n    Returns\n    -------\n    parameters : `~gammapy.utils.modeling.ParameterList`\n        Parameters with best-fit values\n    minuit : `~iminuit.Minuit`\n        Minuit object\n    \"\"\"\n    from iminuit import Minuit\n\n    minuit_func = MinuitFunction(function, parameters)\n\n    if opts_minuit is None:\n        opts_minuit = {}\n    opts_minuit.update(make_minuit_par_kwargs(parameters))\n\n    minuit = Minuit(minuit_func.fcn,\n                    forced_parameters=parameters.names,\n                    **opts_minuit)\n\n    minuit.migrad()\n    parameters.covariance = _get_covar(minuit)\n\n    return parameters, minuit\n\n\nclass MinuitFunction(object):\n    \"\"\"Wrapper for iminuit\n\n    Parameters\n    ----------\n    parameters : `~gammapy.utils.modeling.ParameterList`\n        Parameters with starting values\n    function : callable\n        Likelihood function\n    \"\"\"\n\n    def __init__(self, function, parameters):\n        self.function = function\n        self.parameters = parameters\n\n    def fcn(self, *values):\n        for value, parameter in zip(values, self.parameters.parameters):\n            parameter.value = value\n        return self.function(self.parameters)\n\n\ndef make_minuit_par_kwargs(parameters):\n    \"\"\"Create *Parameter Keyword Arguments* for the `Minuit` constructor.\n\n    See: http://iminuit.readthedocs.io/en/latest/api.html#iminuit.Minuit\n    \"\"\"\n    kwargs = {}\n    for par in parameters.parameters:\n        kwargs[par.name] = par.value\n        if par.frozen:\n            kwargs['fix_{}'.format(par.name)] = True\n        min_ = None if np.isnan(par.min) else par.min\n        max_ = None if np.isnan(par.max) else par.max\n        kwargs['limit_{}'.format(par.name)] = (min_, max_)\n\n        if parameters.covariance is None:\n            kwargs['error_{}'.format(par.name)] = 1\n        else:\n            kwargs['error_{}'.format(par.name)] = parameters.error(par.name)\n\n        # TODO: Check if we need 0.5 or 1\n        kwargs['errordef'] = 1\n\n    return kwargs\n\n\ndef _get_covar(minuit):\n    \"\"\"Get full covar matrix as Numpy array.\n\n    This was added as `minuit.np_covariance` in `iminuit` in v1.3,\n    but we still want to support v1.2\n    \"\"\"\n    n = len(minuit.parameters)\n    m = np.zeros((n, n))\n    for i1, k1 in enumerate(minuit.parameters):\n        for i2, k2 in enumerate(minuit.parameters):\n            if set([k1, k2]).issubset(minuit.list_of_vary_param()):\n                m[i1, i2] = minuit.covariance[(k1, k2)]\n    return m\n", "path": "gammapy/utils/fitting/iminuit.py"}]}