-
Notifications
You must be signed in to change notification settings - Fork 12
/
lm_fitter_test.py
executable file
·72 lines (54 loc) · 2.02 KB
/
lm_fitter_test.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
"""
Fit Multiple Data Sets
======================
Fitting multiple (simulated) Gaussian data sets simultaneously.
All minimizers require the residual array to be one-dimensional. Therefore, in
the ``objective`` we need to ```flatten``` the array before returning it.
TODO: this should be using the Model interface / built-in models!
"""
import spinmob as _s
import numpy as _n
from scipy.optimize import leastsq
from lmfit import Parameters, minimize, report_fit
sigma = 17
dof = 100
N = 1000
# Functions that return the residuals in a 1D array
def residuals_lmfit(parameters): return (parameters['y']-ydata)/sigma
def residuals_leastsq(y ): return (y -ydata)/sigma
# My fitter
f = _s.data.fitter(autoplot=False)
f.set_functions('a', 'a')
# Parameters container for lmfit
p_lmfit = Parameters()
p_lmfit.add('y', value=1.0)
p_lmfit.add('x', vary=False)
# Run the fitter many times
ys_leastsq = [] # fit y-values
es_leastsq = [] # fit errorbars
ys_lmfit = [] # fit y-values
es_lmfit = [] # fit errorbars
ys_me = []
es_me = []
for n in range(N):
# Data
xdata = _n.linspace( 0, 1,dof+1)
ydata = _n.random.normal(0,sigma,dof+1)
# Do the fit
results_lmfit = minimize(residuals_lmfit, p_lmfit)
results_leastsq = leastsq (residuals_leastsq, 1, full_output=True)
f.set_data(xdata, ydata, sigma).fit()
# Record the results
ys_lmfit.append(results_lmfit.params['y'].value)
es_lmfit.append(results_lmfit.params['y'].stderr)
ys_leastsq.append(results_leastsq[0][0])
es_leastsq.append(results_leastsq[1][0][0]**0.5)
ys_me.append(f.results[0][0])
es_me.append(f.results[1][0][0]**0.5)
a1 = _s.pylab.subplot(211)
a2 = _s.pylab.subplot(212)
_s.plot.xy.data(None, [ys_lmfit, es_lmfit, ys_me, es_me], axes=a1)
n,b,p = a2.hist(ys_lmfit, alpha=0.5)
_s.plot.xy.function('N*db/(s*sqrt(2*pi))*exp(-0.5*x**2/s**2)',
min(ys_leastsq), max(ys_leastsq),
g=dict(s=sigma/dof**0.5, N=N, db=b[1]-b[0]), clear=0, axes=a2)