{
 "cells": [
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# Tutorial\n",
    "\n",
    "Welcome to the **iminuit tutorial**. You will learn basic usage of iminuit and how to approach standard fitting problems with iminuit. \n",
    "\n",
    "iminuit is a Python frontend to the *Minuit* library in C++, an integrated software that combines a local minimizer (called *Migrad*) and two error calculators (called *Hesse* and the *Minos*). You provide it an analytical function, which accepts one or several parameters, and an initial guess of the parameter values. It will then find a local minimum of this function starting from the initial guess. In that regard, iminuit minimizer is like other local minimizers, like those in scipy.optimize.\n",
    "\n",
    "In addition, iminuit has the ability to compute **uncertainty estimates** for model parameters. iminuit was designed to solve statistics problems, where uncertainty estimates are an essential part of the result. The two ways of computing uncertainty estimates, *Hesse* and the *Minos*, have different advantages and disadvantages.\n",
    "\n",
    "iminuit is the successor of pyminuit. If you used pyminuit before, you will find iminuit very familiar. An important feature of iminuit (and pyminuit) is that it uses introspection to detect the parameter names of your function. This is very convenient, especially when you work interactively in a Jupyter notebook. It also provides special output routines for Jupyter notebooks to pretty print the fit results, as you will see below."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 1,
   "metadata": {},
   "outputs": [],
   "source": [
    "# basic setup of the notebook\n",
    "from matplotlib import pyplot as plt\n",
    "import numpy as np\n",
    "\n",
    "# everything in iminuit is done through the Minuit object, so we import it\n",
    "from iminuit import Minuit"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Fit example\n",
    "\n",
    "For this tutorial, we look at a simple case where line should be fitted to scattered $(x, y)$ data. A line has two parameters $(a, b)$."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 2,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "image/png": "[encoded data, 7864 characters]\n",
      "text/plain": [
       "<Figure size 432x288 with 1 Axes>"
      ]
     },
     "metadata": {
      "needs_background": "light"
     },
     "output_type": "display_data"
    }
   ],
   "source": [
    "def line(x, a, b):\n",
    "    return a + x * b\n",
    "\n",
    "data_x = np.linspace(0, 1, 10)\n",
    "# precomputed random numbers from a normal distribution\n",
    "offsets = np.array([-0.49783783, -0.33041722, -1.71800806,  1.60229399,  1.36682387,\n",
    "                    -1.15424221, -0.91425267, -0.03395604, -1.27611719, -0.7004073 ])\n",
    "data_y = line(data_x, 1, 2) + 0.1 * offsets # generate some data points with random offsets\n",
    "plt.plot(data_x, data_y, \"o\")\n",
    "plt.xlim(-0.1, 1.1);"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "To recovert the parameters of the line, we fit the line to the scattered data using the method of least-squares. We compute the sum of squared residuals of the $y$ values around the line for a given pair of line parameters $(a, b)$."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 3,
   "metadata": {},
   "outputs": [],
   "source": [
    "def least_squares(a, b):\n",
    "    yvar = 0.01\n",
    "    return sum((data_y - line(data_x, a, b)) ** 2 / yvar)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "With iminuit we can find the values of $a$ and $b$ which minimize this sum. Let's do it:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 4,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "a = 0.9909664415271797 +/- 0.05877537956552539\n",
      "b = 1.9449447037452918 +/- 0.0990867390925457\n"
     ]
    },
    {
     "data": {
      "image/png": "[encoded data, 11972 characters]\n",
      "text/plain": [
       "<Figure size 432x288 with 1 Axes>"
      ]
     },
     "metadata": {
      "needs_background": "light"
     },
     "output_type": "display_data"
    }
   ],
   "source": [
    "m = Minuit(least_squares, pedantic=False)\n",
    "m.migrad() # finds minimum of least_squares function\n",
    "m.hesse()  # computes errors \n",
    "\n",
    "# draw data and fitted line\n",
    "plt.plot(data_x, data_y, \"o\")\n",
    "plt.plot(data_x, line(data_x, *m.values.values()))\n",
    "\n",
    "# print parameter values and uncertainty estimates\n",
    "for p in m.parameters:\n",
    "    print(\"{} = {} +/- {}\".format(p, m.values[p], m.errors[p]))"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "In the following, we dive into the details step by step; how the Minuit object is initialized, how to run the algorithms, and how to get the results.\n",
    "\n",
    "iminuit was designed to make it easy to fit functions like `least_squares(a, b)`, where the parameters are individual arguments of the function. There is an alternative function signature that Minuit supports, which is more convenient when you work a lot with numpy. Here, the parameters are passed as a numpy array. The two kinds of function definitions have each pros and cons. We will first dive how to work with functions of the first kind and come back to the second kind later. If you are interested only in the second kind, skip to the section **Alternative: Numpy functions**"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Initialize Minuit object\n",
    "\n",
    "To minimize a function, you create an instance of the Minuit class and pass the function to it. This does not start the minimization yet, this will come later. iminuit uses introspection to get the number and names of the function parameters automatically."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 5,
   "metadata": {},
   "outputs": [
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "/usr/local/lib/python3.7/site-packages/ipykernel_launcher.py:1: InitialParamWarning: Parameter a does not have neither initial value nor limits.\n",
      "  \"\"\"Entry point for launching an IPython kernel.\n",
      "/usr/local/lib/python3.7/site-packages/ipykernel_launcher.py:1: InitialParamWarning: Parameter b does not have neither initial value nor limits.\n",
      "  \"\"\"Entry point for launching an IPython kernel.\n",
      "/usr/local/lib/python3.7/site-packages/ipykernel_launcher.py:1: InitialParamWarning: errordef is not given, defaults to 1.\n",
      "  \"\"\"Entry point for launching an IPython kernel.\n"
     ]
    }
   ],
   "source": [
    "m = Minuit(least_squares) # we create an instance of Minuit and pass the function to minimize"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Woah, lots of warnings, we will go through them step-by-step. Note how iminuit refers to your parameters by correct names in the warnings. The filename and line numbers shown in the warnings are bogus in Jupyter notebooks, but refer to the correct file and line when you use iminuit in a script or in the terminal shell.\n",
    "\n",
    "### Initial parameter values\n",
    "\n",
    "iminuit is a local minimizer. It searches for a local minimum by gradient-descent method from a starting point. If your function has several minima, the minimum found will depend on the starting point. Even if it has only one minimum, iminuit will converge to it faster if you start in the proximity of the minimum. If you don't provide a starting value for a parameter, it uses 0. You almost always want to specify a starting point.\n",
    "\n",
    "You can set the starting point using the parameter names as keywords, `<name> = <value>`."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 6,
   "metadata": {},
   "outputs": [
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "/usr/local/lib/python3.7/site-packages/ipykernel_launcher.py:1: InitialParamWarning: errordef is not given, defaults to 1.\n",
      "  \"\"\"Entry point for launching an IPython kernel.\n"
     ]
    }
   ],
   "source": [
    "m = Minuit(least_squares, a=5, b=5) # pass starting values for a and b"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### Error definition\n",
    "\n",
    "Only one warning left. Minuit asks you to explicitly provide a value for the error definition with the `errordef` keyword. This is needed to get correct uncertainty estimates for your parameters. In statistical problems, there are two kinds of functions to minimize, the *negative log-likelihood* and the *least-squares* function. Each has a corresponding value for `errordef`:\n",
    " - `0.5` or the constant `Minuit.LIKELIHOOD` for negative log-likelihood functions \n",
    " - `1` or the constant `Minuit.LEAST_SQUARES` for least-squares functions \n",
    "\n",
    "The origin of these numbers is not complicated, but cannot be explained briefly. If you are curious, have a look into the tutorial \"Error computation with HESSE and MINOS\".\n",
    "\n",
    "If you don't care about uncertainty estimates, just use the `errordef=1`.\n",
    "\n",
    "For our example, we need to pass `errordef=1` or `errordef=Minuit.LEAST_SQUARES`, because we are minimizing a least-squares function."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 7,
   "metadata": {},
   "outputs": [],
   "source": [
    "m = Minuit(least_squares, a=5, b=5, errordef=Minuit.LEAST_SQUARES)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Now iminuit is happy, all recommended information is provided. You can always check the current parameter settings with the method `Minuit.params`."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 8,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/html": [
       "<table>\n",
       "<tr style=\"background-color:#F4F4F4;\">\n",
       "<td/>\n",
       "<th title=\"Variable name\">\n",
       "Name\n",
       "</th>\n",
       "<th title=\"Value of parameter\">\n",
       "Value\n",
       "</th>\n",
       "<th title=\"Hesse error\">\n",
       "Hesse Error\n",
       "</th>\n",
       "<th title=\"Minos lower error\">\n",
       "Minos Error-\n",
       "</th>\n",
       "<th title=\"Minos upper error\">\n",
       "Minos Error+\n",
       "</th>\n",
       "<th title=\"Lower limit of the parameter\">\n",
       "Limit-\n",
       "</th>\n",
       "<th title=\"Upper limit of the parameter\">\n",
       "Limit+\n",
       "</th>\n",
       "<th title=\"Is the parameter fixed in the fit\">\n",
       "Fixed\n",
       "</th>\n",
       "</tr>\n",
       "<tr style=\"background-color:#FFFFFF;\">\n",
       "<td>\n",
       "0\n",
       "</td>\n",
       "<td>\n",
       "a\n",
       "</td>\n",
       "<td>\n",
       "5.00\n",
       "</td>\n",
       "<td>\n",
       "0.05\n",
       "</td>\n",
       "<td>\n",
       "\n",
       "</td>\n",
       "<td>\n",
       "\n",
       "</td>\n",
       "<td>\n",
       "\n",
       "</td>\n",
       "<td>\n",
       "\n",
       "</td>\n",
       "<td>\n",
       "\n",
       "</td>\n",
       "</tr>\n",
       "<tr style=\"background-color:#F4F4F4;\">\n",
       "<td>\n",
       "1\n",
       "</td>\n",
       "<td>\n",
       "b\n",
       "</td>\n",
       "<td>\n",
       "5.00\n",
       "</td>\n",
       "<td>\n",
       "0.05\n",
       "</td>\n",
       "<td>\n",
       "\n",
       "</td>\n",
       "<td>\n",
       "\n",
       "</td>\n",
       "<td>\n",
       "\n",
       "</td>\n",
       "<td>\n",
       "\n",
       "</td>\n",
       "<td>\n",
       "\n",
       "</td>\n",
       "</tr>\n",
       "</table>\n"
      ],
      "text/plain": [
       "------------------------------------------------------------------------------------------\n",
       "|   | Name |   Value   | Hesse Err | Minos Err- | Minos Err+ | Limit-  | Limit+  | Fixed |\n",
       "------------------------------------------------------------------------------------------\n",
       "| 0 | a    |   5.00    |   0.05    |            |            |         |         |       |\n",
       "| 1 | b    |   5.00    |   0.05    |            |            |         |         |       |\n",
       "------------------------------------------------------------------------------------------"
      ]
     },
     "execution_count": 8,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "m.params"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "\n",
    "As you can see, this produces a nice table. The table will be updated once you run the actual minimization. To look at the initital conditions later, use `Minuit.init_params`. We will come back to the meaning of *Hesse Error* and *Minos Error*, when we discuss the actual minimization.\n",
    "\n",
    "Before we do that, let's see what else we can specify in the initialization."
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### Silence warnings\n",
    "\n",
    "If you want to quickly minimize a function and you know that the defaults are ok, you can explicitly silence all warnings, like so:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 9,
   "metadata": {},
   "outputs": [],
   "source": [
    "m = Minuit(least_squares, pedantic=False)  # silence warnings, use default values"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### Parameters with limits\n",
    "\n",
    "iminuit allows you to set parameter limits. Often a parameter is limited mathematically or physically to a certain range. For example, if your function contains `sqrt(x)`, then $x$ must be non-negative, $x \\ge 0$. You can set upper-, lower-, or two-sided limits for each parameter individually with keywords `limit_<name>`:\n",
    "\n",
    "- lower limit: use `limit_<name> = (<value>, None)` or `(<value>, float(\"infinity\"))`\n",
    "- upper limit: use `limit_<name> = (None, <value>)` or `(-float(\"infinity\"), <value>)`\n",
    "- two-sided limit: use `limit_<name> = (<min_value>, <max_value>)`\n",
    "\n",
    "To impose the limits $a \\ge 0$ and $0 \\le b \\le 10$ in our example, we use:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 10,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/html": [
       "<table>\n",
       "<tr style=\"background-color:#F4F4F4;\">\n",
       "<td/>\n",
       "<th title=\"Variable name\">\n",
       "Name\n",
       "</th>\n",
       "<th title=\"Value of parameter\">\n",
       "Value\n",
       "</th>\n",
       "<th title=\"Hesse error\">\n",
       "Hesse Error\n",
       "</th>\n",
       "<th title=\"Minos lower error\">\n",
       "Minos Error-\n",
       "</th>\n",
       "<th title=\"Minos upper error\">\n",
       "Minos Error+\n",
       "</th>\n",
       "<th title=\"Lower limit of the parameter\">\n",
       "Limit-\n",
       "</th>\n",
       "<th title=\"Upper limit of the parameter\">\n",
       "Limit+\n",
       "</th>\n",
       "<th title=\"Is the parameter fixed in the fit\">\n",
       "Fixed\n",
       "</th>\n",
       "</tr>\n",
       "<tr style=\"background-color:#FFFFFF;\">\n",
       "<td>\n",
       "0\n",
       "</td>\n",
       "<td>\n",
       "a\n",
       "</td>\n",
       "<td>\n",
       "5.0\n",
       "</td>\n",
       "<td>\n",
       "0.1\n",
       "</td>\n",
       "<td>\n",
       "\n",
       "</td>\n",
       "<td>\n",
       "\n",
       "</td>\n",
       "<td>\n",
       "0\n",
       "</td>\n",
       "<td>\n",
       "\n",
       "</td>\n",
       "<td>\n",
       "\n",
       "</td>\n",
       "</tr>\n",
       "<tr style=\"background-color:#F4F4F4;\">\n",
       "<td>\n",
       "1\n",
       "</td>\n",
       "<td>\n",
       "b\n",
       "</td>\n",
       "<td>\n",
       "5.0\n",
       "</td>\n",
       "<td>\n",
       "0.1\n",
       "</td>\n",
       "<td>\n",
       "\n",
       "</td>\n",
       "<td>\n",
       "\n",
       "</td>\n",
       "<td>\n",
       "0\n",
       "</td>\n",
       "<td>\n",
       "10\n",
       "</td>\n",
       "<td>\n",
       "\n",
       "</td>\n",
       "</tr>\n",
       "</table>\n"
      ],
      "text/plain": [
       "------------------------------------------------------------------------------------------\n",
       "|   | Name |   Value   | Hesse Err | Minos Err- | Minos Err+ | Limit-  | Limit+  | Fixed |\n",
       "------------------------------------------------------------------------------------------\n",
       "| 0 | a    |    5.0    |    0.1    |            |            |    0    |         |       |\n",
       "| 1 | b    |    5.0    |    0.1    |            |            |    0    |   10    |       |\n",
       "------------------------------------------------------------------------------------------"
      ]
     },
     "execution_count": 10,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "m = Minuit(least_squares, a=5, b=5,\n",
    "           error_a=0.1, error_b=0.1,\n",
    "           limit_a=(0, None), limit_b=(0, 10),\n",
    "           errordef=1)\n",
    "m.params"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### (Initially) Fixed parameters\n",
    "\n",
    "Sometimes you have a parameter which you want to set to a fixed value temporarily. Perhaps you have a guess for its value, and you want to see how the other parameters adapt when this parameter is fixed to that value.\n",
    "\n",
    "Or you have a complex function with many parameters that do not all affect the function at the same scale. Then you can manually help the minimizer to find the minimum faster by first fixing the less important parameters to initial guesses and fit only the important parameters. Once the minimum is found under these conditions, you can release the fixed parameters and optimize all parameters together. Minuit remembers the last state of the minimization and starts from there. The minimization time roughly scales with the square of the number of parameters. Iterated minimization over subspaces of the parameters can reduce that time.\n",
    "\n",
    "To fix an individual parameter, you use the keyword `fix_<name> = True`. In our example, we fix $x$, like so:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 11,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/html": [
       "<table>\n",
       "<tr style=\"background-color:#F4F4F4;\">\n",
       "<td/>\n",
       "<th title=\"Variable name\">\n",
       "Name\n",
       "</th>\n",
       "<th title=\"Value of parameter\">\n",
       "Value\n",
       "</th>\n",
       "<th title=\"Hesse error\">\n",
       "Hesse Error\n",
       "</th>\n",
       "<th title=\"Minos lower error\">\n",
       "Minos Error-\n",
       "</th>\n",
       "<th title=\"Minos upper error\">\n",
       "Minos Error+\n",
       "</th>\n",
       "<th title=\"Lower limit of the parameter\">\n",
       "Limit-\n",
       "</th>\n",
       "<th title=\"Upper limit of the parameter\">\n",
       "Limit+\n",
       "</th>\n",
       "<th title=\"Is the parameter fixed in the fit\">\n",
       "Fixed\n",
       "</th>\n",
       "</tr>\n",
       "<tr style=\"background-color:#FFFFFF;\">\n",
       "<td>\n",
       "0\n",
       "</td>\n",
       "<td>\n",
       "a\n",
       "</td>\n",
       "<td>\n",
       "5.0\n",
       "</td>\n",
       "<td>\n",
       "0.1\n",
       "</td>\n",
       "<td>\n",
       "\n",
       "</td>\n",
       "<td>\n",
       "\n",
       "</td>\n",
       "<td>\n",
       "\n",
       "</td>\n",
       "<td>\n",
       "\n",
       "</td>\n",
       "<td>\n",
       "yes\n",
       "</td>\n",
       "</tr>\n",
       "<tr style=\"background-color:#F4F4F4;\">\n",
       "<td>\n",
       "1\n",
       "</td>\n",
       "<td>\n",
       "b\n",
       "</td>\n",
       "<td>\n",
       "5.0\n",
       "</td>\n",
       "<td>\n",
       "0.1\n",
       "</td>\n",
       "<td>\n",
       "\n",
       "</td>\n",
       "<td>\n",
       "\n",
       "</td>\n",
       "<td>\n",
       "\n",
       "</td>\n",
       "<td>\n",
       "\n",
       "</td>\n",
       "<td>\n",
       "\n",
       "</td>\n",
       "</tr>\n",
       "</table>\n"
      ],
      "text/plain": [
       "------------------------------------------------------------------------------------------\n",
       "|   | Name |   Value   | Hesse Err | Minos Err- | Minos Err+ | Limit-  | Limit+  | Fixed |\n",
       "------------------------------------------------------------------------------------------\n",
       "| 0 | a    |    5.0    |    0.1    |            |            |         |         |  yes  |\n",
       "| 1 | b    |    5.0    |    0.1    |            |            |         |         |       |\n",
       "------------------------------------------------------------------------------------------"
      ]
     },
     "execution_count": 11,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "m = Minuit(least_squares, a=5, b=5, fix_a=True,\n",
    "           error_a=0.1, error_b=0.1,\n",
    "           errordef=1)\n",
    "m.params"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 12,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/html": [
       "<table>\n",
       "<tr>\n",
       "<td colspan=\"2\" title=\"Minimum value of function\">\n",
       "FCN = 4663\n",
       "</td>\n",
       "<td align=\"center\" colspan=\"3\" title=\"No. of calls in last algorithm and total number of calls\">\n",
       "Ncalls = 13 (13 total)\n",
       "</td>\n",
       "</tr>\n",
       "<tr>\n",
       "<td colspan=\"2\" title=\"Estimated distance to minimum and target threshold\">\n",
       "EDM = 2.56e-16 (Goal: 0.0002)\n",
       "</td>\n",
       "<td align=\"center\" colspan=\"3\" title=\"Increase in FCN which corresponds to 1 standard deviation\">\n",
       "up = 1.0\n",
       "</td>\n",
       "</tr>\n",
       "<tr>\n",
       "<td align=\"center\" title=\"Validity of the migrad call\">\n",
       "Valid Min.\n",
       "</td>\n",
       "<td align=\"center\" title=\"Validity of parameters\">\n",
       "Valid Param.\n",
       "</td>\n",
       "<td align=\"center\" title=\"Is EDM above goal EDM?\">\n",
       "Above EDM\n",
       "</td>\n",
       "<td align=\"center\" colspan=\"2\" title=\"Did last migrad call reach max call limit?\">\n",
       "Reached call limit\n",
       "</td>\n",
       "</tr>\n",
       "<tr>\n",
       "<td align=\"center\" style=\"background-color:#92CCA6;\">\n",
       "True\n",
       "</td>\n",
       "<td align=\"center\" style=\"background-color:#92CCA6;\">\n",
       "True\n",
       "</td>\n",
       "<td align=\"center\" style=\"background-color:#92CCA6;\">\n",
       "False\n",
       "</td>\n",
       "<td align=\"center\" colspan=\"2\" style=\"background-color:#92CCA6;\">\n",
       "False\n",
       "</td>\n",
       "</tr>\n",
       "<tr>\n",
       "<td align=\"center\" title=\"Did Hesse fail?\">\n",
       "Hesse failed\n",
       "</td>\n",
       "<td align=\"center\" title=\"Has covariance matrix\">\n",
       "Has cov.\n",
       "</td>\n",
       "<td align=\"center\" title=\"Is covariance matrix accurate?\">\n",
       "Accurate\n",
       "</td>\n",
       "<td align=\"center\" title=\"Is covariance matrix positive definite?\">\n",
       "Pos. def.\n",
       "</td>\n",
       "<td align=\"center\" title=\"Was positive definiteness enforced by Minuit?\">\n",
       "Forced\n",
       "</td>\n",
       "</tr>\n",
       "<tr>\n",
       "<td align=\"center\" style=\"background-color:#92CCA6;\">\n",
       "False\n",
       "</td>\n",
       "<td align=\"center\" style=\"background-color:#92CCA6;\">\n",
       "True\n",
       "</td>\n",
       "<td align=\"center\" style=\"background-color:#92CCA6;\">\n",
       "True\n",
       "</td>\n",
       "<td align=\"center\" style=\"background-color:#92CCA6;\">\n",
       "True\n",
       "</td>\n",
       "<td align=\"center\" style=\"background-color:#92CCA6;\">\n",
       "False\n",
       "</td>\n",
       "</tr>\n",
       "</table>\n",
       "<table>\n",
       "<tr style=\"background-color:#F4F4F4;\">\n",
       "<td/>\n",
       "<th title=\"Variable name\">\n",
       "Name\n",
       "</th>\n",
       "<th title=\"Value of parameter\">\n",
       "Value\n",
       "</th>\n",
       "<th title=\"Hesse error\">\n",
       "Hesse Error\n",
       "</th>\n",
       "<th title=\"Minos lower error\">\n",
       "Minos Error-\n",
       "</th>\n",
       "<th title=\"Minos upper error\">\n",
       "Minos Error+\n",
       "</th>\n",
       "<th title=\"Lower limit of the parameter\">\n",
       "Limit-\n",
       "</th>\n",
       "<th title=\"Upper limit of the parameter\">\n",
       "Limit+\n",
       "</th>\n",
       "<th title=\"Is the parameter fixed in the fit\">\n",
       "Fixed\n",
       "</th>\n",
       "</tr>\n",
       "<tr style=\"background-color:#FFFFFF;\">\n",
       "<td>\n",
       "0\n",
       "</td>\n",
       "<td>\n",
       "a\n",
       "</td>\n",
       "<td>\n",
       "5.0\n",
       "</td>\n",
       "<td>\n",
       "0.1\n",
       "</td>\n",
       "<td>\n",
       "\n",
       "</td>\n",
       "<td>\n",
       "\n",
       "</td>\n",
       "<td>\n",
       "\n",
       "</td>\n",
       "<td>\n",
       "\n",
       "</td>\n",
       "<td>\n",
       "yes\n",
       "</td>\n",
       "</tr>\n",
       "<tr style=\"background-color:#F4F4F4;\">\n",
       "<td>\n",
       "1\n",
       "</td>\n",
       "<td>\n",
       "b\n",
       "</td>\n",
       "<td>\n",
       "-3.75\n",
       "</td>\n",
       "<td>\n",
       "0.05\n",
       "</td>\n",
       "<td>\n",
       "\n",
       "</td>\n",
       "<td>\n",
       "\n",
       "</td>\n",
       "<td>\n",
       "\n",
       "</td>\n",
       "<td>\n",
       "\n",
       "</td>\n",
       "<td>\n",
       "\n",
       "</td>\n",
       "</tr>\n",
       "</table>\n"
      ],
      "text/plain": [
       "------------------------------------------------------------------\n",
       "| FCN = 4663                    |      Ncalls=13 (13 total)      |\n",
       "| EDM = 2.56e-16 (Goal: 0.0002) |            up = 1.0            |\n",
       "------------------------------------------------------------------\n",
       "|  Valid Min.   | Valid Param.  | Above EDM | Reached call limit |\n",
       "------------------------------------------------------------------\n",
       "|     True      |     True      |   False   |       False        |\n",
       "------------------------------------------------------------------\n",
       "| Hesse failed  |   Has cov.    | Accurate  | Pos. def. | Forced |\n",
       "------------------------------------------------------------------\n",
       "|     False     |     True      |   True    |   True    | False  |\n",
       "------------------------------------------------------------------\n",
       "------------------------------------------------------------------------------------------\n",
       "|   | Name |   Value   | Hesse Err | Minos Err- | Minos Err+ | Limit-  | Limit+  | Fixed |\n",
       "------------------------------------------------------------------------------------------\n",
       "| 0 | a    |    5.0    |    0.1    |            |            |         |         |  yes  |\n",
       "| 1 | b    |   -3.75   |   0.05    |            |            |         |         |       |\n",
       "------------------------------------------------------------------------------------------"
      ]
     },
     "execution_count": 12,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "# migrad will not vary a, only b\n",
    "m.migrad()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 13,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/html": [
       "<table>\n",
       "<tr>\n",
       "<td colspan=\"2\" title=\"Minimum value of function\">\n",
       "FCN = 3316\n",
       "</td>\n",
       "<td align=\"center\" colspan=\"3\" title=\"No. of calls in last algorithm and total number of calls\">\n",
       "Ncalls = 13 (26 total)\n",
       "</td>\n",
       "</tr>\n",
       "<tr>\n",
       "<td colspan=\"2\" title=\"Estimated distance to minimum and target threshold\">\n",
       "EDM = 1.02e-17 (Goal: 0.0002)\n",
       "</td>\n",
       "<td align=\"center\" colspan=\"3\" title=\"Increase in FCN which corresponds to 1 standard deviation\">\n",
       "up = 1.0\n",
       "</td>\n",
       "</tr>\n",
       "<tr>\n",
       "<td align=\"center\" title=\"Validity of the migrad call\">\n",
       "Valid Min.\n",
       "</td>\n",
       "<td align=\"center\" title=\"Validity of parameters\">\n",
       "Valid Param.\n",
       "</td>\n",
       "<td align=\"center\" title=\"Is EDM above goal EDM?\">\n",
       "Above EDM\n",
       "</td>\n",
       "<td align=\"center\" colspan=\"2\" title=\"Did last migrad call reach max call limit?\">\n",
       "Reached call limit\n",
       "</td>\n",
       "</tr>\n",
       "<tr>\n",
       "<td align=\"center\" style=\"background-color:#92CCA6;\">\n",
       "True\n",
       "</td>\n",
       "<td align=\"center\" style=\"background-color:#92CCA6;\">\n",
       "True\n",
       "</td>\n",
       "<td align=\"center\" style=\"background-color:#92CCA6;\">\n",
       "False\n",
       "</td>\n",
       "<td align=\"center\" colspan=\"2\" style=\"background-color:#92CCA6;\">\n",
       "False\n",
       "</td>\n",
       "</tr>\n",
       "<tr>\n",
       "<td align=\"center\" title=\"Did Hesse fail?\">\n",
       "Hesse failed\n",
       "</td>\n",
       "<td align=\"center\" title=\"Has covariance matrix\">\n",
       "Has cov.\n",
       "</td>\n",
       "<td align=\"center\" title=\"Is covariance matrix accurate?\">\n",
       "Accurate\n",
       "</td>\n",
       "<td align=\"center\" title=\"Is covariance matrix positive definite?\">\n",
       "Pos. def.\n",
       "</td>\n",
       "<td align=\"center\" title=\"Was positive definiteness enforced by Minuit?\">\n",
       "Forced\n",
       "</td>\n",
       "</tr>\n",
       "<tr>\n",
       "<td align=\"center\" style=\"background-color:#92CCA6;\">\n",
       "False\n",
       "</td>\n",
       "<td align=\"center\" style=\"background-color:#92CCA6;\">\n",
       "True\n",
       "</td>\n",
       "<td align=\"center\" style=\"background-color:#92CCA6;\">\n",
       "True\n",
       "</td>\n",
       "<td align=\"center\" style=\"background-color:#92CCA6;\">\n",
       "True\n",
       "</td>\n",
       "<td align=\"center\" style=\"background-color:#92CCA6;\">\n",
       "False\n",
       "</td>\n",
       "</tr>\n",
       "</table>\n",
       "<table>\n",
       "<tr style=\"background-color:#F4F4F4;\">\n",
       "<td/>\n",
       "<th title=\"Variable name\">\n",
       "Name\n",
       "</th>\n",
       "<th title=\"Value of parameter\">\n",
       "Value\n",
       "</th>\n",
       "<th title=\"Hesse error\">\n",
       "Hesse Error\n",
       "</th>\n",
       "<th title=\"Minos lower error\">\n",
       "Minos Error-\n",
       "</th>\n",
       "<th title=\"Minos upper error\">\n",
       "Minos Error+\n",
       "</th>\n",
       "<th title=\"Lower limit of the parameter\">\n",
       "Limit-\n",
       "</th>\n",
       "<th title=\"Upper limit of the parameter\">\n",
       "Limit+\n",
       "</th>\n",
       "<th title=\"Is the parameter fixed in the fit\">\n",
       "Fixed\n",
       "</th>\n",
       "</tr>\n",
       "<tr style=\"background-color:#FFFFFF;\">\n",
       "<td>\n",
       "0\n",
       "</td>\n",
       "<td>\n",
       "a\n",
       "</td>\n",
       "<td>\n",
       "3.839\n",
       "</td>\n",
       "<td>\n",
       "0.032\n",
       "</td>\n",
       "<td>\n",
       "\n",
       "</td>\n",
       "<td>\n",
       "\n",
       "</td>\n",
       "<td>\n",
       "\n",
       "</td>\n",
       "<td>\n",
       "\n",
       "</td>\n",
       "<td>\n",
       "\n",
       "</td>\n",
       "</tr>\n",
       "<tr style=\"background-color:#F4F4F4;\">\n",
       "<td>\n",
       "1\n",
       "</td>\n",
       "<td>\n",
       "b\n",
       "</td>\n",
       "<td>\n",
       "-3.75\n",
       "</td>\n",
       "<td>\n",
       "0.05\n",
       "</td>\n",
       "<td>\n",
       "\n",
       "</td>\n",
       "<td>\n",
       "\n",
       "</td>\n",
       "<td>\n",
       "\n",
       "</td>\n",
       "<td>\n",
       "\n",
       "</td>\n",
       "<td>\n",
       "yes\n",
       "</td>\n",
       "</tr>\n",
       "</table>\n"
      ],
      "text/plain": [
       "------------------------------------------------------------------\n",
       "| FCN = 3316                    |      Ncalls=13 (26 total)      |\n",
       "| EDM = 1.02e-17 (Goal: 0.0002) |            up = 1.0            |\n",
       "------------------------------------------------------------------\n",
       "|  Valid Min.   | Valid Param.  | Above EDM | Reached call limit |\n",
       "------------------------------------------------------------------\n",
       "|     True      |     True      |   False   |       False        |\n",
       "------------------------------------------------------------------\n",
       "| Hesse failed  |   Has cov.    | Accurate  | Pos. def. | Forced |\n",
       "------------------------------------------------------------------\n",
       "|     False     |     True      |   True    |   True    | False  |\n",
       "------------------------------------------------------------------\n",
       "------------------------------------------------------------------------------------------\n",
       "|   | Name |   Value   | Hesse Err | Minos Err- | Minos Err+ | Limit-  | Limit+  | Fixed |\n",
       "------------------------------------------------------------------------------------------\n",
       "| 0 | a    |   3.839   |   0.032   |            |            |         |         |       |\n",
       "| 1 | b    |   -3.75   |   0.05    |            |            |         |         |  yes  |\n",
       "------------------------------------------------------------------------------------------"
      ]
     },
     "execution_count": 13,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "# now we release a and fix b and minimize again\n",
    "m.fixed[\"a\"] = False\n",
    "m.fixed[\"b\"] = True\n",
    "m.migrad()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 14,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/html": [
       "<table>\n",
       "<tr>\n",
       "<td colspan=\"2\" title=\"Minimum value of function\">\n",
       "FCN = 10.39\n",
       "</td>\n",
       "<td align=\"center\" colspan=\"3\" title=\"No. of calls in last algorithm and total number of calls\">\n",
       "Ncalls = 29 (55 total)\n",
       "</td>\n",
       "</tr>\n",
       "<tr>\n",
       "<td colspan=\"2\" title=\"Estimated distance to minimum and target threshold\">\n",
       "EDM = 5.42e-15 (Goal: 0.0002)\n",
       "</td>\n",
       "<td align=\"center\" colspan=\"3\" title=\"Increase in FCN which corresponds to 1 standard deviation\">\n",
       "up = 1.0\n",
       "</td>\n",
       "</tr>\n",
       "<tr>\n",
       "<td align=\"center\" title=\"Validity of the migrad call\">\n",
       "Valid Min.\n",
       "</td>\n",
       "<td align=\"center\" title=\"Validity of parameters\">\n",
       "Valid Param.\n",
       "</td>\n",
       "<td align=\"center\" title=\"Is EDM above goal EDM?\">\n",
       "Above EDM\n",
       "</td>\n",
       "<td align=\"center\" colspan=\"2\" title=\"Did last migrad call reach max call limit?\">\n",
       "Reached call limit\n",
       "</td>\n",
       "</tr>\n",
       "<tr>\n",
       "<td align=\"center\" style=\"background-color:#92CCA6;\">\n",
       "True\n",
       "</td>\n",
       "<td align=\"center\" style=\"background-color:#92CCA6;\">\n",
       "True\n",
       "</td>\n",
       "<td align=\"center\" style=\"background-color:#92CCA6;\">\n",
       "False\n",
       "</td>\n",
       "<td align=\"center\" colspan=\"2\" style=\"background-color:#92CCA6;\">\n",
       "False\n",
       "</td>\n",
       "</tr>\n",
       "<tr>\n",
       "<td align=\"center\" title=\"Did Hesse fail?\">\n",
       "Hesse failed\n",
       "</td>\n",
       "<td align=\"center\" title=\"Has covariance matrix\">\n",
       "Has cov.\n",
       "</td>\n",
       "<td align=\"center\" title=\"Is covariance matrix accurate?\">\n",
       "Accurate\n",
       "</td>\n",
       "<td align=\"center\" title=\"Is covariance matrix positive definite?\">\n",
       "Pos. def.\n",
       "</td>\n",
       "<td align=\"center\" title=\"Was positive definiteness enforced by Minuit?\">\n",
       "Forced\n",
       "</td>\n",
       "</tr>\n",
       "<tr>\n",
       "<td align=\"center\" style=\"background-color:#92CCA6;\">\n",
       "False\n",
       "</td>\n",
       "<td align=\"center\" style=\"background-color:#92CCA6;\">\n",
       "True\n",
       "</td>\n",
       "<td align=\"center\" style=\"background-color:#92CCA6;\">\n",
       "True\n",
       "</td>\n",
       "<td align=\"center\" style=\"background-color:#92CCA6;\">\n",
       "True\n",
       "</td>\n",
       "<td align=\"center\" style=\"background-color:#92CCA6;\">\n",
       "False\n",
       "</td>\n",
       "</tr>\n",
       "</table>\n",
       "<table>\n",
       "<tr style=\"background-color:#F4F4F4;\">\n",
       "<td/>\n",
       "<th title=\"Variable name\">\n",
       "Name\n",
       "</th>\n",
       "<th title=\"Value of parameter\">\n",
       "Value\n",
       "</th>\n",
       "<th title=\"Hesse error\">\n",
       "Hesse Error\n",
       "</th>\n",
       "<th title=\"Minos lower error\">\n",
       "Minos Error-\n",
       "</th>\n",
       "<th title=\"Minos upper error\">\n",
       "Minos Error+\n",
       "</th>\n",
       "<th title=\"Lower limit of the parameter\">\n",
       "Limit-\n",
       "</th>\n",
       "<th title=\"Upper limit of the parameter\">\n",
       "Limit+\n",
       "</th>\n",
       "<th title=\"Is the parameter fixed in the fit\">\n",
       "Fixed\n",
       "</th>\n",
       "</tr>\n",
       "<tr style=\"background-color:#FFFFFF;\">\n",
       "<td>\n",
       "0\n",
       "</td>\n",
       "<td>\n",
       "a\n",
       "</td>\n",
       "<td>\n",
       "0.99\n",
       "</td>\n",
       "<td>\n",
       "0.06\n",
       "</td>\n",
       "<td>\n",
       "\n",
       "</td>\n",
       "<td>\n",
       "\n",
       "</td>\n",
       "<td>\n",
       "\n",
       "</td>\n",
       "<td>\n",
       "\n",
       "</td>\n",
       "<td>\n",
       "\n",
       "</td>\n",
       "</tr>\n",
       "<tr style=\"background-color:#F4F4F4;\">\n",
       "<td>\n",
       "1\n",
       "</td>\n",
       "<td>\n",
       "b\n",
       "</td>\n",
       "<td>\n",
       "1.94\n",
       "</td>\n",
       "<td>\n",
       "0.10\n",
       "</td>\n",
       "<td>\n",
       "\n",
       "</td>\n",
       "<td>\n",
       "\n",
       "</td>\n",
       "<td>\n",
       "\n",
       "</td>\n",
       "<td>\n",
       "\n",
       "</td>\n",
       "<td>\n",
       "\n",
       "</td>\n",
       "</tr>\n",
       "</table>\n"
      ],
      "text/plain": [
       "------------------------------------------------------------------\n",
       "| FCN = 10.39                   |      Ncalls=29 (55 total)      |\n",
       "| EDM = 5.42e-15 (Goal: 0.0002) |            up = 1.0            |\n",
       "------------------------------------------------------------------\n",
       "|  Valid Min.   | Valid Param.  | Above EDM | Reached call limit |\n",
       "------------------------------------------------------------------\n",
       "|     True      |     True      |   False   |       False        |\n",
       "------------------------------------------------------------------\n",
       "| Hesse failed  |   Has cov.    | Accurate  | Pos. def. | Forced |\n",
       "------------------------------------------------------------------\n",
       "|     False     |     True      |   True    |   True    | False  |\n",
       "------------------------------------------------------------------\n",
       "------------------------------------------------------------------------------------------\n",
       "|   | Name |   Value   | Hesse Err | Minos Err- | Minos Err+ | Limit-  | Limit+  | Fixed |\n",
       "------------------------------------------------------------------------------------------\n",
       "| 0 | a    |   0.99    |   0.06    |            |            |         |         |       |\n",
       "| 1 | b    |   1.94    |   0.10    |            |            |         |         |       |\n",
       "------------------------------------------------------------------------------------------"
      ]
     },
     "execution_count": 14,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "# convergence is slow in this case, let's release both parameters and minimize again\n",
    "for key in m.fixed:\n",
    "    m.fixed[key] = False\n",
    "m.migrad()"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "It is also possible and sometimes useful to change the values of some fixed parameters by hand and fit the others, or to restart the fit from another starting point. This can also be done."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 15,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/html": [
       "<table>\n",
       "<tr>\n",
       "<td colspan=\"2\" title=\"Minimum value of function\">\n",
       "FCN = 80.16\n",
       "</td>\n",
       "<td align=\"center\" colspan=\"3\" title=\"No. of calls in last algorithm and total number of calls\">\n",
       "Ncalls = 8 (63 total)\n",
       "</td>\n",
       "</tr>\n",
       "<tr>\n",
       "<td colspan=\"2\" title=\"Estimated distance to minimum and target threshold\">\n",
       "EDM = 2.12e-18 (Goal: 0.0002)\n",
       "</td>\n",
       "<td align=\"center\" colspan=\"3\" title=\"Increase in FCN which corresponds to 1 standard deviation\">\n",
       "up = 1.0\n",
       "</td>\n",
       "</tr>\n",
       "<tr>\n",
       "<td align=\"center\" title=\"Validity of the migrad call\">\n",
       "Valid Min.\n",
       "</td>\n",
       "<td align=\"center\" title=\"Validity of parameters\">\n",
       "Valid Param.\n",
       "</td>\n",
       "<td align=\"center\" title=\"Is EDM above goal EDM?\">\n",
       "Above EDM\n",
       "</td>\n",
       "<td align=\"center\" colspan=\"2\" title=\"Did last migrad call reach max call limit?\">\n",
       "Reached call limit\n",
       "</td>\n",
       "</tr>\n",
       "<tr>\n",
       "<td align=\"center\" style=\"background-color:#92CCA6;\">\n",
       "True\n",
       "</td>\n",
       "<td align=\"center\" style=\"background-color:#92CCA6;\">\n",
       "True\n",
       "</td>\n",
       "<td align=\"center\" style=\"background-color:#92CCA6;\">\n",
       "False\n",
       "</td>\n",
       "<td align=\"center\" colspan=\"2\" style=\"background-color:#92CCA6;\">\n",
       "False\n",
       "</td>\n",
       "</tr>\n",
       "<tr>\n",
       "<td align=\"center\" title=\"Did Hesse fail?\">\n",
       "Hesse failed\n",
       "</td>\n",
       "<td align=\"center\" title=\"Has covariance matrix\">\n",
       "Has cov.\n",
       "</td>\n",
       "<td align=\"center\" title=\"Is covariance matrix accurate?\">\n",
       "Accurate\n",
       "</td>\n",
       "<td align=\"center\" title=\"Is covariance matrix positive definite?\">\n",
       "Pos. def.\n",
       "</td>\n",
       "<td align=\"center\" title=\"Was positive definiteness enforced by Minuit?\">\n",
       "Forced\n",
       "</td>\n",
       "</tr>\n",
       "<tr>\n",
       "<td align=\"center\" style=\"background-color:#92CCA6;\">\n",
       "False\n",
       "</td>\n",
       "<td align=\"center\" style=\"background-color:#92CCA6;\">\n",
       "True\n",
       "</td>\n",
       "<td align=\"center\" style=\"background-color:#92CCA6;\">\n",
       "True\n",
       "</td>\n",
       "<td align=\"center\" style=\"background-color:#92CCA6;\">\n",
       "True\n",
       "</td>\n",
       "<td align=\"center\" style=\"background-color:#92CCA6;\">\n",
       "False\n",
       "</td>\n",
       "</tr>\n",
       "</table>\n",
       "<table>\n",
       "<tr style=\"background-color:#F4F4F4;\">\n",
       "<td/>\n",
       "<th title=\"Variable name\">\n",
       "Name\n",
       "</th>\n",
       "<th title=\"Value of parameter\">\n",
       "Value\n",
       "</th>\n",
       "<th title=\"Hesse error\">\n",
       "Hesse Error\n",
       "</th>\n",
       "<th title=\"Minos lower error\">\n",
       "Minos Error-\n",
       "</th>\n",
       "<th title=\"Minos upper error\">\n",
       "Minos Error+\n",
       "</th>\n",
       "<th title=\"Lower limit of the parameter\">\n",
       "Limit-\n",
       "</th>\n",
       "<th title=\"Upper limit of the parameter\">\n",
       "Limit+\n",
       "</th>\n",
       "<th title=\"Is the parameter fixed in the fit\">\n",
       "Fixed\n",
       "</th>\n",
       "</tr>\n",
       "<tr style=\"background-color:#FFFFFF;\">\n",
       "<td>\n",
       "0\n",
       "</td>\n",
       "<td>\n",
       "a\n",
       "</td>\n",
       "<td>\n",
       "0.50\n",
       "</td>\n",
       "<td>\n",
       "0.06\n",
       "</td>\n",
       "<td>\n",
       "\n",
       "</td>\n",
       "<td>\n",
       "\n",
       "</td>\n",
       "<td>\n",
       "\n",
       "</td>\n",
       "<td>\n",
       "\n",
       "</td>\n",
       "<td>\n",
       "yes\n",
       "</td>\n",
       "</tr>\n",
       "<tr style=\"background-color:#F4F4F4;\">\n",
       "<td>\n",
       "1\n",
       "</td>\n",
       "<td>\n",
       "b\n",
       "</td>\n",
       "<td>\n",
       "2.64\n",
       "</td>\n",
       "<td>\n",
       "0.05\n",
       "</td>\n",
       "<td>\n",
       "\n",
       "</td>\n",
       "<td>\n",
       "\n",
       "</td>\n",
       "<td>\n",
       "\n",
       "</td>\n",
       "<td>\n",
       "\n",
       "</td>\n",
       "<td>\n",
       "\n",
       "</td>\n",
       "</tr>\n",
       "</table>\n"
      ],
      "text/plain": [
       "------------------------------------------------------------------\n",
       "| FCN = 80.16                   |      Ncalls=8 (63 total)       |\n",
       "| EDM = 2.12e-18 (Goal: 0.0002) |            up = 1.0            |\n",
       "------------------------------------------------------------------\n",
       "|  Valid Min.   | Valid Param.  | Above EDM | Reached call limit |\n",
       "------------------------------------------------------------------\n",
       "|     True      |     True      |   False   |       False        |\n",
       "------------------------------------------------------------------\n",
       "| Hesse failed  |   Has cov.    | Accurate  | Pos. def. | Forced |\n",
       "------------------------------------------------------------------\n",
       "|     False     |     True      |   True    |   True    | False  |\n",
       "------------------------------------------------------------------\n",
       "------------------------------------------------------------------------------------------\n",
       "|   | Name |   Value   | Hesse Err | Minos Err- | Minos Err+ | Limit-  | Limit+  | Fixed |\n",
       "------------------------------------------------------------------------------------------\n",
       "| 0 | a    |   0.50    |   0.06    |            |            |         |         |  yes  |\n",
       "| 1 | b    |   2.64    |   0.05    |            |            |         |         |       |\n",
       "------------------------------------------------------------------------------------------"
      ]
     },
     "execution_count": 15,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "m.fixed[\"a\"] = True\n",
    "m.values[\"a\"] = 0.5\n",
    "m.migrad()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 16,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/html": [
       "<table>\n",
       "<tr>\n",
       "<td colspan=\"2\" title=\"Minimum value of function\">\n",
       "FCN = 10.41\n",
       "</td>\n",
       "<td align=\"center\" colspan=\"3\" title=\"No. of calls in last algorithm and total number of calls\">\n",
       "Ncalls = 8 (71 total)\n",
       "</td>\n",
       "</tr>\n",
       "<tr>\n",
       "<td colspan=\"2\" title=\"Estimated distance to minimum and target threshold\">\n",
       "EDM = 4.53e-23 (Goal: 0.0002)\n",
       "</td>\n",
       "<td align=\"center\" colspan=\"3\" title=\"Increase in FCN which corresponds to 1 standard deviation\">\n",
       "up = 1.0\n",
       "</td>\n",
       "</tr>\n",
       "<tr>\n",
       "<td align=\"center\" title=\"Validity of the migrad call\">\n",
       "Valid Min.\n",
       "</td>\n",
       "<td align=\"center\" title=\"Validity of parameters\">\n",
       "Valid Param.\n",
       "</td>\n",
       "<td align=\"center\" title=\"Is EDM above goal EDM?\">\n",
       "Above EDM\n",
       "</td>\n",
       "<td align=\"center\" colspan=\"2\" title=\"Did last migrad call reach max call limit?\">\n",
       "Reached call limit\n",
       "</td>\n",
       "</tr>\n",
       "<tr>\n",
       "<td align=\"center\" style=\"background-color:#92CCA6;\">\n",
       "True\n",
       "</td>\n",
       "<td align=\"center\" style=\"background-color:#92CCA6;\">\n",
       "True\n",
       "</td>\n",
       "<td align=\"center\" style=\"background-color:#92CCA6;\">\n",
       "False\n",
       "</td>\n",
       "<td align=\"center\" colspan=\"2\" style=\"background-color:#92CCA6;\">\n",
       "False\n",
       "</td>\n",
       "</tr>\n",
       "<tr>\n",
       "<td align=\"center\" title=\"Did Hesse fail?\">\n",
       "Hesse failed\n",
       "</td>\n",
       "<td align=\"center\" title=\"Has covariance matrix\">\n",
       "Has cov.\n",
       "</td>\n",
       "<td align=\"center\" title=\"Is covariance matrix accurate?\">\n",
       "Accurate\n",
       "</td>\n",
       "<td align=\"center\" title=\"Is covariance matrix positive definite?\">\n",
       "Pos. def.\n",
       "</td>\n",
       "<td align=\"center\" title=\"Was positive definiteness enforced by Minuit?\">\n",
       "Forced\n",
       "</td>\n",
       "</tr>\n",
       "<tr>\n",
       "<td align=\"center\" style=\"background-color:#92CCA6;\">\n",
       "False\n",
       "</td>\n",
       "<td align=\"center\" style=\"background-color:#92CCA6;\">\n",
       "True\n",
       "</td>\n",
       "<td align=\"center\" style=\"background-color:#92CCA6;\">\n",
       "True\n",
       "</td>\n",
       "<td align=\"center\" style=\"background-color:#92CCA6;\">\n",
       "True\n",
       "</td>\n",
       "<td align=\"center\" style=\"background-color:#92CCA6;\">\n",
       "False\n",
       "</td>\n",
       "</tr>\n",
       "</table>\n",
       "<table>\n",
       "<tr style=\"background-color:#F4F4F4;\">\n",
       "<td/>\n",
       "<th title=\"Variable name\">\n",
       "Name\n",
       "</th>\n",
       "<th title=\"Value of parameter\">\n",
       "Value\n",
       "</th>\n",
       "<th title=\"Hesse error\">\n",
       "Hesse Error\n",
       "</th>\n",
       "<th title=\"Minos lower error\">\n",
       "Minos Error-\n",
       "</th>\n",
       "<th title=\"Minos upper error\">\n",
       "Minos Error+\n",
       "</th>\n",
       "<th title=\"Lower limit of the parameter\">\n",
       "Limit-\n",
       "</th>\n",
       "<th title=\"Upper limit of the parameter\">\n",
       "Limit+\n",
       "</th>\n",
       "<th title=\"Is the parameter fixed in the fit\">\n",
       "Fixed\n",
       "</th>\n",
       "</tr>\n",
       "<tr style=\"background-color:#FFFFFF;\">\n",
       "<td>\n",
       "0\n",
       "</td>\n",
       "<td>\n",
       "a\n",
       "</td>\n",
       "<td>\n",
       "1.00\n",
       "</td>\n",
       "<td>\n",
       "0.06\n",
       "</td>\n",
       "<td>\n",
       "\n",
       "</td>\n",
       "<td>\n",
       "\n",
       "</td>\n",
       "<td>\n",
       "\n",
       "</td>\n",
       "<td>\n",
       "\n",
       "</td>\n",
       "<td>\n",
       "yes\n",
       "</td>\n",
       "</tr>\n",
       "<tr style=\"background-color:#F4F4F4;\">\n",
       "<td>\n",
       "1\n",
       "</td>\n",
       "<td>\n",
       "b\n",
       "</td>\n",
       "<td>\n",
       "1.93\n",
       "</td>\n",
       "<td>\n",
       "0.05\n",
       "</td>\n",
       "<td>\n",
       "\n",
       "</td>\n",
       "<td>\n",
       "\n",
       "</td>\n",
       "<td>\n",
       "\n",
       "</td>\n",
       "<td>\n",
       "\n",
       "</td>\n",
       "<td>\n",
       "\n",
       "</td>\n",
       "</tr>\n",
       "</table>\n"
      ],
      "text/plain": [
       "------------------------------------------------------------------\n",
       "| FCN = 10.41                   |      Ncalls=8 (71 total)       |\n",
       "| EDM = 4.53e-23 (Goal: 0.0002) |            up = 1.0            |\n",
       "------------------------------------------------------------------\n",
       "|  Valid Min.   | Valid Param.  | Above EDM | Reached call limit |\n",
       "------------------------------------------------------------------\n",
       "|     True      |     True      |   False   |       False        |\n",
       "------------------------------------------------------------------\n",
       "| Hesse failed  |   Has cov.    | Accurate  | Pos. def. | Forced |\n",
       "------------------------------------------------------------------\n",
       "|     False     |     True      |   True    |   True    | False  |\n",
       "------------------------------------------------------------------\n",
       "------------------------------------------------------------------------------------------\n",
       "|   | Name |   Value   | Hesse Err | Minos Err- | Minos Err+ | Limit-  | Limit+  | Fixed |\n",
       "------------------------------------------------------------------------------------------\n",
       "| 0 | a    |   1.00    |   0.06    |            |            |         |         |  yes  |\n",
       "| 1 | b    |   1.93    |   0.05    |            |            |         |         |       |\n",
       "------------------------------------------------------------------------------------------"
      ]
     },
     "execution_count": 16,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "m.values[\"a\"] = 1\n",
    "m.migrad()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 17,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/html": [
       "<table>\n",
       "<tr>\n",
       "<td colspan=\"2\" title=\"Minimum value of function\">\n",
       "FCN = 85.39\n",
       "</td>\n",
       "<td align=\"center\" colspan=\"3\" title=\"No. of calls in last algorithm and total number of calls\">\n",
       "Ncalls = 6 (77 total)\n",
       "</td>\n",
       "</tr>\n",
       "<tr>\n",
       "<td colspan=\"2\" title=\"Estimated distance to minimum and target threshold\">\n",
       "EDM = 1.04e-22 (Goal: 0.0002)\n",
       "</td>\n",
       "<td align=\"center\" colspan=\"3\" title=\"Increase in FCN which corresponds to 1 standard deviation\">\n",
       "up = 1.0\n",
       "</td>\n",
       "</tr>\n",
       "<tr>\n",
       "<td align=\"center\" title=\"Validity of the migrad call\">\n",
       "Valid Min.\n",
       "</td>\n",
       "<td align=\"center\" title=\"Validity of parameters\">\n",
       "Valid Param.\n",
       "</td>\n",
       "<td align=\"center\" title=\"Is EDM above goal EDM?\">\n",
       "Above EDM\n",
       "</td>\n",
       "<td align=\"center\" colspan=\"2\" title=\"Did last migrad call reach max call limit?\">\n",
       "Reached call limit\n",
       "</td>\n",
       "</tr>\n",
       "<tr>\n",
       "<td align=\"center\" style=\"background-color:#92CCA6;\">\n",
       "True\n",
       "</td>\n",
       "<td align=\"center\" style=\"background-color:#92CCA6;\">\n",
       "True\n",
       "</td>\n",
       "<td align=\"center\" style=\"background-color:#92CCA6;\">\n",
       "False\n",
       "</td>\n",
       "<td align=\"center\" colspan=\"2\" style=\"background-color:#92CCA6;\">\n",
       "False\n",
       "</td>\n",
       "</tr>\n",
       "<tr>\n",
       "<td align=\"center\" title=\"Did Hesse fail?\">\n",
       "Hesse failed\n",
       "</td>\n",
       "<td align=\"center\" title=\"Has covariance matrix\">\n",
       "Has cov.\n",
       "</td>\n",
       "<td align=\"center\" title=\"Is covariance matrix accurate?\">\n",
       "Accurate\n",
       "</td>\n",
       "<td align=\"center\" title=\"Is covariance matrix positive definite?\">\n",
       "Pos. def.\n",
       "</td>\n",
       "<td align=\"center\" title=\"Was positive definiteness enforced by Minuit?\">\n",
       "Forced\n",
       "</td>\n",
       "</tr>\n",
       "<tr>\n",
       "<td align=\"center\" style=\"background-color:#92CCA6;\">\n",
       "False\n",
       "</td>\n",
       "<td align=\"center\" style=\"background-color:#92CCA6;\">\n",
       "True\n",
       "</td>\n",
       "<td align=\"center\" style=\"background-color:#92CCA6;\">\n",
       "True\n",
       "</td>\n",
       "<td align=\"center\" style=\"background-color:#92CCA6;\">\n",
       "True\n",
       "</td>\n",
       "<td align=\"center\" style=\"background-color:#92CCA6;\">\n",
       "False\n",
       "</td>\n",
       "</tr>\n",
       "</table>\n",
       "<table>\n",
       "<tr style=\"background-color:#F4F4F4;\">\n",
       "<td/>\n",
       "<th title=\"Variable name\">\n",
       "Name\n",
       "</th>\n",
       "<th title=\"Value of parameter\">\n",
       "Value\n",
       "</th>\n",
       "<th title=\"Hesse error\">\n",
       "Hesse Error\n",
       "</th>\n",
       "<th title=\"Minos lower error\">\n",
       "Minos Error-\n",
       "</th>\n",
       "<th title=\"Minos upper error\">\n",
       "Minos Error+\n",
       "</th>\n",
       "<th title=\"Lower limit of the parameter\">\n",
       "Limit-\n",
       "</th>\n",
       "<th title=\"Upper limit of the parameter\">\n",
       "Limit+\n",
       "</th>\n",
       "<th title=\"Is the parameter fixed in the fit\">\n",
       "Fixed\n",
       "</th>\n",
       "</tr>\n",
       "<tr style=\"background-color:#FFFFFF;\">\n",
       "<td>\n",
       "0\n",
       "</td>\n",
       "<td>\n",
       "a\n",
       "</td>\n",
       "<td>\n",
       "1.50\n",
       "</td>\n",
       "<td>\n",
       "0.06\n",
       "</td>\n",
       "<td>\n",
       "\n",
       "</td>\n",
       "<td>\n",
       "\n",
       "</td>\n",
       "<td>\n",
       "\n",
       "</td>\n",
       "<td>\n",
       "\n",
       "</td>\n",
       "<td>\n",
       "yes\n",
       "</td>\n",
       "</tr>\n",
       "<tr style=\"background-color:#F4F4F4;\">\n",
       "<td>\n",
       "1\n",
       "</td>\n",
       "<td>\n",
       "b\n",
       "</td>\n",
       "<td>\n",
       "1.22\n",
       "</td>\n",
       "<td>\n",
       "0.05\n",
       "</td>\n",
       "<td>\n",
       "\n",
       "</td>\n",
       "<td>\n",
       "\n",
       "</td>\n",
       "<td>\n",
       "\n",
       "</td>\n",
       "<td>\n",
       "\n",
       "</td>\n",
       "<td>\n",
       "\n",
       "</td>\n",
       "</tr>\n",
       "</table>\n"
      ],
      "text/plain": [
       "------------------------------------------------------------------\n",
       "| FCN = 85.39                   |      Ncalls=6 (77 total)       |\n",
       "| EDM = 1.04e-22 (Goal: 0.0002) |            up = 1.0            |\n",
       "------------------------------------------------------------------\n",
       "|  Valid Min.   | Valid Param.  | Above EDM | Reached call limit |\n",
       "------------------------------------------------------------------\n",
       "|     True      |     True      |   False   |       False        |\n",
       "------------------------------------------------------------------\n",
       "| Hesse failed  |   Has cov.    | Accurate  | Pos. def. | Forced |\n",
       "------------------------------------------------------------------\n",
       "|     False     |     True      |   True    |   True    | False  |\n",
       "------------------------------------------------------------------\n",
       "------------------------------------------------------------------------------------------\n",
       "|   | Name |   Value   | Hesse Err | Minos Err- | Minos Err+ | Limit-  | Limit+  | Fixed |\n",
       "------------------------------------------------------------------------------------------\n",
       "| 0 | a    |   1.50    |   0.06    |            |            |         |         |  yes  |\n",
       "| 1 | b    |   1.22    |   0.05    |            |            |         |         |       |\n",
       "------------------------------------------------------------------------------------------"
      ]
     },
     "execution_count": 17,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "m.values[\"a\"] = 1.5\n",
    "m.migrad()"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### Initial step sizes\n",
    "\n",
    "Minuit uses a gradient-descent method to find the minimum and the gradient is computed numerically using finite differences. The initial step size is used to compute the first gradient. A good step size is small compared to the curvature of the function, but large compared to numerical resolution. Using a good step size can slightly accelerate the convergence, but Minuit is not very sensitive to the choice. If you don't provide a value, iminuit will guess a step size based on a heuristic.\n",
    "\n",
    "You can set initital step sizes with keywords, `error_<name> = <step size>`. Using an appropriate step size is important when you have you a parameter which has physical bounds. Varying the initial parameter value by the step size may not create a situation where the parameter goes outside of its bounds. For example, a parameter $x$ with $x > 0$ and initital value $0.1$ may not have a step size of $0.2$.\n",
    "\n",
    "In our example, we could use an initital step size of $\\Delta a = \\Delta b = 0.1$."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 18,
   "metadata": {},
   "outputs": [],
   "source": [
    "m = Minuit(least_squares, a=5, b=5, error_a=0.1, error_b=0.1, errordef=Minuit.LEAST_SQUARES)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### Override paramater name detection\n",
    "\n",
    "iminuit tries hard to find out the parameter names and is pretty good at it. For example, if you pass a functor instead of a function, it will use the arguments of the `__call__` method, automatically skipping `self`.\n",
    "\n",
    "To see which parameter names iminuit finds for your function, use the `describe` function, like so:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 19,
   "metadata": {},
   "outputs": [],
   "source": [
    "from iminuit import describe\n",
    "\n",
    "def foo(x, y, z): pass\n",
    "assert describe(foo) == ['x', 'y', 'z']\n",
    "\n",
    "class Foo:\n",
    "    def __call__(self, a, b):\n",
    "        pass\n",
    "\n",
    "assert describe(Foo()) == ['a', 'b']"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "This works very well, but for some functions, the parameter names cannot be determined. For example, functions which accept a variable number of arguments."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 20,
   "metadata": {},
   "outputs": [
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "Traceback (most recent call last):\n",
      "  File \"<ipython-input-20-467b3a978ace>\", line 5, in <module>\n",
      "    describe(bar)  # this will raise a TypeError\n",
      "  File \"/Users/hdembinski/Extern/iminuit/src/iminuit/util.py\", line 404, in describe\n",
      "    raise TypeError(\"Unable to obtain function signature\")\n",
      "TypeError: Unable to obtain function signature\n"
     ]
    }
   ],
   "source": [
    "def bar(*args):  # function with variable number of arguments\n",
    "    return np.sum((np.array(args) - 1) ** 2)\n",
    "\n",
    "try:\n",
    "    describe(bar)  # this will raise a TypeError\n",
    "except TypeError as e:\n",
    "    import traceback as tb\n",
    "    tb.print_exc()"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "A `TypeError` is raised, because `describe` cannot detect the number and names of the parameters in this case. If you work with functions that accept a variable number of arguments a lot, we recommend to use vectorized functions, as explained in the next section.\n",
    "\n",
    "When iminuit cannot detect the arguments, but you know how many arguments there are, or if you simply want to override the names found by iminuit, you can do that with the keyword `forced_parameters`, like so:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 21,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/html": [
       "<table>\n",
       "<tr>\n",
       "<td colspan=\"2\" title=\"Minimum value of function\">\n",
       "FCN = 2.867e-19\n",
       "</td>\n",
       "<td align=\"center\" colspan=\"3\" title=\"No. of calls in last algorithm and total number of calls\">\n",
       "Ncalls = 24 (24 total)\n",
       "</td>\n",
       "</tr>\n",
       "<tr>\n",
       "<td colspan=\"2\" title=\"Estimated distance to minimum and target threshold\">\n",
       "EDM = 2.87e-19 (Goal: 0.0002)\n",
       "</td>\n",
       "<td align=\"center\" colspan=\"3\" title=\"Increase in FCN which corresponds to 1 standard deviation\">\n",
       "up = 1.0\n",
       "</td>\n",
       "</tr>\n",
       "<tr>\n",
       "<td align=\"center\" title=\"Validity of the migrad call\">\n",
       "Valid Min.\n",
       "</td>\n",
       "<td align=\"center\" title=\"Validity of parameters\">\n",
       "Valid Param.\n",
       "</td>\n",
       "<td align=\"center\" title=\"Is EDM above goal EDM?\">\n",
       "Above EDM\n",
       "</td>\n",
       "<td align=\"center\" colspan=\"2\" title=\"Did last migrad call reach max call limit?\">\n",
       "Reached call limit\n",
       "</td>\n",
       "</tr>\n",
       "<tr>\n",
       "<td align=\"center\" style=\"background-color:#92CCA6;\">\n",
       "True\n",
       "</td>\n",
       "<td align=\"center\" style=\"background-color:#92CCA6;\">\n",
       "True\n",
       "</td>\n",
       "<td align=\"center\" style=\"background-color:#92CCA6;\">\n",
       "False\n",
       "</td>\n",
       "<td align=\"center\" colspan=\"2\" style=\"background-color:#92CCA6;\">\n",
       "False\n",
       "</td>\n",
       "</tr>\n",
       "<tr>\n",
       "<td align=\"center\" title=\"Did Hesse fail?\">\n",
       "Hesse failed\n",
       "</td>\n",
       "<td align=\"center\" title=\"Has covariance matrix\">\n",
       "Has cov.\n",
       "</td>\n",
       "<td align=\"center\" title=\"Is covariance matrix accurate?\">\n",
       "Accurate\n",
       "</td>\n",
       "<td align=\"center\" title=\"Is covariance matrix positive definite?\">\n",
       "Pos. def.\n",
       "</td>\n",
       "<td align=\"center\" title=\"Was positive definiteness enforced by Minuit?\">\n",
       "Forced\n",
       "</td>\n",
       "</tr>\n",
       "<tr>\n",
       "<td align=\"center\" style=\"background-color:#92CCA6;\">\n",
       "False\n",
       "</td>\n",
       "<td align=\"center\" style=\"background-color:#92CCA6;\">\n",
       "True\n",
       "</td>\n",
       "<td align=\"center\" style=\"background-color:#92CCA6;\">\n",
       "True\n",
       "</td>\n",
       "<td align=\"center\" style=\"background-color:#92CCA6;\">\n",
       "True\n",
       "</td>\n",
       "<td align=\"center\" style=\"background-color:#92CCA6;\">\n",
       "False\n",
       "</td>\n",
       "</tr>\n",
       "</table>\n",
       "<table>\n",
       "<tr style=\"background-color:#F4F4F4;\">\n",
       "<td/>\n",
       "<th title=\"Variable name\">\n",
       "Name\n",
       "</th>\n",
       "<th title=\"Value of parameter\">\n",
       "Value\n",
       "</th>\n",
       "<th title=\"Hesse error\">\n",
       "Hesse Error\n",
       "</th>\n",
       "<th title=\"Minos lower error\">\n",
       "Minos Error-\n",
       "</th>\n",
       "<th title=\"Minos upper error\">\n",
       "Minos Error+\n",
       "</th>\n",
       "<th title=\"Lower limit of the parameter\">\n",
       "Limit-\n",
       "</th>\n",
       "<th title=\"Upper limit of the parameter\">\n",
       "Limit+\n",
       "</th>\n",
       "<th title=\"Is the parameter fixed in the fit\">\n",
       "Fixed\n",
       "</th>\n",
       "</tr>\n",
       "<tr style=\"background-color:#FFFFFF;\">\n",
       "<td>\n",
       "0\n",
       "</td>\n",
       "<td>\n",
       "a\n",
       "</td>\n",
       "<td>\n",
       "1\n",
       "</td>\n",
       "<td>\n",
       "1\n",
       "</td>\n",
       "<td>\n",
       "\n",
       "</td>\n",
       "<td>\n",
       "\n",
       "</td>\n",
       "<td>\n",
       "\n",
       "</td>\n",
       "<td>\n",
       "\n",
       "</td>\n",
       "<td>\n",
       "\n",
       "</td>\n",
       "</tr>\n",
       "<tr style=\"background-color:#F4F4F4;\">\n",
       "<td>\n",
       "1\n",
       "</td>\n",
       "<td>\n",
       "b\n",
       "</td>\n",
       "<td>\n",
       "1\n",
       "</td>\n",
       "<td>\n",
       "1\n",
       "</td>\n",
       "<td>\n",
       "\n",
       "</td>\n",
       "<td>\n",
       "\n",
       "</td>\n",
       "<td>\n",
       "\n",
       "</td>\n",
       "<td>\n",
       "\n",
       "</td>\n",
       "<td>\n",
       "\n",
       "</td>\n",
       "</tr>\n",
       "</table>\n"
      ],
      "text/plain": [
       "------------------------------------------------------------------\n",
       "| FCN = 2.867e-19               |      Ncalls=24 (24 total)      |\n",
       "| EDM = 2.87e-19 (Goal: 0.0002) |            up = 1.0            |\n",
       "------------------------------------------------------------------\n",
       "|  Valid Min.   | Valid Param.  | Above EDM | Reached call limit |\n",
       "------------------------------------------------------------------\n",
       "|     True      |     True      |   False   |       False        |\n",
       "------------------------------------------------------------------\n",
       "| Hesse failed  |   Has cov.    | Accurate  | Pos. def. | Forced |\n",
       "------------------------------------------------------------------\n",
       "|     False     |     True      |   True    |   True    | False  |\n",
       "------------------------------------------------------------------\n",
       "------------------------------------------------------------------------------------------\n",
       "|   | Name |   Value   | Hesse Err | Minos Err- | Minos Err+ | Limit-  | Limit+  | Fixed |\n",
       "------------------------------------------------------------------------------------------\n",
       "| 0 | a    |     1     |     1     |            |            |         |         |       |\n",
       "| 1 | b    |     1     |     1     |            |            |         |         |       |\n",
       "------------------------------------------------------------------------------------------"
      ]
     },
     "execution_count": 21,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "m = Minuit(bar, forced_parameters=('a', 'b'), a=1, b=2, pedantic=False)\n",
    "m.migrad()"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### Alternative: Vectorized functions\n",
    "\n",
    "You can also use iminuit with functions that accept numpy arrays. This has pros and cons.\n",
    "\n",
    "**Pros**\n",
    "- Easy to change number of fitted parameters\n",
    "- Sometimes simpler function body that's easier to read\n",
    "- Technically more efficient, although this is probably not noticable unless you have >100 parameters\n",
    "\n",
    "**Cons**\n",
    "- iminuit cannot figure out names for each parameter\n",
    "\n",
    "Let's take the original `least_squares` function and write a vectorized version:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 22,
   "metadata": {},
   "outputs": [],
   "source": [
    "import numpy as np\n",
    "\n",
    "def least_squares_np(par):  # par is a numpy array here \n",
    "    mu = np.polyval(par, data_x)  # for par = (a, b) this is a line\n",
    "    yvar = 0.01\n",
    "    return np.sum((data_y - mu) ** 2 / yvar)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "`least_square(a, b)` and `least_squares_np(par)` are alternative implementations of the same mathematical function, if the latter is called with two arguments. In contrast to `least_squares`, `least_squares_np` can also be called with fewer or more arguments, using a polynomial of the corresponding order predict the behavior of the data. This will come in handy. \n",
    "\n",
    "To pass a numpy function, create a Minuit object with the method `Minuit.from_array_func`. Using the function `least_squares_np(par)` described above as an example, the call looks like this:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 23,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/html": [
       "<table>\n",
       "<tr style=\"background-color:#F4F4F4;\">\n",
       "<td/>\n",
       "<th title=\"Variable name\">\n",
       "Name\n",
       "</th>\n",
       "<th title=\"Value of parameter\">\n",
       "Value\n",
       "</th>\n",
       "<th title=\"Hesse error\">\n",
       "Hesse Error\n",
       "</th>\n",
       "<th title=\"Minos lower error\">\n",
       "Minos Error-\n",
       "</th>\n",
       "<th title=\"Minos upper error\">\n",
       "Minos Error+\n",
       "</th>\n",
       "<th title=\"Lower limit of the parameter\">\n",
       "Limit-\n",
       "</th>\n",
       "<th title=\"Upper limit of the parameter\">\n",
       "Limit+\n",
       "</th>\n",
       "<th title=\"Is the parameter fixed in the fit\">\n",
       "Fixed\n",
       "</th>\n",
       "</tr>\n",
       "<tr style=\"background-color:#FFFFFF;\">\n",
       "<td>\n",
       "0\n",
       "</td>\n",
       "<td>\n",
       "x0\n",
       "</td>\n",
       "<td>\n",
       "5.0\n",
       "</td>\n",
       "<td>\n",
       "0.1\n",
       "</td>\n",
       "<td>\n",
       "\n",
       "</td>\n",
       "<td>\n",
       "\n",
       "</td>\n",
       "<td>\n",
       "\n",
       "</td>\n",
       "<td>\n",
       "\n",
       "</td>\n",
       "<td>\n",
       "\n",
       "</td>\n",
       "</tr>\n",
       "<tr style=\"background-color:#F4F4F4;\">\n",
       "<td>\n",
       "1\n",
       "</td>\n",
       "<td>\n",
       "x1\n",
       "</td>\n",
       "<td>\n",
       "5.0\n",
       "</td>\n",
       "<td>\n",
       "0.1\n",
       "</td>\n",
       "<td>\n",
       "\n",
       "</td>\n",
       "<td>\n",
       "\n",
       "</td>\n",
       "<td>\n",
       "\n",
       "</td>\n",
       "<td>\n",
       "\n",
       "</td>\n",
       "<td>\n",
       "\n",
       "</td>\n",
       "</tr>\n",
       "</table>\n"
      ],
      "text/plain": [
       "------------------------------------------------------------------------------------------\n",
       "|   | Name |   Value   | Hesse Err | Minos Err- | Minos Err+ | Limit-  | Limit+  | Fixed |\n",
       "------------------------------------------------------------------------------------------\n",
       "| 0 | x0   |    5.0    |    0.1    |            |            |         |         |       |\n",
       "| 1 | x1   |    5.0    |    0.1    |            |            |         |         |       |\n",
       "------------------------------------------------------------------------------------------"
      ]
     },
     "execution_count": 23,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "m = Minuit.from_array_func(least_squares_np, (5, 5), error=(0.1, 0.1), errordef=1)\n",
    "m.params"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "The first argument after the function is the starting point, which you provide as a sequence here. iminuit uses the length of this sequence to detect how many parameters your function has. As before you can use the keywords `error`, `limit`, and `fix`, to set initial step sizes, parameter limits, and fix parameters. These must be sequences with the same length as the starting point. For `error` and `limit`, it is also allowed to give a single step size or a single limit, which is then used for all parameters.\n",
    "\n",
    "By default, the parameters are named automatically `x0` to `xN`. You can override this with the keyword `name`, passing a sequence of parameter names, like so: "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 24,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/html": [
       "<table>\n",
       "<tr style=\"background-color:#F4F4F4;\">\n",
       "<td/>\n",
       "<th title=\"Variable name\">\n",
       "Name\n",
       "</th>\n",
       "<th title=\"Value of parameter\">\n",
       "Value\n",
       "</th>\n",
       "<th title=\"Hesse error\">\n",
       "Hesse Error\n",
       "</th>\n",
       "<th title=\"Minos lower error\">\n",
       "Minos Error-\n",
       "</th>\n",
       "<th title=\"Minos upper error\">\n",
       "Minos Error+\n",
       "</th>\n",
       "<th title=\"Lower limit of the parameter\">\n",
       "Limit-\n",
       "</th>\n",
       "<th title=\"Upper limit of the parameter\">\n",
       "Limit+\n",
       "</th>\n",
       "<th title=\"Is the parameter fixed in the fit\">\n",
       "Fixed\n",
       "</th>\n",
       "</tr>\n",
       "<tr style=\"background-color:#FFFFFF;\">\n",
       "<td>\n",
       "0\n",
       "</td>\n",
       "<td>\n",
       "a\n",
       "</td>\n",
       "<td>\n",
       "5.0\n",
       "</td>\n",
       "<td>\n",
       "0.1\n",
       "</td>\n",
       "<td>\n",
       "\n",
       "</td>\n",
       "<td>\n",
       "\n",
       "</td>\n",
       "<td>\n",
       "0\n",
       "</td>\n",
       "<td>\n",
       "\n",
       "</td>\n",
       "<td>\n",
       "yes\n",
       "</td>\n",
       "</tr>\n",
       "<tr style=\"background-color:#F4F4F4;\">\n",
       "<td>\n",
       "1\n",
       "</td>\n",
       "<td>\n",
       "b\n",
       "</td>\n",
       "<td>\n",
       "5.0\n",
       "</td>\n",
       "<td>\n",
       "0.1\n",
       "</td>\n",
       "<td>\n",
       "\n",
       "</td>\n",
       "<td>\n",
       "\n",
       "</td>\n",
       "<td>\n",
       "0\n",
       "</td>\n",
       "<td>\n",
       "10\n",
       "</td>\n",
       "<td>\n",
       "\n",
       "</td>\n",
       "</tr>\n",
       "</table>\n"
      ],
      "text/plain": [
       "------------------------------------------------------------------------------------------\n",
       "|   | Name |   Value   | Hesse Err | Minos Err- | Minos Err+ | Limit-  | Limit+  | Fixed |\n",
       "------------------------------------------------------------------------------------------\n",
       "| 0 | a    |    5.0    |    0.1    |            |            |    0    |         |  yes  |\n",
       "| 1 | b    |    5.0    |    0.1    |            |            |    0    |   10    |       |\n",
       "------------------------------------------------------------------------------------------"
      ]
     },
     "execution_count": 24,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "m = Minuit.from_array_func(least_squares_np, (5, 5), error=(0.1, 0.1), fix=(True, False),\n",
    "                           limit=((0, None), (0, 10)),\n",
    "                           name=(\"a\", \"b\"), errordef=1)\n",
    "m.params"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Since `least_squares_np(par)` works for numpy arrays of any length, you can easily change the number of fitted parameters by changing the length of the starting array, like so:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 25,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/html": [
       "<table>\n",
       "<tr style=\"background-color:#F4F4F4;\">\n",
       "<td/>\n",
       "<th title=\"Variable name\">\n",
       "Name\n",
       "</th>\n",
       "<th title=\"Value of parameter\">\n",
       "Value\n",
       "</th>\n",
       "<th title=\"Hesse error\">\n",
       "Hesse Error\n",
       "</th>\n",
       "<th title=\"Minos lower error\">\n",
       "Minos Error-\n",
       "</th>\n",
       "<th title=\"Minos upper error\">\n",
       "Minos Error+\n",
       "</th>\n",
       "<th title=\"Lower limit of the parameter\">\n",
       "Limit-\n",
       "</th>\n",
       "<th title=\"Upper limit of the parameter\">\n",
       "Limit+\n",
       "</th>\n",
       "<th title=\"Is the parameter fixed in the fit\">\n",
       "Fixed\n",
       "</th>\n",
       "</tr>\n",
       "<tr style=\"background-color:#FFFFFF;\">\n",
       "<td>\n",
       "0\n",
       "</td>\n",
       "<td>\n",
       "x0\n",
       "</td>\n",
       "<td>\n",
       "5.0\n",
       "</td>\n",
       "<td>\n",
       "0.1\n",
       "</td>\n",
       "<td>\n",
       "\n",
       "</td>\n",
       "<td>\n",
       "\n",
       "</td>\n",
       "<td>\n",
       "\n",
       "</td>\n",
       "<td>\n",
       "\n",
       "</td>\n",
       "<td>\n",
       "\n",
       "</td>\n",
       "</tr>\n",
       "<tr style=\"background-color:#F4F4F4;\">\n",
       "<td>\n",
       "1\n",
       "</td>\n",
       "<td>\n",
       "x1\n",
       "</td>\n",
       "<td>\n",
       "5.0\n",
       "</td>\n",
       "<td>\n",
       "0.1\n",
       "</td>\n",
       "<td>\n",
       "\n",
       "</td>\n",
       "<td>\n",
       "\n",
       "</td>\n",
       "<td>\n",
       "\n",
       "</td>\n",
       "<td>\n",
       "\n",
       "</td>\n",
       "<td>\n",
       "\n",
       "</td>\n",
       "</tr>\n",
       "<tr style=\"background-color:#FFFFFF;\">\n",
       "<td>\n",
       "2\n",
       "</td>\n",
       "<td>\n",
       "x2\n",
       "</td>\n",
       "<td>\n",
       "5.0\n",
       "</td>\n",
       "<td>\n",
       "0.1\n",
       "</td>\n",
       "<td>\n",
       "\n",
       "</td>\n",
       "<td>\n",
       "\n",
       "</td>\n",
       "<td>\n",
       "\n",
       "</td>\n",
       "<td>\n",
       "\n",
       "</td>\n",
       "<td>\n",
       "\n",
       "</td>\n",
       "</tr>\n",
       "<tr style=\"background-color:#F4F4F4;\">\n",
       "<td>\n",
       "3\n",
       "</td>\n",
       "<td>\n",
       "x3\n",
       "</td>\n",
       "<td>\n",
       "5.0\n",
       "</td>\n",
       "<td>\n",
       "0.1\n",
       "</td>\n",
       "<td>\n",
       "\n",
       "</td>\n",
       "<td>\n",
       "\n",
       "</td>\n",
       "<td>\n",
       "\n",
       "</td>\n",
       "<td>\n",
       "\n",
       "</td>\n",
       "<td>\n",
       "\n",
       "</td>\n",
       "</tr>\n",
       "</table>\n"
      ],
      "text/plain": [
       "------------------------------------------------------------------------------------------\n",
       "|   | Name |   Value   | Hesse Err | Minos Err- | Minos Err+ | Limit-  | Limit+  | Fixed |\n",
       "------------------------------------------------------------------------------------------\n",
       "| 0 | x0   |    5.0    |    0.1    |            |            |         |         |       |\n",
       "| 1 | x1   |    5.0    |    0.1    |            |            |         |         |       |\n",
       "| 2 | x2   |    5.0    |    0.1    |            |            |         |         |       |\n",
       "| 3 | x3   |    5.0    |    0.1    |            |            |         |         |       |\n",
       "------------------------------------------------------------------------------------------"
      ]
     },
     "execution_count": 25,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "m = Minuit.from_array_func(least_squares_np, (5, 5, 5, 5), error=0.1, errordef=1)\n",
    "m.params"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "This is useful when you fit a polynomial to parametrize some data and you want to try different orders of the polynomial. If the order is too small, the polynomial will not follow the data. If it is too large, you will overfit the data and polynomial will pick up random fluctuations and not the underlying trend. You can figure out the right order by experimenting or using an algorithm like cross-validation.\n",
    "\n",
    "If you are very familiar with numpy and scipy, you may find the `minimize` function useful. It exactly mimics the function interface of `scipy.optimize.minimize`, but uses `Minuit` for the actual minimization. You need to have `scipy` installed to use it."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 26,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "      fun: 10.387011251394046\n",
       " hess_inv: array([[ 0.00490909, -0.00245455],\n",
       "       [-0.00245455,  0.00172727]])\n",
       "  message: 'Optimization terminated successfully.'\n",
       "   minuit: <iminuit._libiminuit.Minuit object at 0x7febbf866bb0>\n",
       "     nfev: 36\n",
       "     njev: 0\n",
       "  success: True\n",
       "        x: array([1.9449447 , 0.99096644])"
      ]
     },
     "execution_count": 26,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "from iminuit import minimize  # has same interface as scipy.optimize.minimize\n",
    "minimize(least_squares_np, (5, 5))"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Minimize the function\n",
    "\n",
    "To run the actual minimization, you call the `Minuit.migrad()` method. Migrad performs Variable-Metric Minimization. It combines a steepest-descends algorithm along with line search strategy. Migrad is very popular in high energy physics field because of its robustness."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 27,
   "metadata": {
    "scrolled": true
   },
   "outputs": [
    {
     "data": {
      "text/html": [
       "<table>\n",
       "<tr>\n",
       "<td colspan=\"2\" title=\"Minimum value of function\">\n",
       "FCN = 10.39\n",
       "</td>\n",
       "<td align=\"center\" colspan=\"3\" title=\"No. of calls in last algorithm and total number of calls\">\n",
       "Ncalls = 32 (32 total)\n",
       "</td>\n",
       "</tr>\n",
       "<tr>\n",
       "<td colspan=\"2\" title=\"Estimated distance to minimum and target threshold\">\n",
       "EDM = 7.24e-23 (Goal: 0.0002)\n",
       "</td>\n",
       "<td align=\"center\" colspan=\"3\" title=\"Increase in FCN which corresponds to 1 standard deviation\">\n",
       "up = 1.0\n",
       "</td>\n",
       "</tr>\n",
       "<tr>\n",
       "<td align=\"center\" title=\"Validity of the migrad call\">\n",
       "Valid Min.\n",
       "</td>\n",
       "<td align=\"center\" title=\"Validity of parameters\">\n",
       "Valid Param.\n",
       "</td>\n",
       "<td align=\"center\" title=\"Is EDM above goal EDM?\">\n",
       "Above EDM\n",
       "</td>\n",
       "<td align=\"center\" colspan=\"2\" title=\"Did last migrad call reach max call limit?\">\n",
       "Reached call limit\n",
       "</td>\n",
       "</tr>\n",
       "<tr>\n",
       "<td align=\"center\" style=\"background-color:#92CCA6;\">\n",
       "True\n",
       "</td>\n",
       "<td align=\"center\" style=\"background-color:#92CCA6;\">\n",
       "True\n",
       "</td>\n",
       "<td align=\"center\" style=\"background-color:#92CCA6;\">\n",
       "False\n",
       "</td>\n",
       "<td align=\"center\" colspan=\"2\" style=\"background-color:#92CCA6;\">\n",
       "False\n",
       "</td>\n",
       "</tr>\n",
       "<tr>\n",
       "<td align=\"center\" title=\"Did Hesse fail?\">\n",
       "Hesse failed\n",
       "</td>\n",
       "<td align=\"center\" title=\"Has covariance matrix\">\n",
       "Has cov.\n",
       "</td>\n",
       "<td align=\"center\" title=\"Is covariance matrix accurate?\">\n",
       "Accurate\n",
       "</td>\n",
       "<td align=\"center\" title=\"Is covariance matrix positive definite?\">\n",
       "Pos. def.\n",
       "</td>\n",
       "<td align=\"center\" title=\"Was positive definiteness enforced by Minuit?\">\n",
       "Forced\n",
       "</td>\n",
       "</tr>\n",
       "<tr>\n",
       "<td align=\"center\" style=\"background-color:#92CCA6;\">\n",
       "False\n",
       "</td>\n",
       "<td align=\"center\" style=\"background-color:#92CCA6;\">\n",
       "True\n",
       "</td>\n",
       "<td align=\"center\" style=\"background-color:#92CCA6;\">\n",
       "True\n",
       "</td>\n",
       "<td align=\"center\" style=\"background-color:#92CCA6;\">\n",
       "True\n",
       "</td>\n",
       "<td align=\"center\" style=\"background-color:#92CCA6;\">\n",
       "False\n",
       "</td>\n",
       "</tr>\n",
       "</table>\n",
       "<table>\n",
       "<tr style=\"background-color:#F4F4F4;\">\n",
       "<td/>\n",
       "<th title=\"Variable name\">\n",
       "Name\n",
       "</th>\n",
       "<th title=\"Value of parameter\">\n",
       "Value\n",
       "</th>\n",
       "<th title=\"Hesse error\">\n",
       "Hesse Error\n",
       "</th>\n",
       "<th title=\"Minos lower error\">\n",
       "Minos Error-\n",
       "</th>\n",
       "<th title=\"Minos upper error\">\n",
       "Minos Error+\n",
       "</th>\n",
       "<th title=\"Lower limit of the parameter\">\n",
       "Limit-\n",
       "</th>\n",
       "<th title=\"Upper limit of the parameter\">\n",
       "Limit+\n",
       "</th>\n",
       "<th title=\"Is the parameter fixed in the fit\">\n",
       "Fixed\n",
       "</th>\n",
       "</tr>\n",
       "<tr style=\"background-color:#FFFFFF;\">\n",
       "<td>\n",
       "0\n",
       "</td>\n",
       "<td>\n",
       "a\n",
       "</td>\n",
       "<td>\n",
       "0.99\n",
       "</td>\n",
       "<td>\n",
       "0.06\n",
       "</td>\n",
       "<td>\n",
       "\n",
       "</td>\n",
       "<td>\n",
       "\n",
       "</td>\n",
       "<td>\n",
       "\n",
       "</td>\n",
       "<td>\n",
       "\n",
       "</td>\n",
       "<td>\n",
       "\n",
       "</td>\n",
       "</tr>\n",
       "<tr style=\"background-color:#F4F4F4;\">\n",
       "<td>\n",
       "1\n",
       "</td>\n",
       "<td>\n",
       "b\n",
       "</td>\n",
       "<td>\n",
       "1.94\n",
       "</td>\n",
       "<td>\n",
       "0.10\n",
       "</td>\n",
       "<td>\n",
       "\n",
       "</td>\n",
       "<td>\n",
       "\n",
       "</td>\n",
       "<td>\n",
       "\n",
       "</td>\n",
       "<td>\n",
       "\n",
       "</td>\n",
       "<td>\n",
       "\n",
       "</td>\n",
       "</tr>\n",
       "</table>\n"
      ],
      "text/plain": [
       "------------------------------------------------------------------\n",
       "| FCN = 10.39                   |      Ncalls=32 (32 total)      |\n",
       "| EDM = 7.24e-23 (Goal: 0.0002) |            up = 1.0            |\n",
       "------------------------------------------------------------------\n",
       "|  Valid Min.   | Valid Param.  | Above EDM | Reached call limit |\n",
       "------------------------------------------------------------------\n",
       "|     True      |     True      |   False   |       False        |\n",
       "------------------------------------------------------------------\n",
       "| Hesse failed  |   Has cov.    | Accurate  | Pos. def. | Forced |\n",
       "------------------------------------------------------------------\n",
       "|     False     |     True      |   True    |   True    | False  |\n",
       "------------------------------------------------------------------\n",
       "------------------------------------------------------------------------------------------\n",
       "|   | Name |   Value   | Hesse Err | Minos Err- | Minos Err+ | Limit-  | Limit+  | Fixed |\n",
       "------------------------------------------------------------------------------------------\n",
       "| 0 | a    |   0.99    |   0.06    |            |            |         |         |       |\n",
       "| 1 | b    |   1.94    |   0.10    |            |            |         |         |       |\n",
       "------------------------------------------------------------------------------------------"
      ]
     },
     "execution_count": 27,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "m = Minuit(least_squares, a=5, b=5, error_a=0.1, error_b=0.1, errordef=1)\n",
    "m.migrad()"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "The method returns two dict-like objects, which contain information about the function minimum and the parameter state. In a notebook, these objects are nicely rendered as tables. This is good for a quick check:\n",
    "\n",
    "- All blocks should be green.\n",
    "- Red means something bad. \n",
    "- Yellow is a caution (fit is good but you ran over call limit)\n",
    "\n",
    "Let's look at the actual object. The first is the function minimum `fmin`:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 28,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "FMin(fval=10.387011251394041, edm=7.239494620985003e-23, tolerance=0.1, nfcn=32, ncalls=32, up=1.0, is_valid=True, has_valid_parameters=True, has_accurate_covar=True, has_posdef_covar=True, has_made_posdef_covar=False, hesse_failed=False, has_covariance=True, is_above_max_edm=False, has_reached_call_limit=False)\n"
     ]
    }
   ],
   "source": [
    "print(repr(m.fmin)) # use repr() to avoid pretty printing"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "The most important one here is `is_valid`. If this is false, the fit did not converge and the result is useless. If that happens, there can be many reasons.\n",
    "\n",
    "- The fit function is not analytical everywhere in the parameter space or does not have a local minimum (the minimum may be at infinity, the extremum may be a saddle point or maximum). Indicators for this are `is_above_max_edm=True`, `hesse_failed=True`, `has_posdef_covar=False`, or `has_made_posdef_covar=True`.\n",
    "- Migrad reached the call limit before the convergence so that `has_reached_call_limit=True`. The used number of function calls is `nfcn`, and the call limit can be changed with the keyword argument `ncall` in the method  `Minuit.migrad`. Note that `nfcn` can be slightly larger than `ncall`, because Migrad internally only checks this condition after a full iteration step, in which several function calls can happen.\n",
    "\n",
    "Migrad detects converge by a small `edm` value, the *estimated distance to minimum*. This is the difference between the current minimum value of the minimized function and the next prediction based on a local quadratic approximation of the function (something that Migrad computes as part of its algorithm). If the fit did not converge, `is_above_max_edm` is true.\n",
    "\n",
    "If you are interested in parameter uncertainties, you should make sure that:\n",
    "\n",
    "- `has_covariance`, `has_accurate_covar`, and `has_posdef_covar` are true.\n",
    "- `has_made_posdef_covar` and `hesse_failed` are false.\n",
    "\n",
    "**Beware**: Migrad sometimes reports `is_valid=True` even when the result is wrong. There are some known and perhaps some hidden bugs in the Migrad code which cause this. When you find such a case, please report it, so that we can forward it to the maintainers of C++ Minuit. We advice to carefully check the fit result in any case for consistency, for example, by plotting the fitted function on top of the data to see that they match.\n",
    "\n",
    "The second object of interest after the fit is the parameter list:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 29,
   "metadata": {
    "scrolled": true
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "[Param(number=0, name='a', value=0.9909664415272599, error=0.058775380904206566, is_const=False, is_fixed=False, has_limits=False, has_lower_limit=False, has_upper_limit=False, lower_limit=None, upper_limit=None), Param(number=1, name='b', value=1.9449447037454373, error=0.09908673816096732, is_const=False, is_fixed=False, has_limits=False, has_lower_limit=False, has_upper_limit=False, lower_limit=None, upper_limit=None)]\n"
     ]
    }
   ],
   "source": [
    "print(repr(m.params)) # use repr() to avoid pretty printing"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "This is a list of dict-like objects which contain information about the fitted parameters. Important fields are:\n",
    "- `index`: parameter index.\n",
    "- `name`: parameter name.\n",
    "- `value`: value of the parameter at the minimum.\n",
    "- `error`: uncertainty estimate for the parameter value.\n",
    "\n",
    "Whether the uncertainty estimate is accurate depends on the correct mathematical modeling of your fitting problem and using the right `errordef` value for Minuit (which one to use was already explained earlier).\n",
    "\n",
    "What do we mean by correct mathematical modelling? If you look into the function `least_squares(a, b)`, you see that each squared residuals is divided by the expected stochastic variance of the residual. This is necessary to get accurate uncertainty estimates for the parameters.\n",
    "\n",
    "Often the expected variance of the residual is not exactly known, but it usually can be approximated. If the function to minimize is a least-squares function, there is a simple test to check whether the residual variances are accurate. You look at the function value at the minimum, here given by `fmin.fval`, and divide it by the difference of the number of residuals and the number of fitted parameters, which can be conveniently queried with the attribute `nfit`. This is so-called reduced chi2."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 30,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "1.2983764064242551"
      ]
     },
     "execution_count": 30,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "m.fval / (len(data_y) - m.nfit)  # reduced chi2"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "This value should be around 1. The more residuals you have, the closer. If the value is much larger than 1, then you either underestimate the variance of the residuals or your model does not describe the data. If the value is much smaller than 1, then you overestimate the variance of the residuals.\n",
    "\n",
    "##  Parameter uncertainties, covariances, and confidence intervals\n",
    "\n",
    "You saw how to get the uncertainty of each individual parameter, but parameters are usually correlated. This is essential additional information if you want to work with parameter uncertainties seriously. We will discuss next how you access that.\n",
    "\n",
    "Minuit offers two ways to compute the parameter uncertainties, Hesse and Minos. Both have pros and cons."
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### Hesse for covariance and correlation matrices\n",
    "\n",
    "The Hesse algorithm numerically computes the matrix of second derivatives at the function minimum (called the Hesse matrix) and inverts it. The Hesse matrix is symmetric by construction. In the limit of infinite data samples to fit, the result of this computation converges to the true covariance matrix of the parameters. It often is already a good approximation even for finite statistic. These errors obtained from this method are sometimes called *parabolic errors*, because the Hesse matrix method is exact if the function is a hyperparabola (third and higher-order derivatives are all zero).\n",
    "\n",
    "Pros:\n",
    "- (Comparably) fast computation.\n",
    "- Provides covariance matrix for error propagation.\n",
    "\n",
    "Cons:\n",
    "- Wrong if function does not look like a hyperparabola around the minimum\n",
    "\n",
    "The Migrad algorithm computes an approximation of the Hesse matrix automatically during minimization. When the default strategy is used, Minuit does a check whether this approximation is sufficiently accurate and if not, it computes the Hesse matrix automatically.\n",
    "\n",
    "All this happens inside C++ Minuit and is a bit intransparent, so we recommend to call `Minuit.hesse` explicitly after the minimization if exact errors are important, like so:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 31,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/html": [
       "<table>\n",
       "<tr style=\"background-color:#F4F4F4;\">\n",
       "<td/>\n",
       "<th title=\"Variable name\">\n",
       "Name\n",
       "</th>\n",
       "<th title=\"Value of parameter\">\n",
       "Value\n",
       "</th>\n",
       "<th title=\"Hesse error\">\n",
       "Hesse Error\n",
       "</th>\n",
       "<th title=\"Minos lower error\">\n",
       "Minos Error-\n",
       "</th>\n",
       "<th title=\"Minos upper error\">\n",
       "Minos Error+\n",
       "</th>\n",
       "<th title=\"Lower limit of the parameter\">\n",
       "Limit-\n",
       "</th>\n",
       "<th title=\"Upper limit of the parameter\">\n",
       "Limit+\n",
       "</th>\n",
       "<th title=\"Is the parameter fixed in the fit\">\n",
       "Fixed\n",
       "</th>\n",
       "</tr>\n",
       "<tr style=\"background-color:#FFFFFF;\">\n",
       "<td>\n",
       "0\n",
       "</td>\n",
       "<td>\n",
       "a\n",
       "</td>\n",
       "<td>\n",
       "0.99\n",
       "</td>\n",
       "<td>\n",
       "0.16\n",
       "</td>\n",
       "<td>\n",
       "\n",
       "</td>\n",
       "<td>\n",
       "\n",
       "</td>\n",
       "<td>\n",
       "\n",
       "</td>\n",
       "<td>\n",
       "\n",
       "</td>\n",
       "<td>\n",
       "\n",
       "</td>\n",
       "</tr>\n",
       "<tr style=\"background-color:#F4F4F4;\">\n",
       "<td>\n",
       "1\n",
       "</td>\n",
       "<td>\n",
       "b\n",
       "</td>\n",
       "<td>\n",
       "1.94\n",
       "</td>\n",
       "<td>\n",
       "0.20\n",
       "</td>\n",
       "<td>\n",
       "\n",
       "</td>\n",
       "<td>\n",
       "\n",
       "</td>\n",
       "<td>\n",
       "\n",
       "</td>\n",
       "<td>\n",
       "\n",
       "</td>\n",
       "<td>\n",
       "\n",
       "</td>\n",
       "</tr>\n",
       "</table>\n"
      ],
      "text/plain": [
       "------------------------------------------------------------------------------------------\n",
       "|   | Name |   Value   | Hesse Err | Minos Err- | Minos Err+ | Limit-  | Limit+  | Fixed |\n",
       "------------------------------------------------------------------------------------------\n",
       "| 0 | a    |   0.99    |   0.16    |            |            |         |         |       |\n",
       "| 1 | b    |   1.94    |   0.20    |            |            |         |         |       |\n",
       "------------------------------------------------------------------------------------------"
      ]
     },
     "execution_count": 31,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "# let's mess up the current errors a bit so that hesse has something to do\n",
    "m.errors[:] = (0.16, 0.2)\n",
    "m.params"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 32,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/html": [
       "<table>\n",
       "<tr style=\"background-color:#F4F4F4;\">\n",
       "<td/>\n",
       "<th title=\"Variable name\">\n",
       "Name\n",
       "</th>\n",
       "<th title=\"Value of parameter\">\n",
       "Value\n",
       "</th>\n",
       "<th title=\"Hesse error\">\n",
       "Hesse Error\n",
       "</th>\n",
       "<th title=\"Minos lower error\">\n",
       "Minos Error-\n",
       "</th>\n",
       "<th title=\"Minos upper error\">\n",
       "Minos Error+\n",
       "</th>\n",
       "<th title=\"Lower limit of the parameter\">\n",
       "Limit-\n",
       "</th>\n",
       "<th title=\"Upper limit of the parameter\">\n",
       "Limit+\n",
       "</th>\n",
       "<th title=\"Is the parameter fixed in the fit\">\n",
       "Fixed\n",
       "</th>\n",
       "</tr>\n",
       "<tr style=\"background-color:#FFFFFF;\">\n",
       "<td>\n",
       "0\n",
       "</td>\n",
       "<td>\n",
       "a\n",
       "</td>\n",
       "<td>\n",
       "0.99\n",
       "</td>\n",
       "<td>\n",
       "0.06\n",
       "</td>\n",
       "<td>\n",
       "\n",
       "</td>\n",
       "<td>\n",
       "\n",
       "</td>\n",
       "<td>\n",
       "\n",
       "</td>\n",
       "<td>\n",
       "\n",
       "</td>\n",
       "<td>\n",
       "\n",
       "</td>\n",
       "</tr>\n",
       "<tr style=\"background-color:#F4F4F4;\">\n",
       "<td>\n",
       "1\n",
       "</td>\n",
       "<td>\n",
       "b\n",
       "</td>\n",
       "<td>\n",
       "1.94\n",
       "</td>\n",
       "<td>\n",
       "0.10\n",
       "</td>\n",
       "<td>\n",
       "\n",
       "</td>\n",
       "<td>\n",
       "\n",
       "</td>\n",
       "<td>\n",
       "\n",
       "</td>\n",
       "<td>\n",
       "\n",
       "</td>\n",
       "<td>\n",
       "\n",
       "</td>\n",
       "</tr>\n",
       "</table>\n"
      ],
      "text/plain": [
       "------------------------------------------------------------------------------------------\n",
       "|   | Name |   Value   | Hesse Err | Minos Err- | Minos Err+ | Limit-  | Limit+  | Fixed |\n",
       "------------------------------------------------------------------------------------------\n",
       "| 0 | a    |   0.99    |   0.06    |            |            |         |         |       |\n",
       "| 1 | b    |   1.94    |   0.10    |            |            |         |         |       |\n",
       "------------------------------------------------------------------------------------------"
      ]
     },
     "execution_count": 32,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "m.hesse()"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "The call returns the updated parameter list, which is again rendered as a table.\n",
    "\n",
    "#### Correlation and Covariance Matrix\n",
    "\n",
    "To see the correlation matrix of the parameters, you do:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 33,
   "metadata": {
    "inputHidden": false,
    "outputHidden": false
   },
   "outputs": [
    {
     "data": {
      "text/html": [
       "<table>\n",
       "<tr>\n",
       "<td/>\n",
       "\n",
       "<th>\n",
       "a\n",
       "</th>\n",
       "<th>\n",
       "b\n",
       "</th>\n",
       "</tr>\n",
       "<tr>\n",
       "<th>\n",
       "a\n",
       "</th>\n",
       "<td>\n",
       " 1.00\n",
       "</td>\n",
       "<td style=\"background-color:rgb(140,140,250)\">\n",
       "-0.84\n",
       "</td>\n",
       "</tr>\n",
       "<tr>\n",
       "<th>\n",
       "b\n",
       "</th>\n",
       "<td style=\"background-color:rgb(140,140,250)\">\n",
       "-0.84\n",
       "</td>\n",
       "<td>\n",
       " 1.00\n",
       "</td>\n",
       "</tr>\n",
       "</table>\n"
      ],
      "text/plain": [
       "---------------------\n",
       "|   |      a      b |\n",
       "---------------------\n",
       "| a |  1.000 -0.843 |\n",
       "| b | -0.843  1.000 |\n",
       "---------------------"
      ]
     },
     "execution_count": 33,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "m.matrix(correlation=True)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "The paramaters $a$ and $b$ are stronly anti-correlated, which is highlighed by the blue color of the off-diagonal elements.\n",
    "\n",
    "Correlation is not necessarily a bad thing, but if you have freedom in redefining the parameters of the fit function, it is good to chose parameters which are not strongly correlated.\n",
    "\n",
    "Minuit cannot accurately minimise the function if two parameters are (almost) perfectly (anti-)correlated. It also means that one of two parameters is superfluous, it doesn't add new information. You should rethink the fit function in this case and try to remove one of the parameters from the fit.\n",
    "\n",
    "You can also look at the covariance matrix:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 34,
   "metadata": {
    "inputHidden": false,
    "outputHidden": false
   },
   "outputs": [
    {
     "data": {
      "text/html": [
       "<table>\n",
       "<tr>\n",
       "<td/>\n",
       "\n",
       "<th>\n",
       "a\n",
       "</th>\n",
       "<th>\n",
       "b\n",
       "</th>\n",
       "</tr>\n",
       "<tr>\n",
       "<th>\n",
       "a\n",
       "</th>\n",
       "<td>\n",
       "0.003\n",
       "</td>\n",
       "<td style=\"background-color:rgb(140,140,250)\">\n",
       "-0.005\n",
       "</td>\n",
       "</tr>\n",
       "<tr>\n",
       "<th>\n",
       "b\n",
       "</th>\n",
       "<td style=\"background-color:rgb(140,140,250)\">\n",
       "-0.005\n",
       "</td>\n",
       "<td>\n",
       "0.010\n",
       "</td>\n",
       "</tr>\n",
       "</table>\n"
      ],
      "text/plain": [
       "---------------------\n",
       "|   |      a      b |\n",
       "---------------------\n",
       "| a |  0.003 -0.005 |\n",
       "| b | -0.005  0.010 |\n",
       "---------------------"
      ]
     },
     "execution_count": 34,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "m.matrix()"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "inputHidden": false,
    "outputHidden": false
   },
   "source": [
    "To see the matrices as Python objects, use `repr`:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 35,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "((1.0, -0.8429272304121346), (-0.8429272304121346, 1.0))\n",
      "((0.0034545454534978407, -0.004909090907946418), (-0.004909090907946418, 0.009818181816846617))\n"
     ]
    }
   ],
   "source": [
    "print(repr(m.matrix(correlation=True)))  # correlation matrix as before\n",
    "print(repr(m.matrix()))  # covariance matrix"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "If you want the matrix as a numpy array (useful for error propagation), use the `np_` methods:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 36,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "[[ 0.00345455 -0.00490909]\n",
      " [-0.00490909  0.00981818]]\n"
     ]
    }
   ],
   "source": [
    "print(m.np_matrix())  # m.np_covariance() also works"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### Minos for non-parabolic minima\n",
    "\n",
    "Minuits other algorithm to compute uncertainties is Minos. It implements the so-called profile likelihood method, where the neighborhood around the function minimum is scanned until the contour is found where the function increase by the value of `errordef`. The contour defines a confidence region that approximately covers the true parameter point with a certain confidence. The contour is exact in the limit of infinitely large data samples and approximate for the finite case (although the approximation is usually very good). Please consult a textbook about statistics about the mathematical details.\n",
    "\n",
    "Minos provides a better answer than Hesse, if the neighborhood around the minimum is very different from a hyperparabola (e.g. banana shaped), but it takes much much longer to compute.\n",
    "\n",
    "Pros:\n",
    "- Good for functions which are not very close to a hyper-parabola around the minimum\n",
    "- Produces pretty confidence regions for scientific plots\n",
    "\n",
    "Cons:\n",
    "- Takes really long time\n",
    "- Result is difficult to error-propagate, since it cannot be described by a covariance matrix\n",
    "\n",
    "Minos is not automatically called during minimization, it needs to be called explicitly afterwards, like so:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 37,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/html": [
       "<table>\n",
       "<tr>\n",
       "<th title=\"Parameter name\">\n",
       "a\n",
       "</th>\n",
       "<td align=\"center\" colspan=\"2\" style=\"background-color:#92CCA6;\">\n",
       "Valid\n",
       "</td>\n",
       "</tr>\n",
       "<tr>\n",
       "<td title=\"Lower and upper minos error of the parameter\">\n",
       "Error\n",
       "</td>\n",
       "<td>\n",
       "-0.06\n",
       "</td>\n",
       "<td>\n",
       "0.06\n",
       "</td>\n",
       "</tr>\n",
       "<tr>\n",
       "<td title=\"Validity of lower/upper minos error\">\n",
       "Valid\n",
       "</td>\n",
       "<td style=\"background-color:#92CCA6;\">\n",
       "True\n",
       "</td>\n",
       "<td style=\"background-color:#92CCA6;\">\n",
       "True\n",
       "</td>\n",
       "</tr>\n",
       "<tr>\n",
       "<td title=\"Did scan hit limit of any parameter?\">\n",
       "At Limit\n",
       "</td>\n",
       "<td style=\"background-color:#92CCA6;\">\n",
       "False\n",
       "</td>\n",
       "<td style=\"background-color:#92CCA6;\">\n",
       "False\n",
       "</td>\n",
       "</tr>\n",
       "<tr>\n",
       "<td title=\"Did scan hit function call limit?\">\n",
       "Max FCN\n",
       "</td>\n",
       "<td style=\"background-color:#92CCA6;\">\n",
       "False\n",
       "</td>\n",
       "<td style=\"background-color:#92CCA6;\">\n",
       "False\n",
       "</td>\n",
       "</tr>\n",
       "<tr>\n",
       "<td title=\"New minimum found when doing scan?\">\n",
       "New Min\n",
       "</td>\n",
       "<td style=\"background-color:#92CCA6;\">\n",
       "False\n",
       "</td>\n",
       "<td style=\"background-color:#92CCA6;\">\n",
       "False\n",
       "</td>\n",
       "</tr>\n",
       "</table>\n",
       "\n",
       "<table>\n",
       "<tr>\n",
       "<th title=\"Parameter name\">\n",
       "b\n",
       "</th>\n",
       "<td align=\"center\" colspan=\"2\" style=\"background-color:#92CCA6;\">\n",
       "Valid\n",
       "</td>\n",
       "</tr>\n",
       "<tr>\n",
       "<td title=\"Lower and upper minos error of the parameter\">\n",
       "Error\n",
       "</td>\n",
       "<td>\n",
       "-0.1\n",
       "</td>\n",
       "<td>\n",
       "0.1\n",
       "</td>\n",
       "</tr>\n",
       "<tr>\n",
       "<td title=\"Validity of lower/upper minos error\">\n",
       "Valid\n",
       "</td>\n",
       "<td style=\"background-color:#92CCA6;\">\n",
       "True\n",
       "</td>\n",
       "<td style=\"background-color:#92CCA6;\">\n",
       "True\n",
       "</td>\n",
       "</tr>\n",
       "<tr>\n",
       "<td title=\"Did scan hit limit of any parameter?\">\n",
       "At Limit\n",
       "</td>\n",
       "<td style=\"background-color:#92CCA6;\">\n",
       "False\n",
       "</td>\n",
       "<td style=\"background-color:#92CCA6;\">\n",
       "False\n",
       "</td>\n",
       "</tr>\n",
       "<tr>\n",
       "<td title=\"Did scan hit function call limit?\">\n",
       "Max FCN\n",
       "</td>\n",
       "<td style=\"background-color:#92CCA6;\">\n",
       "False\n",
       "</td>\n",
       "<td style=\"background-color:#92CCA6;\">\n",
       "False\n",
       "</td>\n",
       "</tr>\n",
       "<tr>\n",
       "<td title=\"New minimum found when doing scan?\">\n",
       "New Min\n",
       "</td>\n",
       "<td style=\"background-color:#92CCA6;\">\n",
       "False\n",
       "</td>\n",
       "<td style=\"background-color:#92CCA6;\">\n",
       "False\n",
       "</td>\n",
       "</tr>\n",
       "</table>\n"
      ],
      "text/plain": [
       "-------------------------------------------------\n",
       "|        a        |            Valid            |\n",
       "-------------------------------------------------\n",
       "|      Error      |    -0.06     |     0.06     |\n",
       "|      Valid      |     True     |     True     |\n",
       "|    At Limit     |    False     |    False     |\n",
       "|     Max FCN     |    False     |    False     |\n",
       "|     New Min     |    False     |    False     |\n",
       "-------------------------------------------------\n",
       "-------------------------------------------------\n",
       "|        b        |            Valid            |\n",
       "-------------------------------------------------\n",
       "|      Error      |     -0.1     |     0.1      |\n",
       "|      Valid      |     True     |     True     |\n",
       "|    At Limit     |    False     |    False     |\n",
       "|     Max FCN     |    False     |    False     |\n",
       "|     New Min     |    False     |    False     |\n",
       "-------------------------------------------------"
      ]
     },
     "execution_count": 37,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "m.minos()"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "By now you are probably used to see green colors, which indicate that Minos ran successful. Be careful when these are red instead. The fields in the table mean the following:\n",
    "- At Limit: Whether Minos hit a parameter limit before the finishing the contour.\n",
    "- Max FCN: Whether Minos reached the maximum number of allowed calls before finishing the contour.\n",
    "- New Min: Whether Minos discovered a deeper local minimum in the neighborhood of the current one.\n",
    "\n",
    "The errors computed by Minos are now also shown in the parameter list:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 38,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/html": [
       "<table>\n",
       "<tr style=\"background-color:#F4F4F4;\">\n",
       "<td/>\n",
       "<th title=\"Variable name\">\n",
       "Name\n",
       "</th>\n",
       "<th title=\"Value of parameter\">\n",
       "Value\n",
       "</th>\n",
       "<th title=\"Hesse error\">\n",
       "Hesse Error\n",
       "</th>\n",
       "<th title=\"Minos lower error\">\n",
       "Minos Error-\n",
       "</th>\n",
       "<th title=\"Minos upper error\">\n",
       "Minos Error+\n",
       "</th>\n",
       "<th title=\"Lower limit of the parameter\">\n",
       "Limit-\n",
       "</th>\n",
       "<th title=\"Upper limit of the parameter\">\n",
       "Limit+\n",
       "</th>\n",
       "<th title=\"Is the parameter fixed in the fit\">\n",
       "Fixed\n",
       "</th>\n",
       "</tr>\n",
       "<tr style=\"background-color:#FFFFFF;\">\n",
       "<td>\n",
       "0\n",
       "</td>\n",
       "<td>\n",
       "a\n",
       "</td>\n",
       "<td>\n",
       "0.99\n",
       "</td>\n",
       "<td>\n",
       "0.06\n",
       "</td>\n",
       "<td>\n",
       "-0.06\n",
       "</td>\n",
       "<td>\n",
       "0.06\n",
       "</td>\n",
       "<td>\n",
       "\n",
       "</td>\n",
       "<td>\n",
       "\n",
       "</td>\n",
       "<td>\n",
       "\n",
       "</td>\n",
       "</tr>\n",
       "<tr style=\"background-color:#F4F4F4;\">\n",
       "<td>\n",
       "1\n",
       "</td>\n",
       "<td>\n",
       "b\n",
       "</td>\n",
       "<td>\n",
       "1.94\n",
       "</td>\n",
       "<td>\n",
       "0.10\n",
       "</td>\n",
       "<td>\n",
       "-0.10\n",
       "</td>\n",
       "<td>\n",
       "0.10\n",
       "</td>\n",
       "<td>\n",
       "\n",
       "</td>\n",
       "<td>\n",
       "\n",
       "</td>\n",
       "<td>\n",
       "\n",
       "</td>\n",
       "</tr>\n",
       "</table>\n"
      ],
      "text/plain": [
       "------------------------------------------------------------------------------------------\n",
       "|   | Name |   Value   | Hesse Err | Minos Err- | Minos Err+ | Limit-  | Limit+  | Fixed |\n",
       "------------------------------------------------------------------------------------------\n",
       "| 0 | a    |   0.99    |   0.06    |   -0.06    |    0.06    |         |         |       |\n",
       "| 1 | b    |   1.94    |   0.10    |   -0.10    |    0.10    |         |         |       |\n",
       "------------------------------------------------------------------------------------------"
      ]
     },
     "execution_count": 38,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "m.params"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "If the absolute values of the Minos errors are very close to the Hesse Error, the function is well approximated by a hyperparabola around the minimum. You can use this as a check instead of explicitly plotting the function around the minimum (for which we provide tools, see below)."
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Quick access to fit results\n",
    "\n",
    "If working with the dicts returned by `Minuit.migrad` and `Minuit.minos` is not your thing, you can also get the fit results with properties and methods. There are many, please check the reference of `Minuit`. Here are the most important ones:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 39,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "<ValueView of Minuit at 7febbfa9cde0>\n",
      "  a: 0.9909664415272599\n",
      "  b: 1.9449447037454373\n",
      "by name 0.9909664415272599\n",
      "by index 0.9909664415272599\n",
      "('a', 0.9909664415272599)\n",
      "('b', 1.9449447037454373)\n",
      "[0.9909664415272599]\n",
      "Hesse errors\n",
      "<ErrorView of Minuit at 7febbfa9cde0>\n",
      "  a: 0.05877538135561385\n",
      "  b: 0.09908673885463491\n",
      "Minos errors\n",
      "MErrors([('a', MError(name='a', is_valid=True, lower=-0.058775381364513005, upper=0.05877538136453843, lower_valid=True, upper_valid=True, at_lower_limit=False, at_upper_limit=False, at_lower_max_fcn=False, at_upper_max_fcn=False, lower_new_min=False, upper_new_min=False, nfcn=12, min=0.9909664415272599)), ('b', MError(name='b', is_valid=True, lower=-0.09908673886135537, upper=0.09908673886138916, lower_valid=True, upper_valid=True, at_lower_limit=False, at_upper_limit=False, at_lower_max_fcn=False, at_upper_max_fcn=False, lower_new_min=False, upper_new_min=False, nfcn=14, min=1.9449447037454373))])\n",
      "Hesse covariance\n",
      "{('a', 'a'): 0.0034545454534978407, ('a', 'b'): -0.004909090907946418, ('b', 'a'): -0.004909090907946418, ('b', 'b'): 0.009818181816846617}\n"
     ]
    }
   ],
   "source": [
    "print(m.values) # dict-like view of the parameter values\n",
    "# access values by name or index\n",
    "print(\"by name\", m.values[\"a\"])\n",
    "print(\"by index\", m.values[0])\n",
    "\n",
    "# you can iterate over the view like you would over a dict\n",
    "for key, value in m.values.items():\n",
    "    print((key, value))\n",
    "\n",
    "# slicing also works as if m.values was an array\n",
    "print(m.values[:1])\n",
    "    \n",
    "print(\"Hesse errors\")\n",
    "print(m.errors)  # dict-like view of symmetric uncertainties\n",
    "# m.errors supports the same access as m.values\n",
    "\n",
    "print(\"Minos errors\")\n",
    "print(repr(m.merrors))  # asymmetric uncertainties, we use repr() here to avoid the normal pretty print\n",
    "print(\"Hesse covariance\")\n",
    "print(m.covariance)  # the covariance matrix computed by Hesse"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Note that you can play around with iminuit by assigning new values to `m.values` and `m.errors`. The values will be used as a starting point when you call `m.migrad()` again.\n",
    "\n",
    "There are also corresponding methods that return numpy arrays, convenient if you use numpy functions. Note that these methods create copies. The numpy arrays are not views like the attributes. Changing the values of the numpy array does not change the state that `Minuit` sees."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 40,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "[0.99096644 1.9449447 ]\n",
      "[0.05877538 0.09908674]\n",
      "[[0.05877538 0.09908674]\n",
      " [0.05877538 0.09908674]]\n",
      "[[ 0.00345455 -0.00490909]\n",
      " [-0.00490909  0.00981818]]\n"
     ]
    }
   ],
   "source": [
    "# note these are methods and not a properties\n",
    "print(m.np_values())\n",
    "print(m.np_errors())\n",
    "print(m.np_merrors())\n",
    "print(m.np_covariance())"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "The layout for most of these is straight-forward, but for `Minuit.np_merrors()` it is different. The layout returned by `Minuit.np_merrors()` follows the convention `[abs(delta_down), delta_up]` that is used by `matplotlib.pyplot.errorbar`. This makes passing Hesse and Minos errors to matplotlib straight-forward. You can see an example here:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 41,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "image/png": "[encoded data, 5292 characters]\n",
      "text/plain": [
       "<Figure size 432x288 with 1 Axes>"
      ]
     },
     "metadata": {
      "needs_background": "light"
     },
     "output_type": "display_data"
    }
   ],
   "source": [
    "v = m.np_values()\n",
    "ve = m.np_errors()\n",
    "vm = m.np_merrors()\n",
    "# show hesse errors\n",
    "plt.errorbar((0, 1), v, ve, fmt=\"ob\");\n",
    "# show minos errors\n",
    "plt.errorbar((0.01, 1.01), v, vm, fmt=\"or\"); # add a little offset so that the error bars don't overlap\n",
    "plt.xlabel(\"parameter index\")\n",
    "plt.xticks((0, 1))\n",
    "plt.xlim(-0.1, 1.1);"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Plotting\n",
    "\n",
    "iminuit comes with buildin methods to draw the confidence regions around the minimum, like so:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 42,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "image/png": "[encoded data, 39440 characters]\n",
      "text/plain": [
       "<Figure size 432x288 with 1 Axes>"
      ]
     },
     "metadata": {
      "needs_background": "light"
     },
     "output_type": "display_data"
    }
   ],
   "source": [
    "m.draw_mncontour('a','b', nsigma=4);  # nsigma=4 says: draw four contours from sigma=1 to 4"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 43,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "[(0.8734156784913456, 2.1119905249019766), (0.8999995906799966, 2.006682035074518), (0.9468999238490023, 1.90871805615558), (1.0065114363524184, 1.8171680503785055), (1.0900531806220088, 1.7467712255557788), (1.108517204563208, 1.77789888269924), (1.0819332923584948, 1.883207372456996), (1.0350329592153722, 1.981171351317756), (0.9754214467594318, 2.072721357037905), (0.8918797026488856, 2.1431181819351415)]\n"
     ]
    }
   ],
   "source": [
    "# get individual minos contours for plotting them yourself\n",
    "param_a, param_b, ctr_xy = m.mncontour('a','b', sigma=2, numpoints=10)\n",
    "print(ctr_xy)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "If you need to inspect the cost function around the minimum because MINUIT warns you about some issues, you can quickly scan cost function around the current parameter values, too."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 44,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "image/png": "[encoded data, 14548 characters]\n",
      "text/plain": [
       "<Figure size 432x288 with 1 Axes>"
      ]
     },
     "metadata": {
      "needs_background": "light"
     },
     "output_type": "display_data"
    }
   ],
   "source": [
    "# 1D value Scan\n",
    "a, fa = m.profile('a')\n",
    "plt.plot(a, fa);"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 45,
   "metadata": {
    "scrolled": true
   },
   "outputs": [
    {
     "data": {
      "image/png": "[encoded data, 18972 characters]\n",
      "text/plain": [
       "<Figure size 432x288 with 1 Axes>"
      ]
     },
     "metadata": {
      "needs_background": "light"
     },
     "output_type": "display_data"
    }
   ],
   "source": [
    "# or use this function for a quick look\n",
    "m.draw_profile('a');"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Alternativel, you can use `mnprofile` to do a full profile likelihood scan. This mimics what MINOS does to compute confidence intervals. If you have trouble with MINOS, running this may help to inspect the issue.\n",
    "\n",
    "This is computationally expensive, since the scan runs MIGRAD for each point on the profile."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 46,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "image/png": "[encoded data, 19952 characters]\n",
      "text/plain": [
       "<Figure size 432x288 with 1 Axes>"
      ]
     },
     "metadata": {
      "needs_background": "light"
     },
     "output_type": "display_data"
    }
   ],
   "source": [
    "m.draw_mnprofile('a');"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Finally, you can also look at the 2D contours of the cost function around the minimum. Note that these are just contours of the fit function, not confidence regions. The latter you can only get from `mncontour`."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 47,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "image/png": "[encoded data, 47536 characters]\n",
      "text/plain": [
       "<Figure size 432x288 with 1 Axes>"
      ]
     },
     "metadata": {
      "needs_background": "light"
     },
     "output_type": "display_data"
    }
   ],
   "source": [
    "x,y,z = m.contour('a', 'b', subtract_min=True)\n",
    "cs = plt.contour(x,y,z, (1, 2, 3, 4)) # these are not sigmas, just the contour values\n",
    "plt.clabel(cs);"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 48,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "image/png": "[encoded data, 49732 characters]\n",
      "text/plain": [
       "<Figure size 432x288 with 1 Axes>"
      ]
     },
     "metadata": {
      "needs_background": "light"
     },
     "output_type": "display_data"
    }
   ],
   "source": [
    "# or use this function for a quick look\n",
    "m.draw_contour('a', 'b');"
   ]
  }
 ],
 "metadata": {
  "kernel_info": {
   "name": "python3"
  },
  "kernelspec": {
   "display_name": "Python 3",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.7.7"
  },
  "nteract": {
   "version": "0.12.3"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 4
}
