Example fit for the usage of iminuit
from matplotlib import pyplot as plt
plt.rcParams["font.size"] = 20
import numpy as np
Data
x = np.array([0.2,0.4,0.6,0.8,1.,1.2,1.4,1.6,1.8,2.,2.2,2.4,2.6,2.8,3.,3.2,3.4,3.6,3.8,4.],dtype='d')
dy = np.array([0.04,0.021,0.035,0.03,0.029,0.019,0.024,0.018,0.019,0.022,0.02,0.025,0.018,0.024,0.019,0.021,0.03,0.019,0.03,0.024 ], dtype='d')
y = np.array([1.792,1.695,1.541,1.514,1.427,1.399,1.388,1.270,1.262,1.228,1.189,1.182,1.121,1.129,1.124,1.089,1.092,1.084,1.058,1.057 ], dtype='d')
Define fit functions -an exponential
def xp(a, b , c):
return a * np.exp(b*x) + c
least-squares function: sum of data residuals squared
def LS(a,b,c):
return np.sum((y - xp(a,b,c)) ** 2 / dy ** 2)
import Minuit object
from iminuit import Minuit
Minuit instance using LS function to minimize
#m = Minuit(LS,pedantic=False)
LS.errordef = Minuit.LEAST_SQUARES
m = Minuit(LS, a=0.9, b=-0.7 , c=0.95 , error_a=1 , error_b=1 , error_c=1 , limit_b=(-1,-0.1), fix_c=True)
m.params
Name | Value | Hesse Error | Minos Error- | Minos Error+ | Limit- | Limit+ | Fixed | |
---|---|---|---|---|---|---|---|---|
0 | a | 0.9 | 1.0 | |||||
1 | b | -0.7 | 1.0 | -1 | -0.1 | |||
2 | c | 1 | 1 | yes |
Run migrad , parameter c is now fixed
m.migrad()
FCN = 17.82 | Nfcn = 41 (41 total) | |||
EDM = 0.000198 (Goal: 0.0002) | ||||
Valid Minimum | Valid Parameters | No Parameters at limit | ||
Below EDM threshold (goal x 10) | Below call limit | |||
Hesse ok | Has Covariance | Accurate | Pos. def. | Not forced |
Name | Value | Hesse Error | Minos Error- | Minos Error+ | Limit- | Limit+ | Fixed | |
---|---|---|---|---|---|---|---|---|
0 | a | 0.916 | 0.023 | |||||
1 | b | -0.594 | 0.018 | -1 | -0.1 | |||
2 | c | 1 | 1 | yes |
release fix on "c" and minimize again
m.fixed["c"] = False
m.migrad()
FCN = 12.96 | Nfcn = 91 (132 total) | |||
EDM = 5.71e-07 (Goal: 0.0002) | ||||
Valid Minimum | Valid Parameters | No Parameters at limit | ||
Below EDM threshold (goal x 10) | Below call limit | |||
Hesse ok | Has Covariance | Accurate | Pos. def. | Not forced |
Name | Value | Hesse Error | Minos Error- | Minos Error+ | Limit- | Limit+ | Fixed | |
---|---|---|---|---|---|---|---|---|
0 | a | 0.903 | 0.026 | |||||
1 | b | -0.72 | 0.06 | -1 | -0.1 | |||
2 | c | 1.006 | 0.022 |
Get covariance information
m.hesse()
m.params
m.matrix(correlation=True)
m.matrix()
a | b | c | |
---|---|---|---|
a | 0.001 | -0.000 | -0.000 |
b | -0.000 | 0.004 | -0.001 |
c | -0.000 | -0.001 | 0.000 |
Copy covariance information to numpy arrays
cor = m.np_matrix(correlation=True)
cov = m.np_matrix()
print (cov)
# print correlation between parameter a and b
print(cor[0, 1])
[[ 6.49202195e-04 -2.93987060e-04 -6.96037643e-05] [-2.93987060e-04 3.53097407e-03 -1.19593212e-03] [-6.96037643e-05 -1.19593212e-03 4.76430582e-04]] -0.19417394795849946
Get a 2D contour of the function around the minimum for 2 parameters
m.minos()
print (m.merrors['a']) # Print control information of parameter a
m.draw_profile('b')
return Minos error -0.00268629 , 0.00349823 ┌──────────┬───────────────────────┐ │ │ a │ ├──────────┼───────────┬───────────┤ │ Error │ -0.025 │ 0.026 │ │ Valid │ True │ True │ │ At Limit │ False │ False │ │ Max FCN │ False │ False │ │ New Min │ False │ False │ └──────────┴───────────┴───────────┘ return Minos error 0.015994 , -0.00774831 return Minos error 0.0663204 , -0.0562845
(array([-0.83362627, -0.83123343, -0.8288406 , -0.82644777, -0.82405493, -0.8216621 , -0.81926927, -0.81687643, -0.8144836 , -0.81209077, -0.80969794, -0.8073051 , -0.80491227, -0.80251944, -0.8001266 , -0.79773377, -0.79534094, -0.7929481 , -0.79055527, -0.78816244, -0.7857696 , -0.78337677, -0.78098394, -0.7785911 , -0.77619827, -0.77380544, -0.7714126 , -0.76901977, -0.76662694, -0.76423411, -0.76184127, -0.75944844, -0.75705561, -0.75466277, -0.75226994, -0.74987711, -0.74748427, -0.74509144, -0.74269861, -0.74030577, -0.73791294, -0.73552011, -0.73312727, -0.73073444, -0.72834161, -0.72594878, -0.72355594, -0.72116311, -0.71877028, -0.71637744, -0.71398461, -0.71159178, -0.70919894, -0.70680611, -0.70441328, -0.70202044, -0.69962761, -0.69723478, -0.69484194, -0.69244911, -0.69005628, -0.68766345, -0.68527061, -0.68287778, -0.68048495, -0.67809211, -0.67569928, -0.67330645, -0.67091361, -0.66852078, -0.66612795, -0.66373511, -0.66134228, -0.65894945, -0.65655661, -0.65416378, -0.65177095, -0.64937811, -0.64698528, -0.64459245, -0.64219962, -0.63980678, -0.63741395, -0.63502112, -0.63262828, -0.63023545, -0.62784262, -0.62544978, -0.62305695, -0.62066412, -0.61827128, -0.61587845, -0.61348562, -0.61109278, -0.60869995, -0.60630712, -0.60391429, -0.60152145, -0.59912862, -0.59673579]), array([ 73.60259311, 71.42824021, 69.2843301 , 67.17133306, 65.0897254 , 63.03998951, 61.02261398, 59.03809366, 57.08692972, 55.16962979, 53.28670798, 51.43868502, 49.6260883 , 47.849452 , 46.10931715, 44.40623171, 42.74075072, 41.1134363 , 39.52485784, 37.97559202, 36.46622296, 34.99734227, 33.5695492 , 32.18345069, 30.83966152, 29.53880435, 28.28150992, 27.06841704, 25.9001728 , 24.77743262, 23.70086037, 22.67112851, 21.68891816, 20.75491925, 19.86983063, 19.03436018, 18.24922491, 17.51515115, 16.83287459, 16.20314047, 15.62670367, 15.10432886, 14.6367906 , 14.22487352, 13.86937242, 13.57109241, 13.33084905, 13.14946851, 13.02778767, 12.96665432, 12.96692724, 13.02947643, 13.15518317, 13.34494025, 13.59965206, 13.92023482, 14.30761665, 14.76273783, 15.28655087, 15.88002074, 16.54412501, 17.27985405, 18.08821114, 18.97021273, 19.92688854, 20.9592818 , 22.06844941, 23.25546211, 24.52140468, 25.86737617, 27.29449001, 28.80387431, 30.39667196, 32.0740409 , 33.83715431, 35.68720081, 37.62538464, 39.65292597, 41.771061 , 43.98104227, 46.28413885, 48.68163654, 51.17483816, 53.76506374, 56.45365076, 59.24195442, 62.13134785, 65.12322238, 68.21898776, 71.42007248, 74.72792395, 78.14400881, 81.66981319, 85.30684298, 89.05662407, 92.9207027 , 96.90064567, 100.99804066, 105.21449652, 109.55164356]))
The Minos algorithm uses the profile likelihood method to compute (generally asymmetric) confidence intervals. This can be plotted
m.draw_mncontour('a', 'b', nsigma = 3)
return Minos error -0.00268629 , 0.00349823 return Minos error 0.015994 , -0.00774831 return Minos error 0.988189 , 1.01749 return Minos error 1.06021 , 0.964308 return Minos error 1.9791 , 2.04699 return Minos error 2.1372 , 1.91984
<matplotlib.contour.ContourSet at 0x7f72c014fcf8>
Access fit results
print(m.values,m.errors)
a_fit = m.values["a"]
b_fit = m.values["b"]
c_fit = m.values["c"]
<ValueView of Minuit at 2444778> a: 0.9034861278197065 b: -0.7151810261106413 c: 1.0059409448208796 <ErrorView of Minuit at 2444778> a: 0.0254794465138097 b: 0.05922262013629476 c: 0.021827289851835133
Prepare data to display fitted function
x_plot = np.linspace( 0.1, 4.5 , 100 )
y_fit = a_fit * np.exp(b_fit*x_plot) + c_fit
plot data and fit results with matplotlib
plt.figure()
plt.errorbar(x, y, dy , fmt="o")
plt.plot(x_plot, y_fit)
plt.title("iminuit exponential Fit")
plt.xlim(-0.1, 4.1)
plt.show()