* 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.
master
wirawan 14 years ago
parent 592d6bd7c9
commit bceef1e601
  1. 52
      math/fitting.py

@ -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 # wpylib.math.fitting module
# Created: 20100120 # Created: 20100120
@ -117,9 +117,12 @@ class Poly_order4(Poly_base):
for i in xrange(len(x)) ]) for i in xrange(len(x)) ])
class fit_result(dict):
pass
def fit_func(Funct, Data=None, Guess=None, x=None, y=None, def fit_func(Funct, Data=None, Guess=None, x=None, y=None,
debug=10, debug=10,
outfmt=1,
method='leastsq', opts={}): method='leastsq', opts={}):
""" """
Performs a function fitting. 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. size of y data below.
For a 2-D fitting, for example, x should be a column array. 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 Inspect Poly_base, Poly_order2, and other similar function classes in this
module to see the example of the Funct function. 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. (multidimensional) coordinate of the Funct's domain.
y is a one-dimensional dataset. y is a one-dimensional dataset.
Or, 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 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: # We want to minimize this error:
if Data != None: # an alternative way to specifying x and y if Data != None: # an alternative way to specifying x and y
y = Data[0] y = Data[0]
x = Data[1:] # possibly multidimensional! 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 # Try to provide an initial guess
# This is an older version with y-only argument
Guess = Funct.Guess(y) Guess = Funct.Guess(y)
elif Guess == None: # VERY OLD, DO NOT USE ANYMORE! elif Guess == None: # VERY OLD, DO NOT USE ANYMORE!
Guess = [ y.mean() ] + [0.0, 0.0] * len(x) Guess = [ y.mean() ] + [0.0, 0.0] * len(x)
if debug < 20:
fun_err = lambda CC, xx, yy: abs(Funct(CC,xx) - yy) 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) 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: if debug >= 5:
print "Guess params:" print "Guess params:"
@ -175,6 +198,15 @@ def fit_func(Funct, Data=None, Guess=None, x=None, y=None,
full_output=1, full_output=1,
**opts **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': elif method == 'anneal':
rslt = anneal(fun_err2, rslt = anneal(fun_err2,
x0=Guess, # initial coefficient guess x0=Guess, # initial coefficient guess
@ -182,15 +214,25 @@ def fit_func(Funct, Data=None, Guess=None, x=None, y=None,
full_output=1, full_output=1,
**opts **opts
) )
keys = ('xopt', 'fopt', 'T', 'funcalls', 'iter', 'accept', 'retval')
else: else:
raise ValueError, "Unsupported minimization method: %s" % method 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_fit_rslt = rslt
last_chi_sqr = fun_err2(rslt[0], x, y)
if (debug >= 10): if (debug >= 10):
#print "Fit-message: ", rslt[] #print "Fit-message: ", rslt[]
print "Fit-result:" print "Fit-result:"
print "\n".join([ "%2d %s" % (ii, rslt[ii]) for ii in xrange(len(rslt)) ]) print "\n".join([ "%2d %s" % (ii, rslt[ii]) for ii in xrange(len(rslt)) ])
if debug >= 1:
print "params = ", rslt[0] print "params = ", rslt[0]
print "chi square = ", last_chi_sqr / len(y) print "chi square = ", last_chi_sqr / len(y)
if outfmt == 1:
return rslt[0] return rslt[0]
else:
rec = fit_result()
for (k, v) in zip(keys, rslt):
rec[k] = v
rec['chi_square'] = chi_sqr
return rec

Loading…
Cancel
Save