In response to a recent enquiry about non-linear regression here are the
definitions for a routine that can be used.
I have not had time to set this all up correctly as a package with
contexts etc. and have only briefly tested it.
Therefore, use at your own peril.
Given a function f = F[x,y,...,a,b,...] of several variables x,y,...
which also depends on a number of parameters a,b,... and a list of data
data = { {x1,y1,...,f1}, {x2,y2,...,f2}, ... } the routine attempts to
find the values of a,b,... which minimizes the sum of the squares of the
residuals.
The only restriction on F[] is that Mathematica must be able to calculate
symbolic derivatives of F with respect to a,b,....
An initial estimate of the paramters is required and the routine returns
a "better" estimate of the parameters. If the original estimate is good
enough, repeating the process will eventually produce a converged result.
The definitions follow:
LinearFit[list_,fun_,f0_,var_] :=Block[{n,n2,m,b},
n = Length[list];
n2 = Length[fun];
m = Table[
Sum[ (fun[[j]] fun[[k]] /.
Thread[var -> Drop[list[[i]],-1]]), {i,1,n}],
{j,1,n2}, {k,1,n2}];
b = Table[
Sum[ (fun[[j]] (list[[i,-1]]-f0) /.
Thread[var -> Drop[list[[i]],-1]]), {i,1,n}],
{j,1,n2}];
LinearSolve[m,b]
]
NonLinearFit[list_,fun_,par_,init_,var_]:=
Block[{npar,sub,linfun,f0,coeff},
npar = Length[par];
sub = Thread[par -> init];
linfun = Table[ D[ fun, par[[i]] ], {i,1,npar}] /.sub;
f0 = fun /. sub;
coeff = LinearFit[list,linfun,f0,var];
init+coeff
]
The routine is used as follows:
data = { {x1,y1,..,f1}, {x2,y2,...,f2}, ...};
function = F[x,y,...,a,b,...]; (* whatever function you are fitting *)
pars = {a,b,... };
initialestimate = {a0, b0, ... }; (* reasonable values for the parameters *)
vars = {x,y,...};
estimate = NonLinearFit[data,function,pars,initialestimate,vars]
estimate = NonLinearFit[data,function,pars,estimate,vars] (*keep repeating*)
Alternatively one can use FixedPoint
estimate = FixedPoint[NonLinearFit[data,function,pars,#,vars]&,initialestimate]
Leon Poladian
Theoretical Physics
University of Sydney
leon at extro.ucc.su.oz