iminuit
iminuit is a Jupyter-friendly Python frontend for the MINUIT2 C++ library, maintained by CERN's ROOT team. It is designed to optimize statistical cost functions for maximum-likelihood and least-squares fits, providing best-fit parameters and error estimates from likelihood profile analysis. The library is currently at version 2.32.0 and undergoes regular updates with detailed changelogs.
Warnings
- breaking Version 2.x introduced significant breaking interface changes compared to 1.x. Older scripts are not directly compatible.
- gotcha The `errordef` parameter must be correctly set: `1.0` for least-squares (chi-squared) cost functions and `0.5` for negative log-likelihood functions. Incorrect `errordef` will lead to wrong error estimates.
- gotcha The Minuit `migrad` algorithm is a local minimizer. Providing poor initial parameter guesses can lead to convergence to local minima instead of the global minimum, or slow convergence.
- gotcha Always check the fit status (e.g., `m.valid`, `m.fmin.is_valid`) after calling `m.migrad()` or `m.hesse()`. `iminuit` can fail to converge or estimate errors accurately due to numerical issues, discontinuous cost functions, or reaching call limits.
- gotcha Minuit (and thus iminuit) only supports independent box constraints on parameters (e.g., `a > 0`, `b < 5`). Complex, dependent parameter limits (e.g., `x^2 + y^2 < 1`) are not directly supported and require manual transformations or external minimizers.
Install
-
pip install iminuit
Imports
- Minuit
from iminuit import Minuit
- UnbinnedNLL
from iminuit.cost import UnbinnedNLL
- LeastSquares
from iminuit.cost import LeastSquares
Quickstart
import numpy as np
from iminuit import Minuit
from iminuit.cost import LeastSquares
from matplotlib import pyplot as plt
# 1. Generate some dummy data
np.random.seed(1)
x = np.linspace(0, 10, 50)
y_true = 2.5 * x + 1.2
y_err = 1.0 + x * 0.1
y_data = np.random.normal(y_true, y_err)
# 2. Define the model function
def model(x, a, b):
return a * x + b
# 3. Create a cost function using iminuit.cost.LeastSquares
# errordef=1 for least-squares fits
least_squares = LeastSquares(x, y_data, y_err, model)
# 4. Initialize Minuit with the cost function and initial parameter guesses
# Parameter names are auto-detected from the model function signature
m = Minuit(least_squares, a=0, b=0)
# 5. Run the minimization (MIGRAD algorithm)
m.migrad()
# 6. Run HESSE to compute accurate errors
m.hesse()
# 7. Print fit results and plot
print(m)
plt.errorbar(x, y_data, y_err, fmt='o', label='Data')
plt.plot(x, model(x, *m.values), label='Fit')
plt.xlabel('x')
plt.ylabel('y')
plt.legend()
plt.show()