Syntax C/C++ | #include <MFstd.h>
int MF_multiLinfit( fVector A, iVector AStatus, unsigned npars, MF_EXPERIMENT *ListOfExperiments, unsigned nexperiments,
void (*funcs)(fVector BasFuncs, float x, float y, unsigned nfuncs, unsigned iexperiment) );
int MF_multiLinfitwW( fVector A, fMatrix Covar, iVector AStatus, unsigned npars, MF_EXPERIMENT *ListOfExperiments, unsigned nexperiments,
void (*funcs)(fVector BasFuncs, float x, float y, unsigned nfuncs, unsigned iexperiment) );
int MF_multiLinfitwEdit( fVector A, iVector AStatus, unsigned npars, MF_EXPERIMENT *ListOfExperiments, unsigned nexperiments, float thresh,
void (*funcs)(fVector BasFuncs, float x, float y, unsigned nfuncs, unsigned iexperiment) );
int MF_multiLinfitwWwEdit( fVector A, fMatrix Covar, iVector AStatus, unsigned npars, MF_EXPERIMENT *ListOfExperiments, unsigned nexperiments, float thresh,
void (*funcs)(fVector BasFuncs, float x, float y, unsigned nfuncs, unsigned iexperiment) ); |
Pascal/Delphi | uses MFstd;
function MF_multiLinfit( A:fVector; AStatus:iVector; nParameters:UInt; ListOfExperiments: PMF_EXPERIMENT; nexperiments:UInt; funcs: Pointer ): IntBool;
function MF_multiLinfitwW( A:fVector; Covar:fMatrix; AStatus:iVector; nParameters:UInt; ListOfExperiments: PMF_EXPERIMENT; nexperiments:UInt; funcs: Pointer ): IntBool;
function MF_multiLinfitwEdit( A:fVector; AStatus:iVector; nParameters:UInt; ListOfExperiments: PMF_EXPERIMENT; nexperiments:UInt; thresh:Single; funcs: Pointer ): IntBool;
function MF_multiLinfitwWwEdit( A:fVector; Covar:fMatrix; AStatus:iVector; nParameters:UInt; ListOfExperiments: PMF_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,
z = a0f0(x,y) + a1f1(x,y) + a2f2(x,y)...
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 MF_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 MF_EXPERIMENT. Let us assume you have two sets of X-Y-Z data, each with the vectors X and Y for the independent variables, the matrix MZ for the z=f(x,y) values and, for MF_multiLinfitwW, the weights of all points in MInvVar. The matrix dimensions are htZ (equal to sizeY) and lenZ (equal to sizeX). Now you have to construct a list of experiments as in the following example:
| Constructing list of experiments in C/C++ |
MF_EXPERIMENT ExpList[2];
ExpList[0].X = X1; ExpList[0].Y = Y1;
ExpList[0].MZ = MZ1;
ExpList[0].htZ = htZ1; ExpList[0].lenZ = lenZ1;
ExpList[1].X = X1; ExpList[1].Y = Y2;
ExpList[1].MZ = MZ2;
ExpList[1].htZ = htZ2; ExpList[1].lenZ = lenZ2;
/* for the weighted variant, set additionally: */
ExpList[0].MInvVar = MInvVar1;
ExpList[0].WeightOfExperiment = wt1;
ExpList[1].MInvVar = MInvVar2;
ExpList[1].WeightOfExperiment = wt2;
| Constructing list of experiments in Pascal/Delphi |
var ExpList: array[0..1] of MF_EXPERIMENT;
begin
...
ExpList[0].X := X1; ExpList[0].Y := Y1;
ExpList[0].MZ := MZ1;
ExpList[0].htZ := htZ1; ExpList[0].lenZ := lenZ1;
ExpList[1].X := X2; ExpList[1].Y := Y2;
ExpList[1].MZ := MZ2;
ExpList[1].htZ := htZ2; ExpList[1].lenZ := lenZ2;
(* for the weighted variant, set additionally: *)
ExpList[0].MInvVar := MInvVar1;
ExpList[0].WeightOfExperiment := wt1;
ExpList[1].MInvVar := MInvVar2;
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,y) 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, float y, unsigned nfuncs, unsigned iexperiment )
{
BasFuncs[0] = f0( x, y );
BasFuncs[1] = f1( x, y );
...
}
and shall be passed to MF_multiLinfit by calling
MF_multiLinfit( A, AStatus, npars, ExpList, 2, MyFunc );
| Model function for Pascal/Delphi |
procedure MyFunc( BasFuncs:fVector; x, y:Single; nfuncs, iexperiment:UInt );
begin
VF_Pelement( BasFuncs, 0 )^ := f0( x, y );
VF_Pelement( BasFuncs, 1 )^ := f1( x, y );
...
end;
This model function shall be passed to MF_multiLinfit by calling
MF_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 MF_multiLinfit allows to distinguish between parameters that are common to all experiments and others that belong to individual experiments. For example, each experiment's MZ values might be shifted by a constant C. In this case, A has to contain as many shifts Ci as there are experiments. In MyFunc, you would have to code this as (in C/C++; you will easily translate this into Pascal/Delphi yourself):
if( iexperiment == 0 ) { BasFuncs[2] = 1; BasFuncs[3] = 0; }
else {BasFuncs[2] = 0; BasFuncs[3] = 1; }
The functions f0( x,y ) 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, MF_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 /MF_multiLinfit etc. Rather than repeatedly changing the default value, use the "wEdit" variants of VF / MF_multiLinfit, namely VF / MF_multiLinfitwEdit, VF / MF_multiLinfitwWwEdit etc.
In the rare case of failure, this function returns 1 (TRUE) and sets all A[i] = 0. |
|