Currently, I’m interested in fitting data on some rather strange functions. Sometimes, I don’t even know the exact function, so I expected the solution to be easier in case I come up with a complicated function and sufficient free parameters and let the computer do the fitting. The sample data is generated by
import math, random for i in range(-200, 200): x = i/10.0 print x, 3*math.exp(-(x-2)**2)+0.01*x+.02*x**2+2*math.sin(x/2)*math.cos(x/3)+0.3*(0.5-random.random())
Even if you do not know python, you will be able to guess what example function I’m writing about. Did I already mention that the functions are rather strange ones? Now I tried three fitting approaches: odrpack/python (hey – great to read software documentation for a package nearly as old as I am), grace and gnuplot. For the first package, I had to write another script which is based on the documentation:
#!/usr/bin/python from scipy.odr import odrpack as o import sys, math, scipy, numpy data = [x.strip().split(' ') for x in sys.stdin.readlines() if len(x) > 2 if x[0] != '#'] x = [float(e[0]) for e in data] y = [float(e[1]) for e in data] def strange(params, x): return params[0]*numpy.exp(-(x-params[1])**2)+params[2]*x+params[3]*x**2+params[4]*numpy.sin(x/params[5])*numpy.cos(x/params[6]) model = o.Model(strange) data = o.Data(x, y) myodr = o.ODR(data, model, beta0=[1, 1, 0.01, 0.01, 1, 1, 1], maxit=10000) myoutput = myodr.run() myoutput.pprint() for i in range(0, 7): print 'p{0}={1}'.format(i, myoutput.beta[i])
All programs got the correct order of magnitude for each of the parameters in case they offered the possibility of defining some initial values. Now, here are the results (click for a more appropriate size):
So far, I have to stick to less complicated functions…