* Adding more methods for fitting: fmin (simplex minimization).
I still have hard time making fitting routine work for me. But at least this one works for simple SHO fitting.
This commit is contained in:
@@ -1,4 +1,4 @@
|
||||
# $Id: fitting.py,v 1.2 2010-05-28 18:43:39 wirawan Exp $
|
||||
# $Id: fitting.py,v 1.3 2010-11-05 02:28:20 wirawan Exp $
|
||||
#
|
||||
# wpylib.math.fitting module
|
||||
# Created: 20100120
|
||||
@@ -117,9 +117,12 @@ class Poly_order4(Poly_base):
|
||||
for i in xrange(len(x)) ])
|
||||
|
||||
|
||||
class fit_result(dict):
|
||||
pass
|
||||
|
||||
def fit_func(Funct, Data=None, Guess=None, x=None, y=None,
|
||||
debug=10,
|
||||
outfmt=1,
|
||||
method='leastsq', opts={}):
|
||||
"""
|
||||
Performs a function fitting.
|
||||
@@ -137,6 +140,9 @@ def fit_func(Funct, Data=None, Guess=None, x=None, y=None,
|
||||
size of y data below.
|
||||
For a 2-D fitting, for example, x should be a column array.
|
||||
|
||||
The "y" array is a 1-D array of length M, which contain the "measured"
|
||||
value of the function at every domain point given in "x".
|
||||
|
||||
Inspect Poly_base, Poly_order2, and other similar function classes in this
|
||||
module to see the example of the Funct function.
|
||||
|
||||
@@ -146,23 +152,40 @@ def fit_func(Funct, Data=None, Guess=None, x=None, y=None,
|
||||
(multidimensional) coordinate of the Funct's domain.
|
||||
y is a one-dimensional dataset.
|
||||
Or,
|
||||
* via Data argument (which is a multi-column dataset
|
||||
* via Data argument (which is a multi-column dataset, where the first row
|
||||
is the "y" argument).
|
||||
|
||||
"""
|
||||
global last_fit_rslt, last_chi_sqr
|
||||
from scipy.optimize import leastsq, anneal
|
||||
from scipy.optimize import fmin, leastsq, anneal
|
||||
# We want to minimize this error:
|
||||
if Data != None: # an alternative way to specifying x and y
|
||||
y = Data[0]
|
||||
x = Data[1:] # possibly multidimensional!
|
||||
if hasattr(Funct, "Guess"):
|
||||
if hasattr(Funct, "Guess_xy"):
|
||||
# Try to provide an initial guess
|
||||
Guess = Funct.Guess_xy(x, y)
|
||||
elif hasattr(Funct, "Guess"):
|
||||
# Try to provide an initial guess
|
||||
# This is an older version with y-only argument
|
||||
Guess = Funct.Guess(y)
|
||||
elif Guess == None: # VERY OLD, DO NOT USE ANYMORE!
|
||||
Guess = [ y.mean() ] + [0.0, 0.0] * len(x)
|
||||
|
||||
fun_err = lambda CC, xx, yy: abs(Funct(CC,xx) - yy)
|
||||
fun_err2 = lambda CC, xx, yy: numpy.sum(abs(Funct(CC,xx) - yy)**2)
|
||||
if debug < 20:
|
||||
fun_err = lambda CC, xx, yy: abs(Funct(CC,xx) - yy)
|
||||
fun_err2 = lambda CC, xx, yy: numpy.sum(abs(Funct(CC,xx) - yy)**2)
|
||||
else:
|
||||
def fun_err(CC, xx, yy):
|
||||
ff = Funct(CC,xx)
|
||||
r = abs(ff - yy)
|
||||
print " err: %s << %s << %s, %s" % (r, ff, CC, xx)
|
||||
return r
|
||||
def fun_err2(CC, xx, yy):
|
||||
ff = Funct(CC,xx)
|
||||
r = numpy.sum(abs(ff - yy)**2)
|
||||
print " err: %s << %s << %s, %s" % (r, ff, CC, xx)
|
||||
return r
|
||||
|
||||
if debug >= 5:
|
||||
print "Guess params:"
|
||||
@@ -175,6 +198,15 @@ def fit_func(Funct, Data=None, Guess=None, x=None, y=None,
|
||||
full_output=1,
|
||||
**opts
|
||||
)
|
||||
keys = ('xopt', 'cov_x', 'infodict', 'mesg', 'ier')
|
||||
elif method == 'fmin':
|
||||
rslt = fmin(fun_err2,
|
||||
x0=Guess, # initial coefficient guess
|
||||
args=(x,y), # data onto which the function is fitted
|
||||
full_output=1,
|
||||
**opts
|
||||
)
|
||||
keys = ('xopt', 'fopt', 'iter', 'funcalls', 'warnflag', 'allvecs')
|
||||
elif method == 'anneal':
|
||||
rslt = anneal(fun_err2,
|
||||
x0=Guess, # initial coefficient guess
|
||||
@@ -182,15 +214,25 @@ def fit_func(Funct, Data=None, Guess=None, x=None, y=None,
|
||||
full_output=1,
|
||||
**opts
|
||||
)
|
||||
keys = ('xopt', 'fopt', 'T', 'funcalls', 'iter', 'accept', 'retval')
|
||||
else:
|
||||
raise ValueError, "Unsupported minimization method: %s" % method
|
||||
chi_sqr = fun_err2(rslt[0], x, y)
|
||||
last_chi_sqr = chi_sqr
|
||||
last_fit_rslt = rslt
|
||||
last_chi_sqr = fun_err2(rslt[0], x, y)
|
||||
if (debug >= 10):
|
||||
#print "Fit-message: ", rslt[]
|
||||
print "Fit-result:"
|
||||
print "\n".join([ "%2d %s" % (ii, rslt[ii]) for ii in xrange(len(rslt)) ])
|
||||
print "params = ", rslt[0]
|
||||
print "chi square = ", last_chi_sqr / len(y)
|
||||
return rslt[0]
|
||||
if debug >= 1:
|
||||
print "params = ", rslt[0]
|
||||
print "chi square = ", last_chi_sqr / len(y)
|
||||
if outfmt == 1:
|
||||
return rslt[0]
|
||||
else:
|
||||
rec = fit_result()
|
||||
for (k, v) in zip(keys, rslt):
|
||||
rec[k] = v
|
||||
rec['chi_square'] = chi_sqr
|
||||
return rec
|
||||
|
||||
|
||||
Reference in New Issue
Block a user