In [1]:
from IPython.display import Image
Image(filename='minimize.png', width=500, height=500)
Out[1]:
In [2]:
import numpy as np
import matplotlib.pyplot as plt
%matplotlib inline
In [3]:
x= np.array([0.,1.,2.,3.])
data = np.array([1.3,1.8,5.,10.7])
Lets visualize how a quadratic curve fits to it:
In [4]:
plt.scatter(x,data)
xarray=np.arange(-1,4,0.1)
plt.plot(xarray, xarray**2,'r-') # Not the best fit
plt.plot(xarray, xarray**2+1,'g-')
Out[4]:
Lets build a general quadratic model:
In [5]:
def get_residual(vars,x, data):
a= vars[0]
b=vars[1]
model =a* x**2 +b
return data-model
In [6]:
vars=[1.,0.]
print get_residual(vars,x,data)
print sum(get_residual(vars,x,data))
In [7]:
vars=[1.,1.]
print sum(get_residual(vars,x,data))
In [8]:
vars=[2.,0.]
print sum(get_residual(vars,x,data))
In [9]:
from scipy.optimize import leastsq
vars = [0.,0.]
out = leastsq(get_residual, vars, args=(x, data))
print out
In [10]:
vars=[1.06734694, 0.96428571]
print sum(get_residual(vars,x,data)**2)
In [12]:
vars=[1.06734694, 0.96428571]
plt.scatter(x,data)
xarray=np.arange(-1,4,0.1)
plt.plot(xarray, xarray**2,'r-')
plt.plot(xarray, xarray**2+1,'g-')
fitted = vars[0]* xarray**2 +vars[1]
plt.plot(xarray, fitted,'b-')
Out[12]:
Ease of changing fitting algorithms. Once a fitting model is set up, one can change the fitting algorithm used to find the optimal solution without changing the objective function.
Improved estimation of confidence intervals. While scipy.optimize.leastsq() will automatically calculate uncertainties and correlations from the covariance matrix, the accuracy of these estimates are often questionable. To help address this, lmfit has functions to explicitly explore parameter space to determine confidence levels even for the most difficult cases.
Improved curve-fitting with the Model class. This extends the capabilities of scipy.optimize.curve_fit(), allowing you to turn a function that models for your data into a python class that helps you parametrize and fit data with that model.
Many pre-built models for common lineshapes are included and ready to use.
In [13]:
from lmfit import minimize, Parameters
params = Parameters()
params.add('amp', value=0.)
params.add('offset', value=0.)
def get_residual(params,x, data):
amp= params['amp'].value
offset=params['offset'].value
model =amp* x**2 +offset
return data-model
out = minimize(get_residual, params, args=(x, data))
In [14]:
dir(out)
Out[14]:
In [121]:
out.params
Out[121]:
In [122]:
dir(out.params)
Out[122]:
In [125]:
out.params.values
Out[125]:
In [126]:
out.__dict__
Out[126]:
In [132]:
out.params['amp'].__dict__
Out[132]:
In [15]:
params['amp'].vary = False
In [16]:
out = minimize(get_residual, params, args=(x, data))
In [17]:
print out.params
In [18]:
print out.chisqr
In [19]:
params['amp'].value = 1.0673469387778385
In [20]:
out = minimize(get_residual, params, args=(x, data))
print out.chisqr
In [21]:
def get_residual(params,x, data):
#amp= params['amp'].value
#offset=params['offset'].value
#xoffset=params['xoffset'].value
parvals = params.valuesdict()
amp = parvals['amp']
offset = parvals['offset']
model =amp* x**2 +offset
return data-model
In [22]:
params = Parameters()
params.add('amp', value=0.)
#params['amp'] = Parameter(value=..., min=...)
params.add('offset', value=0.)
params.add('xoffset', value=0.0, vary=False)
out = minimize(get_residual, params, args=(x, data))
In [23]:
print out.params
In [24]:
Image(filename='output.png', width=500, height=500)
Out[24]:
In [25]:
params['offset'].min = -10.
params['offset'].max = 10.
In [26]:
out = minimize(get_residual, params, args=(x, data))
print out.params
In [27]:
print out.params['amp'].stderr
In [28]:
print out.params['amp'].correl
In [29]:
from lmfit import minimize, Parameters, Parameter, report_fit
result = minimize(get_residual, params, args=(x, data))
In [31]:
help(report_fit)
In [32]:
# write error report
report_fit(result.params)
In [21]:
Image(filename='fitting.png', width=500, height=500)
Out[21]:
In [33]:
result2 = minimize(get_residual, params, args=(x, data), method='tnc')
report_fit(result2.params)
In [34]:
result3 = minimize(get_residual, params, args=(x, data), method='powell')
report_fit(result3.params)
In [35]:
print(report_fit(result3))
In [36]:
params.add('amp2', expr='(amp-offset)**2')
def get_residual(params,x, data):
#amp= params['amp'].value
#offset=params['offset'].value
#xoffset=params['xoffset'].value
parvals = params.valuesdict()
amp = parvals['amp']
offset = parvals['offset']
amp2 = parvals['amp2']
model =amp* x**2 + amp2*x**4 +offset
return data-model
In [37]:
result4 = minimize(get_residual, params, args=(x, data))
report_fit(result4.params)
In [ ]: