#!/usr/bin/env python # Author : Pierre Schnizer """ The python equivalent of the C example found in the GSL Reference document. The function run_fsolver shows how to use the fdfsolvers (e.g. lsmder). """ import Numeric import random import pygsl from pygsl import multifit_nlin import copy exp = Numeric.exp def testfunc(t, A = 1., lambda_ = .1, b=.5): return A * exp(- lambda_ * t) + b def exp_f(x, params): A = x[0] lambda_ = x[1] b = x[2] t = params[0] yi = params[1] sigma = params[2] Yi = testfunc(t, A, lambda_, b) f = (Yi -yi) / sigma return f def exp_df(x, params): A = x[0] lambda_ = x[1] b = x[2] t = params[0] yi = params[1] sigma = params[2] e = exp(-lambda_ * t) e_s = e/sigma df = Numeric.array((e_s, -t * A * e_s, 1/sigma)) df = Numeric.transpose(df) return df def exp_fdf(x, params): f = exp_f(x, params) df = exp_df(x, params) return f, df def run_fdfsolver(): A = 1. lambda_ = .1 b = .5 n = 40 p = 3 t = Numeric.arange(n); y = testfunc(t, A, lambda_, b) sigma = Numeric.ones(n) * 0.1 data = Numeric.array((t,y,sigma), Numeric.Float) mysys = multifit_nlin.gsl_multifit_function_fdf(exp_f, exp_df, exp_fdf, data, n,p) solver = multifit_nlin.lmsder(mysys, n, p) #solver = multifit_nlin.lmder(mysys, n, p) x = Numeric.array((1.0, 0.0, 0.0)) solver.set(x) print "# Testing solver ", solver.name() print "# %5s %9s %9s %9s %10s" % ("iter", "A", "lambda", "b", "|f(x)|") for iter in range(20): status = solver.iterate() x = solver.getx() dx = solver.getdx() f = solver.getf() J = solver.getJ() tdx = multifit_nlin.gradient(J, f) status = multifit_nlin.test_delta(dx, x, 1e-8, 1e-8) fn = Numeric.sqrt(Numeric.sum(f*f)) if status == 0: print "# Convereged :" if status == 0: break print " %5d % .7f % .7f % .7f % .7f" %(iter, x[0], x[1], x[2], fn) else: raise ValueError, "Number of Iterations exceeded!" J = solver.getJ() covar = multifit_nlin.covar(solver.getJ(), 0.0) print "# A = % .5f +/- % .5f" % (x[0], covar[0,0]) print "# lambda = % .5f +/- % .5f" % (x[1], covar[1,1]) print "# b = % .5f +/- % .5f" % (x[2], covar[2,2]) if __name__ == '__main__': run_fdfsolver()