The truth is rarely pure and never simple

comparison of data fitting on a complicated function

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):

fitting results for the same data but different programs

So far, I have to stick to less complicated functions…