The sum of functions S - curve that is fitted to data - is itself a
function. The value of the whole sum is computed as a sum of functions,
like Gaussians or polynomials, and can be given by formula:
,
where fi is a function of x, and
depends on a vector of parameters a. This vector contains all
fitted parameters.
Because we often have the situation, that the error
in the x coordinate of data points can be modeled with function z(x; a),
we introduce this term to sum:
where
. Note that the same z(x) is used in all functions.
Now we will have a closer look at fi functions. Every function fi has a type chosen from function types available in program. One of these types is the Gaussian. It has the following formula:
a0 is a height of peak, a1 - position of center and a2 - half width at half maximum. Every of these parameters can be:
a constant parameter - a constant real number.
a simple parameter - a real number, that can be changed.
compound parameter - a function of parameters, eg. sum of two simple parameters or product of constant and simple parameter. I called it g-parameter (this name will be changed to more meaningful in future). A g-parameter is of course different from functions fi. The basic difference is that g-parameter is not a function of x.
Functions fi are called f-functions. See the list of available f-function types in Appendix C, List of functions.
Functions zi(x;a) are called zero-shifts. This name is not precise (FIXME: what is a better name? calibration function? instrumental function?). The simplest of them has a formula: z = a0 and can be used for modeling error of shifting zero in instrument. In general case, so-called zero-shifts are parametrized functions of x, like f-functions.
Every f-function, zero-shift and g-parameter has its type and its parameters - the number of its parameters is determined by the type. Two examples:
Gaussian is a type of f-function, and f-function of this type has 3 parameters: a0, a1 and a2 (see formula above).
One of g-parameter types is division: a0/a1. A g-parameter of this type contains two parameters.
F-functions, zero-shifts, g-parameters and simple-parameters are elements of a sum. Every sort of element has a symbol: f-function (^), zero-shift (<), g-parameter ($) and simple-parameter (@). Every f-function contained in the sum has a number assigned, that allows referring to this f-function. If there is only one f-function defined, it has number 0. If there are two f-functions, the first has number 0 and the second 1. As you will see further in this chapter, commands refer to f-functions using symbol (^) and number, eg. ^0 or ^15. The same about other sorts of elements: first zero-shift is referred to as <0, fifth simple-parameter - as @4, etc.
Three kinds of parameters were described above. They are used in f-functions, zero-shifts and g-parameters, and are denoted in adequate formulae as ai. Note, that actually only simple-parameters are fitted. The term parameter used in context of fitting and the term vector of parameters refer to simple-parameters only.
Every simple parameter has a value and, optionally, domain. Command
creates simple-parameter equal p. Once created, the parameter will be given a number (first available), say m, and later can be referred to as @m. Domain is used only by fitting algorithms, when they need to randomly initialize variable, or change it. In some cases only width of domain is needed. Domain must be enclosed by square brackets. It can be specified in three ways:
[a:b] -- from a to b,
[a +- b] -- from a-b to a+b,
and [ +- b] -- from v-b to v+b, where v is the value of simple parameter.
If domain of parameter is not defined, it is assumed to be [v - r v, v + r v], where v is the value of simple parameter and r is the value of option default-relative-domain-width.
F-functions, zero-shifts and g-parameters can be created using command:
where t is a letter denoting type of f-function, zero-shift or g-parameter (respectively ^t, <t or $t). It is followed by parameters in number required for given type of object. Parameters can be given as:
@n - existing simple parameter, eg. @15,
$n - existing g-parameter, eg. $15,
_p - constant value, eg. _3.14159,
~p - simple parameter created on-the-fly, eg. ~3.2
In particular, a g-parameter can be defined as a function of another g-parameters. As a result of it, every parameter of f-function (eg. of Lorentzian function) can be an arbitrary combination of simple parameters. You can learn about available types using command s.info described below.
Every f-function, zero-shift, g-parameter or simple-parameter, that was created (added), can also be removed. The only condition is, that there are no references to it. It is obvious - you can not remove a simple parameter, that represents a height of a peak, before removing the peak. The syntax of command is straightforward:
n is the number of f-function, zero-shift, g-parameter or simple-parameter. It can be replaced with an asterisk(*). Command s.remove ^3 will remove ^3, and s.remove ^* will remove all f-functions. To avoid gaps in numeration, all larger numbers are decreased by one. If f-function ^3 is removed, ^9 will become ^8 and ^4 will become ^3. All references are properly updated. If option recursive-remove is set, also parameters, in our example parameters of ^3, will be removed.
Information about every element of the sum can be obtained using command:
And informations about available types of f-functions, zero-shifts and g-parameters can be displayed with:
t is a letter that stands for type, eg. ^G means f-function Gaussian. If type is not specified, list of all available types will be displayed.
The whole sum or selected f-functions can be saved to file in various formats with command:
where t is a letter that stands for format of file: f - mathematical formula, d - xy points, p - peak listing, x - XFIT peak listing (used by some crystallographic software), s - fityk script. + will cause, if specified file exist, appending to the file rather than overwritting.
Value and domain of simple parameters can be changed with command:
p is a new value of @n, or, if % is given, new value is equal to p% of current value. domain is specified in the same way as in command s.add. If domain is not given, it is not changed.
Vector of simple parameters is a subject to change in a fitting process. Sometimes it is useful to refine only selected parameters. The parameters that are not to be refined are called frozen. You can freeze and unfreeze parameters with command:
This command will freeze @n if exclamation mark (!) is not present and unfreeze if it is present. To freeze or unfreeze all parameters, use asterisk(*) instead of n. Example: s.freeze @*, ! @0, ! @3 causes, that only @0 and @3 would be fitted. To display information about currently frozen parameters, just type:
Every change of values of parameters is remembered. It is remembered since last adding or removing simple parameter operation. You can display history of changes with command:
and move to selected position in history with command:
Without sign - you will move to n-th position, with plus(+) or minus(-) - you will go n steps forward or backward. The history is similar to a history in web browser - if you move backward and then add a new entry, eg. by fitting, last entries of history will be erased. In some cases it can be reasonable to fit curve with one method, move back to initial parameters, fit with another method and compare results. To make this comparison easier, you can save result obtained with first method using command:
The command toggles saved and not saved state of history item, what means that using it second time on the same item will allow to delete it. If n is not specified, current history item is used.
Now it is time to explain how value of the sum and its derivatives are computed. You may skip it and read next chapter, if you are not interested.
All fitting methods involve computing value of the sum S(x) for x = x1 x2 ..., xN and such series of computations are repeated multiple times, for different parameter vectors. x1 x2 ..., xN are x coordinates of active data points. In typical cases N >> 1, therefore, when thinking about time consumed by computations, only operations executed for every point matter.
At the beginning of every series of S(x) computations values of g-parameters and some expressions in f-functions, that do not depend on x, are computed. Then S(x) value of every f-function and zero-shift is computed in every point. To speedup computations, tails of peaks, that are very small, can be neglected. This can be controlled with two options: cut-tails and cut-tails-level. If option cut-tails is set, at the beginning of each series of computations, for every peak, points, where the peak has value approximately equal to value of cut-tails-level option, are computed. Outside of these points, value of the peak function is assumed to be zero.
Most commonly used nonlinear fitting methods (in our program Levenberg-Marquard) are using first derivatives of functions. The program knows derivative formulae for all types of f-functions, zero-shifts and g-functions, but it can also use numerical differentiation. If is useful only for testing the program. Numerical differentiation is used when option numerical-d is set. If option numerical-d-both-sides is set, it uses formula df(x)/dx=(f(x+h)-f(x-h))/2h, otherwise df(x)/dx=(f(x+h)-f(x))/h. h is computed as value of option numerical-d-rel-change multiplied by x.
A value either of the whole sum or of a an element of the sum, and all appropriate derivatives can be viewed using command:
eg. s.value ^0 41.5. With asterisk(*), derivatives, computed symbolically and numerically are shown and compared, what is useful for program developers.