Vector
error = data_vec.fit(fit_vec,"fcn",indep_vec,&p1,[&p2],...,[&pN])
data_vec
and the approximation generated by the user-supplied "fcn"
applied to the elements of indep_vec
.
fcn must take one argument which is the main independent variable followed by one or more arguments which are tunable parameters which will be optimized. Thus the arguments to .fit following "fcn" should be completely analogous to the arguments to fcn itself. The difference is that the args to fcn must all be scalars while the corresponding args to .fit will be a vector object (for the independent variable) and pointers to scalars (for the remaining parameters).
The results of a call to .fit are three-fold. First, the parameters
of best fit are returned by setting the values of the variables p1 to
pN (possible because they are passed as pointers). Second, the values
of the vector fit_vec are set to the fitted function. If fit_vec
is
not passed with the same size as indep_vec
and data_vec
, it is resized
accordingly. Third, the mean squared error between the fitted
function and the data is returned by .fit
. The .fit()
call may be
reiterated several times until the error has reached an acceptable
level.
Care must be taken in selecting an initial set of parameter values. Although you need not be too close, wild discrepancies will cause the simplex algorithm to give up. Values of 0 are to be avoided. Trial and error is sometimes necessary.
Because calls to hoc have a high overhead, this procedure can be
rather slow. Several commonly-used functions are provided directly
in c code and will work much faster. In each case, if the name below
is used, the builtin function will be used and the user is expected to
provide the correct number of arguments (here denoted a,b,c
...).
"exp1": y = a * exp(-x/b) "exp2": y = a * exp(-x/b) + c * exp (-x/d) "charging": y = a * (1-exp(-x/b)) + c * (1-exp(-x/d)) "line": y = a * x + b "quad": y = a * x^2 + b*x + c
An alternative implementation of the simplex fitting algorithm is in the scopmath library.
The following example demonstrates the strategy used by the simplex fitting algorithm to search for a minimum. The location of the parameter values is plotted on each call to the function. The sample function has a minimum at the point (1, .5)
objref g, dvec, fvec, ivec g = new Graph() g.size(0,3,0,3) func fun() {local f if ($1 == 0) { g.line($2, $3) g.flush() print $1, $2, $3 } return ($2 - 1)^2 +($3-.5)^2 } dvec = new Vector(2) fvec = new Vector(2) fvec.fill(1) ivec = new Vector(2) ivec.indgen() a = 2 b = 1 g.beginline() error = dvec.fit(fvec, "fun", ivec, &a, &b) print a, b, error