We are currently solving the following issue within our repository. Here is the issue text:
--- BEGIN ISSUE ---
 Participate in iminuit v2.0 beta?
Dear pyhf team,

I am about to finish a major rewrite of iminuit, version 2.0, that replaces Cython as the tool to wrap C++ Minuit2 with pybind11, which is going to solve several issues that the legacy code had. All the good things that this will bring are listed on top of this PR:
scikit-hep/iminuit#502

Switching to the new version of iminuit should be completely transparent to you, since the new version passes the comprehensive suite of unit tests of iminuit-v1.x. However, I would like to use this opportunity to finally remove interface that has been successively marked as deprecated in versions 1.3 to 1.5.

Therefore my two question to you:

 * Did you take note of the deprecation warnings in iminuit and did you keep up with the interface changes so far?
 * Are you interested in trying out a Beta release of v2.0 to work out any possible bugs in the new version before the release?

Best regards,
Hans, iminuit maintainer

--- END ISSUE ---

Below are some code segments, each from a relevant file. One or more of these files may contain bugs.
--- BEGIN FILES ---
Path: `src/pyhf/optimize/opt_minuit.py`
Content:
```
1 """Minuit Optimizer Class."""
2 from .. import default_backend, exceptions
3 from .mixins import OptimizerMixin
4 import scipy
5 import iminuit
6 
7 
8 class minuit_optimizer(OptimizerMixin):
9     """
10     Optimizer that uses iminuit.Minuit.migrad.
11     """
12 
13     __slots__ = ['name', 'errordef', 'steps', 'strategy', 'tolerance']
14 
15     def __init__(self, *args, **kwargs):
16         """
17         Create MINUIT Optimizer.
18 
19         .. note::
20 
21             ``errordef`` should be 1.0 for a least-squares cost function and 0.5
22             for negative log-likelihood function. See page 37 of
23             http://hep.fi.infn.it/minuit.pdf. This parameter is sometimes
24             called ``UP`` in the ``MINUIT`` docs.
25 
26 
27         Args:
28             errordef (:obj:`float`): See minuit docs. Default is 1.0.
29             steps (:obj:`int`): Number of steps for the bounds. Default is 1000.
30             strategy (:obj:`int`): See :attr:`iminuit.Minuit.strategy`. Default is None.
31             tolerance (:obj:`float`): tolerance for termination. See specific optimizer for detailed meaning. Default is 0.1.
32         """
33         self.name = 'minuit'
34         self.errordef = kwargs.pop('errordef', 1)
35         self.steps = kwargs.pop('steps', 1000)
36         self.strategy = kwargs.pop('strategy', None)
37         self.tolerance = kwargs.pop('tolerance', 0.1)
38         super().__init__(*args, **kwargs)
39 
40     def _get_minimizer(
41         self, objective_and_grad, init_pars, init_bounds, fixed_vals=None, do_grad=False
42     ):
43 
44         step_sizes = [(b[1] - b[0]) / float(self.steps) for b in init_bounds]
45         fixed_vals = fixed_vals or []
46         # Minuit wants True/False for each parameter
47         fixed_bools = [False] * len(init_pars)
48         for index, val in fixed_vals:
49             fixed_bools[index] = True
50             init_pars[index] = val
51             step_sizes[index] = 0.0
52 
53         # Minuit requires jac=callable
54         if do_grad:
55             wrapped_objective = lambda pars: objective_and_grad(pars)[0]  # noqa: E731
56             jac = lambda pars: objective_and_grad(pars)[1]  # noqa: E731
57         else:
58             wrapped_objective = objective_and_grad
59             jac = None
60 
61         kwargs = dict(
62             fcn=wrapped_objective,
63             grad=jac,
64             start=init_pars,
65             error=step_sizes,
66             limit=init_bounds,
67             fix=fixed_bools,
68             print_level=self.verbose,
69             errordef=self.errordef,
70         )
71         return iminuit.Minuit.from_array_func(**kwargs)
72 
73     def _minimize(
74         self,
75         minimizer,
76         func,
77         x0,
78         do_grad=False,
79         bounds=None,
80         fixed_vals=None,
81         return_uncertainties=False,
82         options={},
83     ):
84 
85         """
86         Same signature as :func:`scipy.optimize.minimize`.
87 
88         Note: an additional `minuit` is injected into the fitresult to get the
89         underlying minimizer.
90 
91         Minimizer Options:
92             maxiter (:obj:`int`): maximum number of iterations. Default is 100000.
93             return_uncertainties (:obj:`bool`): Return uncertainties on the fitted parameters. Default is off.
94             strategy (:obj:`int`): See :attr:`iminuit.Minuit.strategy`. Default is to configure in response to `do_grad`.
95 
96         Returns:
97             fitresult (scipy.optimize.OptimizeResult): the fit result
98         """
99         maxiter = options.pop('maxiter', self.maxiter)
100         return_uncertainties = options.pop('return_uncertainties', False)
101         # 0: Fast, user-provided gradient
102         # 1: Default, no user-provided gradient
103         strategy = options.pop(
104             'strategy', self.strategy if self.strategy else not do_grad
105         )
106         tolerance = options.pop('tolerance', self.tolerance)
107         if options:
108             raise exceptions.Unsupported(
109                 f"Unsupported options were passed in: {list(options.keys())}."
110             )
111 
112         minimizer.strategy = strategy
113         minimizer.tol = tolerance
114         minimizer.migrad(ncall=maxiter)
115         # Following lines below come from:
116         # https://github.com/scikit-hep/iminuit/blob/64acac11cfa2fb91ccbd02d1b3c51f8a9e2cc484/src/iminuit/_minimize.py#L102-L121
117         message = "Optimization terminated successfully."
118         if not minimizer.valid:
119             message = "Optimization failed."
120             fmin = minimizer.fmin
121             if fmin.has_reached_call_limit:
122                 message += " Call limit was reached."
123             if fmin.is_above_max_edm:
124                 message += " Estimated distance to minimum too large."
125 
126         n = len(x0)
127         hess_inv = default_backend.ones((n, n))
128         if minimizer.valid:
129             # Extra call to hesse() after migrad() is always needed for good error estimates. If you pass a user-provided gradient to MINUIT, convergence is faster.
130             minimizer.hesse()
131             hess_inv = minimizer.np_covariance()
132 
133         unc = None
134         if return_uncertainties:
135             unc = minimizer.np_errors()
136 
137         return scipy.optimize.OptimizeResult(
138             x=minimizer.np_values(),
139             unc=unc,
140             success=minimizer.valid,
141             fun=minimizer.fval,
142             hess_inv=hess_inv,
143             message=message,
144             nfev=minimizer.ncalls_total,
145             njev=minimizer.ngrads_total,
146             minuit=minimizer,
147         )
148
```

Path: `setup.py`
Content:
```
1 from setuptools import setup
2 
3 extras_require = {
4     'shellcomplete': ['click_completion'],
5     'tensorflow': [
6         'tensorflow~=2.2.0',  # TensorFlow minor releases are as volatile as major
7         'tensorflow-probability~=0.10.0',
8     ],
9     'torch': ['torch~=1.2'],
10     'jax': ['jax~=0.2.4', 'jaxlib~=0.1.56'],
11     'xmlio': ['uproot3~=3.14'],  # Future proof against uproot4 API changes
12     'minuit': ['iminuit~=1.5.3'],
13 }
14 extras_require['backends'] = sorted(
15     set(
16         extras_require['tensorflow']
17         + extras_require['torch']
18         + extras_require['jax']
19         + extras_require['minuit']
20     )
21 )
22 extras_require['contrib'] = sorted({'matplotlib', 'requests'})
23 extras_require['lint'] = sorted({'flake8', 'black'})
24 
25 extras_require['test'] = sorted(
26     set(
27         extras_require['backends']
28         + extras_require['xmlio']
29         + extras_require['contrib']
30         + extras_require['shellcomplete']
31         + [
32             'pytest~=6.0',
33             'pytest-cov>=2.5.1',
34             'pytest-mock',
35             'pytest-benchmark[histogram]',
36             'pytest-console-scripts',
37             'pytest-mpl',
38             'pydocstyle',
39             'coverage>=4.0',  # coveralls
40             'papermill~=2.0',
41             'nteract-scrapbook~=0.2',
42             'jupyter',
43             'graphviz',
44             'jsonpatch',
45         ]
46     )
47 )
48 extras_require['docs'] = sorted(
49     {
50         'sphinx>=3.1.2',
51         'sphinxcontrib-bibtex~=1.0',
52         'sphinx-click',
53         'sphinx_rtd_theme',
54         'nbsphinx',
55         'ipywidgets',
56         'sphinx-issues',
57         'sphinx-copybutton>0.2.9',
58     }
59 )
60 extras_require['develop'] = sorted(
61     set(
62         extras_require['docs']
63         + extras_require['lint']
64         + extras_require['test']
65         + [
66             'nbdime',
67             'bump2version',
68             'ipython',
69             'pre-commit',
70             'check-manifest',
71             'codemetapy>=0.3.4',
72             'twine',
73         ]
74     )
75 )
76 extras_require['complete'] = sorted(set(sum(extras_require.values(), [])))
77 
78 
79 setup(
80     extras_require=extras_require,
81     use_scm_version=lambda: {'local_scheme': lambda version: ''},
82 )
83
```
--- END FILES ---

Please first localize the bug based on the issue statement, and then generate a patch according to the `git diff` format fenced by three backticks.

Here is an example:

```diff
diff --git a/examples/server_async.py b/examples/server_async.py
--- a/examples/server_async.py
+++ b/examples/server_async.py
@@ -313,4 +313,4 @@
 
 
 if __name__ == "__main__":
-    asyncio.run(run_async_server("."), debug=True)
+    asyncio.run(run_async_server(), debug=True)
diff --git a/examples/server_sync.py b/examples/server_sync.py
--- a/examples/server_sync.py
+++ b/examples/server_sync.py
@@ -313,5 +313,5 @@
 
 
 if __name__ == "__main__":
-    server = run_sync_server(".")
+    server = run_sync_server()
     server.shutdown()

```

diff --git a/setup.py b/setup.py
--- a/setup.py
+++ b/setup.py
@@ -9,7 +9,7 @@
     'torch': ['torch~=1.2'],
     'jax': ['jax~=0.2.4', 'jaxlib~=0.1.56'],
     'xmlio': ['uproot3~=3.14'],  # Future proof against uproot4 API changes
-    'minuit': ['iminuit~=1.5.3'],
+    'minuit': ['iminuit~=2.1'],
 }
 extras_require['backends'] = sorted(
     set(
diff --git a/src/pyhf/optimize/opt_minuit.py b/src/pyhf/optimize/opt_minuit.py
--- a/src/pyhf/optimize/opt_minuit.py
+++ b/src/pyhf/optimize/opt_minuit.py
@@ -58,17 +58,13 @@
             wrapped_objective = objective_and_grad
             jac = None
 
-        kwargs = dict(
-            fcn=wrapped_objective,
-            grad=jac,
-            start=init_pars,
-            error=step_sizes,
-            limit=init_bounds,
-            fix=fixed_bools,
-            print_level=self.verbose,
-            errordef=self.errordef,
-        )
-        return iminuit.Minuit.from_array_func(**kwargs)
+        minuit = iminuit.Minuit(wrapped_objective, init_pars, grad=jac)
+        minuit.errors = step_sizes
+        minuit.limits = init_bounds
+        minuit.fixed = fixed_bools
+        minuit.print_level = self.verbose
+        minuit.errordef = self.errordef
+        return minuit
 
     def _minimize(
         self,
@@ -113,7 +109,7 @@
         minimizer.tol = tolerance
         minimizer.migrad(ncall=maxiter)
         # Following lines below come from:
-        # https://github.com/scikit-hep/iminuit/blob/64acac11cfa2fb91ccbd02d1b3c51f8a9e2cc484/src/iminuit/_minimize.py#L102-L121
+        # https://github.com/scikit-hep/iminuit/blob/23bad7697e39d363f259ca8349684df939b1b2e6/src/iminuit/_minimize.py#L111-L130
         message = "Optimization terminated successfully."
         if not minimizer.valid:
             message = "Optimization failed."
@@ -128,20 +124,20 @@
         if minimizer.valid:
             # Extra call to hesse() after migrad() is always needed for good error estimates. If you pass a user-provided gradient to MINUIT, convergence is faster.
             minimizer.hesse()
-            hess_inv = minimizer.np_covariance()
+            hess_inv = minimizer.covariance
 
         unc = None
         if return_uncertainties:
-            unc = minimizer.np_errors()
+            unc = minimizer.errors
 
         return scipy.optimize.OptimizeResult(
-            x=minimizer.np_values(),
+            x=minimizer.values,
             unc=unc,
             success=minimizer.valid,
             fun=minimizer.fval,
             hess_inv=hess_inv,
             message=message,
-            nfev=minimizer.ncalls_total,
-            njev=minimizer.ngrads_total,
+            nfev=minimizer.nfcn,
+            njev=minimizer.ngrad,
             minuit=minimizer,
         )

{"golden_diff": "diff --git a/setup.py b/setup.py\n--- a/setup.py\n+++ b/setup.py\n@@ -9,7 +9,7 @@\n     'torch': ['torch~=1.2'],\n     'jax': ['jax~=0.2.4', 'jaxlib~=0.1.56'],\n     'xmlio': ['uproot3~=3.14'],  # Future proof against uproot4 API changes\n-    'minuit': ['iminuit~=1.5.3'],\n+    'minuit': ['iminuit~=2.1'],\n }\n extras_require['backends'] = sorted(\n     set(\ndiff --git a/src/pyhf/optimize/opt_minuit.py b/src/pyhf/optimize/opt_minuit.py\n--- a/src/pyhf/optimize/opt_minuit.py\n+++ b/src/pyhf/optimize/opt_minuit.py\n@@ -58,17 +58,13 @@\n             wrapped_objective = objective_and_grad\n             jac = None\n \n-        kwargs = dict(\n-            fcn=wrapped_objective,\n-            grad=jac,\n-            start=init_pars,\n-            error=step_sizes,\n-            limit=init_bounds,\n-            fix=fixed_bools,\n-            print_level=self.verbose,\n-            errordef=self.errordef,\n-        )\n-        return iminuit.Minuit.from_array_func(**kwargs)\n+        minuit = iminuit.Minuit(wrapped_objective, init_pars, grad=jac)\n+        minuit.errors = step_sizes\n+        minuit.limits = init_bounds\n+        minuit.fixed = fixed_bools\n+        minuit.print_level = self.verbose\n+        minuit.errordef = self.errordef\n+        return minuit\n \n     def _minimize(\n         self,\n@@ -113,7 +109,7 @@\n         minimizer.tol = tolerance\n         minimizer.migrad(ncall=maxiter)\n         # Following lines below come from:\n-        # https://github.com/scikit-hep/iminuit/blob/64acac11cfa2fb91ccbd02d1b3c51f8a9e2cc484/src/iminuit/_minimize.py#L102-L121\n+        # https://github.com/scikit-hep/iminuit/blob/23bad7697e39d363f259ca8349684df939b1b2e6/src/iminuit/_minimize.py#L111-L130\n         message = \"Optimization terminated successfully.\"\n         if not minimizer.valid:\n             message = \"Optimization failed.\"\n@@ -128,20 +124,20 @@\n         if minimizer.valid:\n             # Extra call to hesse() after migrad() is always needed for good error estimates. If you pass a user-provided gradient to MINUIT, convergence is faster.\n             minimizer.hesse()\n-            hess_inv = minimizer.np_covariance()\n+            hess_inv = minimizer.covariance\n \n         unc = None\n         if return_uncertainties:\n-            unc = minimizer.np_errors()\n+            unc = minimizer.errors\n \n         return scipy.optimize.OptimizeResult(\n-            x=minimizer.np_values(),\n+            x=minimizer.values,\n             unc=unc,\n             success=minimizer.valid,\n             fun=minimizer.fval,\n             hess_inv=hess_inv,\n             message=message,\n-            nfev=minimizer.ncalls_total,\n-            njev=minimizer.ngrads_total,\n+            nfev=minimizer.nfcn,\n+            njev=minimizer.ngrad,\n             minuit=minimizer,\n         )\n", "issue": " Participate in iminuit v2.0 beta?\nDear pyhf team,\r\n\r\nI am about to finish a major rewrite of iminuit, version 2.0, that replaces Cython as the tool to wrap C++ Minuit2 with pybind11, which is going to solve several issues that the legacy code had. All the good things that this will bring are listed on top of this PR:\r\nscikit-hep/iminuit#502\r\n\r\nSwitching to the new version of iminuit should be completely transparent to you, since the new version passes the comprehensive suite of unit tests of iminuit-v1.x. However, I would like to use this opportunity to finally remove interface that has been successively marked as deprecated in versions 1.3 to 1.5.\r\n\r\nTherefore my two question to you:\r\n\r\n * Did you take note of the deprecation warnings in iminuit and did you keep up with the interface changes so far?\r\n * Are you interested in trying out a Beta release of v2.0 to work out any possible bugs in the new version before the release?\r\n\r\nBest regards,\r\nHans, iminuit maintainer\n", "before_files": [{"content": "\"\"\"Minuit Optimizer Class.\"\"\"\nfrom .. import default_backend, exceptions\nfrom .mixins import OptimizerMixin\nimport scipy\nimport iminuit\n\n\nclass minuit_optimizer(OptimizerMixin):\n    \"\"\"\n    Optimizer that uses iminuit.Minuit.migrad.\n    \"\"\"\n\n    __slots__ = ['name', 'errordef', 'steps', 'strategy', 'tolerance']\n\n    def __init__(self, *args, **kwargs):\n        \"\"\"\n        Create MINUIT Optimizer.\n\n        .. note::\n\n            ``errordef`` should be 1.0 for a least-squares cost function and 0.5\n            for negative log-likelihood function. See page 37 of\n            http://hep.fi.infn.it/minuit.pdf. This parameter is sometimes\n            called ``UP`` in the ``MINUIT`` docs.\n\n\n        Args:\n            errordef (:obj:`float`): See minuit docs. Default is 1.0.\n            steps (:obj:`int`): Number of steps for the bounds. Default is 1000.\n            strategy (:obj:`int`): See :attr:`iminuit.Minuit.strategy`. Default is None.\n            tolerance (:obj:`float`): tolerance for termination. See specific optimizer for detailed meaning. Default is 0.1.\n        \"\"\"\n        self.name = 'minuit'\n        self.errordef = kwargs.pop('errordef', 1)\n        self.steps = kwargs.pop('steps', 1000)\n        self.strategy = kwargs.pop('strategy', None)\n        self.tolerance = kwargs.pop('tolerance', 0.1)\n        super().__init__(*args, **kwargs)\n\n    def _get_minimizer(\n        self, objective_and_grad, init_pars, init_bounds, fixed_vals=None, do_grad=False\n    ):\n\n        step_sizes = [(b[1] - b[0]) / float(self.steps) for b in init_bounds]\n        fixed_vals = fixed_vals or []\n        # Minuit wants True/False for each parameter\n        fixed_bools = [False] * len(init_pars)\n        for index, val in fixed_vals:\n            fixed_bools[index] = True\n            init_pars[index] = val\n            step_sizes[index] = 0.0\n\n        # Minuit requires jac=callable\n        if do_grad:\n            wrapped_objective = lambda pars: objective_and_grad(pars)[0]  # noqa: E731\n            jac = lambda pars: objective_and_grad(pars)[1]  # noqa: E731\n        else:\n            wrapped_objective = objective_and_grad\n            jac = None\n\n        kwargs = dict(\n            fcn=wrapped_objective,\n            grad=jac,\n            start=init_pars,\n            error=step_sizes,\n            limit=init_bounds,\n            fix=fixed_bools,\n            print_level=self.verbose,\n            errordef=self.errordef,\n        )\n        return iminuit.Minuit.from_array_func(**kwargs)\n\n    def _minimize(\n        self,\n        minimizer,\n        func,\n        x0,\n        do_grad=False,\n        bounds=None,\n        fixed_vals=None,\n        return_uncertainties=False,\n        options={},\n    ):\n\n        \"\"\"\n        Same signature as :func:`scipy.optimize.minimize`.\n\n        Note: an additional `minuit` is injected into the fitresult to get the\n        underlying minimizer.\n\n        Minimizer Options:\n            maxiter (:obj:`int`): maximum number of iterations. Default is 100000.\n            return_uncertainties (:obj:`bool`): Return uncertainties on the fitted parameters. Default is off.\n            strategy (:obj:`int`): See :attr:`iminuit.Minuit.strategy`. Default is to configure in response to `do_grad`.\n\n        Returns:\n            fitresult (scipy.optimize.OptimizeResult): the fit result\n        \"\"\"\n        maxiter = options.pop('maxiter', self.maxiter)\n        return_uncertainties = options.pop('return_uncertainties', False)\n        # 0: Fast, user-provided gradient\n        # 1: Default, no user-provided gradient\n        strategy = options.pop(\n            'strategy', self.strategy if self.strategy else not do_grad\n        )\n        tolerance = options.pop('tolerance', self.tolerance)\n        if options:\n            raise exceptions.Unsupported(\n                f\"Unsupported options were passed in: {list(options.keys())}.\"\n            )\n\n        minimizer.strategy = strategy\n        minimizer.tol = tolerance\n        minimizer.migrad(ncall=maxiter)\n        # Following lines below come from:\n        # https://github.com/scikit-hep/iminuit/blob/64acac11cfa2fb91ccbd02d1b3c51f8a9e2cc484/src/iminuit/_minimize.py#L102-L121\n        message = \"Optimization terminated successfully.\"\n        if not minimizer.valid:\n            message = \"Optimization failed.\"\n            fmin = minimizer.fmin\n            if fmin.has_reached_call_limit:\n                message += \" Call limit was reached.\"\n            if fmin.is_above_max_edm:\n                message += \" Estimated distance to minimum too large.\"\n\n        n = len(x0)\n        hess_inv = default_backend.ones((n, n))\n        if minimizer.valid:\n            # Extra call to hesse() after migrad() is always needed for good error estimates. If you pass a user-provided gradient to MINUIT, convergence is faster.\n            minimizer.hesse()\n            hess_inv = minimizer.np_covariance()\n\n        unc = None\n        if return_uncertainties:\n            unc = minimizer.np_errors()\n\n        return scipy.optimize.OptimizeResult(\n            x=minimizer.np_values(),\n            unc=unc,\n            success=minimizer.valid,\n            fun=minimizer.fval,\n            hess_inv=hess_inv,\n            message=message,\n            nfev=minimizer.ncalls_total,\n            njev=minimizer.ngrads_total,\n            minuit=minimizer,\n        )\n", "path": "src/pyhf/optimize/opt_minuit.py"}, {"content": "from setuptools import setup\n\nextras_require = {\n    'shellcomplete': ['click_completion'],\n    'tensorflow': [\n        'tensorflow~=2.2.0',  # TensorFlow minor releases are as volatile as major\n        'tensorflow-probability~=0.10.0',\n    ],\n    'torch': ['torch~=1.2'],\n    'jax': ['jax~=0.2.4', 'jaxlib~=0.1.56'],\n    'xmlio': ['uproot3~=3.14'],  # Future proof against uproot4 API changes\n    'minuit': ['iminuit~=1.5.3'],\n}\nextras_require['backends'] = sorted(\n    set(\n        extras_require['tensorflow']\n        + extras_require['torch']\n        + extras_require['jax']\n        + extras_require['minuit']\n    )\n)\nextras_require['contrib'] = sorted({'matplotlib', 'requests'})\nextras_require['lint'] = sorted({'flake8', 'black'})\n\nextras_require['test'] = sorted(\n    set(\n        extras_require['backends']\n        + extras_require['xmlio']\n        + extras_require['contrib']\n        + extras_require['shellcomplete']\n        + [\n            'pytest~=6.0',\n            'pytest-cov>=2.5.1',\n            'pytest-mock',\n            'pytest-benchmark[histogram]',\n            'pytest-console-scripts',\n            'pytest-mpl',\n            'pydocstyle',\n            'coverage>=4.0',  # coveralls\n            'papermill~=2.0',\n            'nteract-scrapbook~=0.2',\n            'jupyter',\n            'graphviz',\n            'jsonpatch',\n        ]\n    )\n)\nextras_require['docs'] = sorted(\n    {\n        'sphinx>=3.1.2',\n        'sphinxcontrib-bibtex~=1.0',\n        'sphinx-click',\n        'sphinx_rtd_theme',\n        'nbsphinx',\n        'ipywidgets',\n        'sphinx-issues',\n        'sphinx-copybutton>0.2.9',\n    }\n)\nextras_require['develop'] = sorted(\n    set(\n        extras_require['docs']\n        + extras_require['lint']\n        + extras_require['test']\n        + [\n            'nbdime',\n            'bump2version',\n            'ipython',\n            'pre-commit',\n            'check-manifest',\n            'codemetapy>=0.3.4',\n            'twine',\n        ]\n    )\n)\nextras_require['complete'] = sorted(set(sum(extras_require.values(), [])))\n\n\nsetup(\n    extras_require=extras_require,\n    use_scm_version=lambda: {'local_scheme': lambda version: ''},\n)\n", "path": "setup.py"}], "after_files": [{"content": "\"\"\"Minuit Optimizer Class.\"\"\"\nfrom .. import default_backend, exceptions\nfrom .mixins import OptimizerMixin\nimport scipy\nimport iminuit\n\n\nclass minuit_optimizer(OptimizerMixin):\n    \"\"\"\n    Optimizer that uses iminuit.Minuit.migrad.\n    \"\"\"\n\n    __slots__ = ['name', 'errordef', 'steps', 'strategy', 'tolerance']\n\n    def __init__(self, *args, **kwargs):\n        \"\"\"\n        Create MINUIT Optimizer.\n\n        .. note::\n\n            ``errordef`` should be 1.0 for a least-squares cost function and 0.5\n            for negative log-likelihood function. See page 37 of\n            http://hep.fi.infn.it/minuit.pdf. This parameter is sometimes\n            called ``UP`` in the ``MINUIT`` docs.\n\n\n        Args:\n            errordef (:obj:`float`): See minuit docs. Default is 1.0.\n            steps (:obj:`int`): Number of steps for the bounds. Default is 1000.\n            strategy (:obj:`int`): See :attr:`iminuit.Minuit.strategy`. Default is None.\n            tolerance (:obj:`float`): tolerance for termination. See specific optimizer for detailed meaning. Default is 0.1.\n        \"\"\"\n        self.name = 'minuit'\n        self.errordef = kwargs.pop('errordef', 1)\n        self.steps = kwargs.pop('steps', 1000)\n        self.strategy = kwargs.pop('strategy', None)\n        self.tolerance = kwargs.pop('tolerance', 0.1)\n        super().__init__(*args, **kwargs)\n\n    def _get_minimizer(\n        self, objective_and_grad, init_pars, init_bounds, fixed_vals=None, do_grad=False\n    ):\n\n        step_sizes = [(b[1] - b[0]) / float(self.steps) for b in init_bounds]\n        fixed_vals = fixed_vals or []\n        # Minuit wants True/False for each parameter\n        fixed_bools = [False] * len(init_pars)\n        for index, val in fixed_vals:\n            fixed_bools[index] = True\n            init_pars[index] = val\n            step_sizes[index] = 0.0\n\n        # Minuit requires jac=callable\n        if do_grad:\n            wrapped_objective = lambda pars: objective_and_grad(pars)[0]  # noqa: E731\n            jac = lambda pars: objective_and_grad(pars)[1]  # noqa: E731\n        else:\n            wrapped_objective = objective_and_grad\n            jac = None\n\n        minuit = iminuit.Minuit(wrapped_objective, init_pars, grad=jac)\n        minuit.errors = step_sizes\n        minuit.limits = init_bounds\n        minuit.fixed = fixed_bools\n        minuit.print_level = self.verbose\n        minuit.errordef = self.errordef\n        return minuit\n\n    def _minimize(\n        self,\n        minimizer,\n        func,\n        x0,\n        do_grad=False,\n        bounds=None,\n        fixed_vals=None,\n        return_uncertainties=False,\n        options={},\n    ):\n\n        \"\"\"\n        Same signature as :func:`scipy.optimize.minimize`.\n\n        Note: an additional `minuit` is injected into the fitresult to get the\n        underlying minimizer.\n\n        Minimizer Options:\n            maxiter (:obj:`int`): maximum number of iterations. Default is 100000.\n            return_uncertainties (:obj:`bool`): Return uncertainties on the fitted parameters. Default is off.\n            strategy (:obj:`int`): See :attr:`iminuit.Minuit.strategy`. Default is to configure in response to `do_grad`.\n\n        Returns:\n            fitresult (scipy.optimize.OptimizeResult): the fit result\n        \"\"\"\n        maxiter = options.pop('maxiter', self.maxiter)\n        return_uncertainties = options.pop('return_uncertainties', False)\n        # 0: Fast, user-provided gradient\n        # 1: Default, no user-provided gradient\n        strategy = options.pop(\n            'strategy', self.strategy if self.strategy else not do_grad\n        )\n        tolerance = options.pop('tolerance', self.tolerance)\n        if options:\n            raise exceptions.Unsupported(\n                f\"Unsupported options were passed in: {list(options.keys())}.\"\n            )\n\n        minimizer.strategy = strategy\n        minimizer.tol = tolerance\n        minimizer.migrad(ncall=maxiter)\n        # Following lines below come from:\n        # https://github.com/scikit-hep/iminuit/blob/23bad7697e39d363f259ca8349684df939b1b2e6/src/iminuit/_minimize.py#L111-L130\n        message = \"Optimization terminated successfully.\"\n        if not minimizer.valid:\n            message = \"Optimization failed.\"\n            fmin = minimizer.fmin\n            if fmin.has_reached_call_limit:\n                message += \" Call limit was reached.\"\n            if fmin.is_above_max_edm:\n                message += \" Estimated distance to minimum too large.\"\n\n        n = len(x0)\n        hess_inv = default_backend.ones((n, n))\n        if minimizer.valid:\n            # Extra call to hesse() after migrad() is always needed for good error estimates. If you pass a user-provided gradient to MINUIT, convergence is faster.\n            minimizer.hesse()\n            hess_inv = minimizer.covariance\n\n        unc = None\n        if return_uncertainties:\n            unc = minimizer.errors\n\n        return scipy.optimize.OptimizeResult(\n            x=minimizer.values,\n            unc=unc,\n            success=minimizer.valid,\n            fun=minimizer.fval,\n            hess_inv=hess_inv,\n            message=message,\n            nfev=minimizer.nfcn,\n            njev=minimizer.ngrad,\n            minuit=minimizer,\n        )\n", "path": "src/pyhf/optimize/opt_minuit.py"}, {"content": "from setuptools import setup\n\nextras_require = {\n    'shellcomplete': ['click_completion'],\n    'tensorflow': [\n        'tensorflow~=2.2.0',  # TensorFlow minor releases are as volatile as major\n        'tensorflow-probability~=0.10.0',\n    ],\n    'torch': ['torch~=1.2'],\n    'jax': ['jax~=0.2.4', 'jaxlib~=0.1.56'],\n    'xmlio': ['uproot3~=3.14'],  # Future proof against uproot4 API changes\n    'minuit': ['iminuit~=2.1'],\n}\nextras_require['backends'] = sorted(\n    set(\n        extras_require['tensorflow']\n        + extras_require['torch']\n        + extras_require['jax']\n        + extras_require['minuit']\n    )\n)\nextras_require['contrib'] = sorted({'matplotlib', 'requests'})\nextras_require['lint'] = sorted({'flake8', 'black'})\n\nextras_require['test'] = sorted(\n    set(\n        extras_require['backends']\n        + extras_require['xmlio']\n        + extras_require['contrib']\n        + extras_require['shellcomplete']\n        + [\n            'pytest~=6.0',\n            'pytest-cov>=2.5.1',\n            'pytest-mock',\n            'pytest-benchmark[histogram]',\n            'pytest-console-scripts',\n            'pytest-mpl',\n            'pydocstyle',\n            'coverage>=4.0',  # coveralls\n            'papermill~=2.0',\n            'nteract-scrapbook~=0.2',\n            'jupyter',\n            'graphviz',\n            'jsonpatch',\n        ]\n    )\n)\nextras_require['docs'] = sorted(\n    {\n        'sphinx>=3.1.2',\n        'sphinxcontrib-bibtex~=1.0',\n        'sphinx-click',\n        'sphinx_rtd_theme',\n        'nbsphinx',\n        'ipywidgets',\n        'sphinx-issues',\n        'sphinx-copybutton>0.2.9',\n    }\n)\nextras_require['develop'] = sorted(\n    set(\n        extras_require['docs']\n        + extras_require['lint']\n        + extras_require['test']\n        + [\n            'nbdime',\n            'bump2version',\n            'ipython',\n            'pre-commit',\n            'check-manifest',\n            'codemetapy>=0.3.4',\n            'twine',\n        ]\n    )\n)\nextras_require['complete'] = sorted(set(sum(extras_require.values(), [])))\n\n\nsetup(\n    extras_require=extras_require,\n    use_scm_version=lambda: {'local_scheme': lambda version: ''},\n)\n", "path": "setup.py"}]}