VF_multiLinfit
| VD_multiLinfit |
VE_multiLinfit |
VF_multiLinfitwW |
VD_multiLinfitwW |
VE_multiLinfitwW |
|
Function | fit multiple X-Y data sets to a common model function, linear in its parameters |
|
Syntax C/C++ | #include <MFstd.h>
int VF_multiLinfit( fVector A, iVector AStatus, unsigned npars, VF_EXPERIMENT *ListOfExperiments, unsigned nexperiments,
void (*funcs)(fVector BasFuncs, float x,unsigned nfuncs, unsigned iexperiment) );
int VF_multiLinfitwW( fVector A, fMatrix Covar, iVector AStatus, unsigned npars, VF_EXPERIMENT *ListOfExperiments, unsigned nexperiments,
void (*funcs)(fVector BasFuncs, float x, unsigned nfuncs, unsigned iexperiment) );
int VF_multiLinfitwEdit( fVector A, iVector AStatus, unsigned npars, VF_EXPERIMENT *ListOfExperiments, unsigned nexperiments, float thresh,
void (*funcs)(fVector BasFuncs, float x,unsigned nfuncs, unsigned iexperiment) );
int VF_multiLinfitwWwEdit( fVector A, fMatrix Covar, iVector AStatus, unsigned npars, VF_EXPERIMENT *ListOfExperiments, unsigned nexperiments, float thresh,
void (*funcs)(fVector BasFuncs, float x, unsigned nfuncs, unsigned iexperiment) ); |
Pascal/Delphi | uses MFstd;
function VF_multiLinfit( A:fVector; AStatus:iVector; nParameters:UInt; ListOfExperiments: PVF_EXPERIMENT; nexperiments:UInt; funcs: Pointer ): IntBool;
function VF_multiLinfitwW( A:fVector; Covar:fMatrix; AStatus:iVector; nParameters:UInt; ListOfExperiments:PVF_EXPERIMENT; nexperiments:UInt; funcs:Pointer ): IntBool;
function VF_multiLinfitwEdit( A:fVector; AStatus:iVector; nParameters:UInt; ListOfExperiments: PVF_EXPERIMENT; nexperiments:UInt; thresh:Single; funcs: Pointer ): IntBool;
function VF_multiLinfitwWwEdit( A:fVector; Covar:fMatrix; AStatus:iVector; nParameters:UInt; ListOfExperiments:PVF_EXPERIMENT; nexperiments:UInt; thresh:Single; funcs:Pointer ): IntBool; |
|
Description | The input data, contained in ListOfExperiments, are used to evaluate the parameters ai of a general linear function,
y = a0f0(x) + a1f1(x) + a2f2(x)...
The parameters ai are returned in the vector A.
Arguments:
A | vector of size npars; returns the coefficients |
Covar | matrix of dimensions [npars, npars]; returns the covariances of the coefficients. If the covariances are not needed, one may call the function with Covar=NULL / nil. |
AStatus | vector of size npars; decides which parameters are treated as free or as fixed |
npars | total number of parameters |
ListOfExperiments | input data, see chap. 13.4 |
nexperiments | number of data sets in ListOfExperiments |
funcs | user-defined model function |
Your model function may actually contain more parameters than you wish to treat as adjustable. This is why you have to provide an additional vector, AStatus, which contains the necessary information about which parameters are to be held fixed at their input values (AStatus[i] = 0) and which are free (AStatus[i] = 1). Any fixed parameters must be initialized in A prior to calling VF_multiLinfit. The argument npars denotes the total number of parameters in A (not only the free parameters!).
The input data must be combined into sets of the type VF_EXPERIMENT. Assuming you have two sets of X-Y data, contained in the vectors X1, Y1 (and, for VF_multiLinfitwW, InvVar1) of size1 elements, and X2, Y2 (and InvVar2) of size2 elements, you have to construct a list of experiments as in the following example:
| Constructing list of experiments in C/C++ |
VF_EXPERIMENT ExpList[2];
ExpList[0].X = X1; ExpList[0].Y = Y1; ExpList[0].size = size1;
ExpList[1].X = X2; ExpList[1].Y = Y2; ExpList[1].size = size2;
/* for the weighted variant, set additionally: */
ExpList[0].InvVar = InvVar1; ExpList[0].WeightOfExperiment = wt1;
ExpList[1].InvVar = InvVar2; ExpList[1].WeightOfExperiment = wt2;
| Constructing list of experiments in Pascal/Delphi |
var ExpList: array[0..1] of VF_EXPERIMENT;
begin
...
ExpList[0].X := X1; ExpList[0].Y := Y1;
ExpList[0].size := size1;
ExpList[1].X := X2; ExpList[1].Y := Y2;
ExpList[1].size := size2;
(* for the weighted variant, set additionally: *)
ExpList[0].InvVar := InvVar1;
ExpList[0].WeightOfExperiment := wt1;
ExpList[1].InvVar := InvVar2;
ExpList[1].WeightOfExperiment := wt2;
...
end;
| Both C/C++ and Pascal/Delphi |
You must provide a model function "funcs" which, for any argument x, must calculate the individual basis functions fi(x) and store them in a vector BasFuncs. The model function has to be defined as
| Model function for C/C++ |
void MyFunc( fVector BasFuncs, float x, unsigned nfuncs, unsigned iexperiment )
{
BasFuncs[0] = f0( x );
BasFuncs[1] = f1( x);
...
}
and shall be passed to VF_multiLinfit by calling
VF_multiLinfit( A, AStatus, npars, ExpList, 2, MyFunc );
| Model function for Pascal/Delphi |
procedure MyFunc( BasFuncs:fVector; x:Single; nfuncs, iexperiment:UInt );
begin
VF_Pelement( BasFuncs, 0 )^ := f0( x );
VF_Pelement( BasFuncs, 1 )^ := f1( x );
...
end;
This model function shall be passed to VF_multiLinfit by calling
VF_multiLinfit( A, AStatus, npars, @ExpList, 2, @MyFunc );
Note the address-of operators in front of "ExpList" (static Pascal array passed to OptiVec function) and "MyFunc." (pointer to the function MyFunc). In Turbo Pascal, the model function must be compiled with the Force-Far-Calls option {$F+}.
| Both C/C++ and Pascal/Delphi |
The argument iexperiment with which MyFunc shall be called by VF_multiLinfit allows to distinguish between parameters that are common to all experiments and others that belong to individual experiments. For example, each experiment's Y values might be shifted by a constant C. In this case, A has to contain as many shifts C as there are experiments. In MyFunc, you would have to code this as (in C/C++; you will easily translate this into Pascal/Delphi):
if( iexperiment == 0 ) { BasFuncs[2] = 1; BasFuncs[3] = 0; }
else {BasFuncs[2] = 0; BasFuncs[3] = 1; }
The functions f0( x ) etc. must not contain the parameters ai. In the weighted variant, the matrix MCovar will be filled with the covariances of the parameters ai on output: MCovari,j = covariance( ai, aj ). Internally, VF_multiLinfit employs a Singular Value Decomposition algorithm to obtain a solution even for (near-)singular linear systems. Thereby, coefficients ai whose significance is lower than a threshold, Thresh, are set to 0 instead of infinity. The default threshold can be modified by calling VF_setLinfitNeglect. The current threshold can be retrieved by VF_getLinfitNeglect. As VF_setLinfitNeglect is not thread-safe, this function should not be used to set different thresholds for different calls to VF_multiLinfit etc. Rather than repeatedly changing the default value, use the "wEdit" variants of VF_multiLinfit, namely VF_multiLinfitwEdit, VF_multiLinfitwWwEdit etc.
In the rare case of failure, this function returns 1 (TRUE) and sets all A[i] = 0. |
|
Return value | FALSE (0), if no error occurred, otherwise TRUE (non-zero). |
|
|