April 14, 2007

Writing fitting functions for lmfit

lmfit expects
fitting functions with prototypes in the form:




double
function_name(double, double *);





For example:




double
sin_fit(double t, double * p)


{


return p[0] + p[1] * sin ( 2 * M_PI * ( p[2] * t + p[3]));


}





Note that while "font:12px Courier, mono;">lm_minimize takes a
pointer to an array of parameters, it may not always pass
that pointer to the fitting function. Because of this
passing fixed parameters to the fitting function using the
3rd argument will yield incorrect results. For example, the
following code is wrong:




double
wrong_fit(double t, double *p)


{


return p[0]*p[0] + p[1];


}




....




double p[2];




p[0] = 1;


p[1] = magic_number;




...




lm_minimize(..., 1, p, ..., ..., ...., ...);




Here the fitting function "font:12px Courier, mono;">wrong_fit relies on a
fixed parameter "font:12px Courier, mono;">p[1] which it expects to
contain the value "font:12px Courier, mono;">magic_number. However it
will be passed such a "font:12px Courier, mono;">p that only "font:12px Courier, mono;">p[0] has a valid value
and p[1] is
undefined. This will lead to incorrect operation.




To work around this, you can use global variables, as
follows:




double magic =
magic_number;




...




double right_fit(double t, double * p)


{


return p[0]*p[0] + magic;


}




....




double p = 1;




...




lm_minimize(..., 1, &p, ..., ..., ..., ...);





Cheers,

Steve