Fit with multiple gaussians in multi-dimension

Hi,

what would be to best approach in writing a fit function that is the sum of an arbitrary number of gaussian functions in arbitrary dimensions (including co-variance).

I would try to work with vectors/matrices as much as possible, so this code should work with any dimension (assuming waves have the correct DimSize).

//multidim gauss with vectors and covariance matrix
//wVectorMu contains center of gaussian
//wMatrixCoVar is co-variance matrix
//wVectorVar is vector of variables, i.e. {x1, x2, x3}

MatrixOP /FREE intermediate1 = exp(-1/2 * ( (wVectorVar -wVectorMu)^t x Inv(wMatrixCoVar) x (wVectorVar -wVectorMu) ))
MatrixOP /FREE intermediate2 = intermediate1 * 1/(sqrt( powR(2*pi, numdims) * Det(wMatrixCoVar) ))
returnVal = intermediate2[0]



What is still missing is how to sum up these gaussians with weighing and how to put all the parameters (wWeight, wVectorMu, wMatrixCoVar [there are # of gaussian different ones for the later two]) into a FitFunc. As far as I understand it, only one parameter wave is allowed in functions of type FitFunc.


Cheers,
MG
Gaussians with covariance, etc., in arbitrary dimensions is pretty big task! I looked into three dimensions once and punted.

You could write a fit function that looks at the number of fit coefficients in the coefficient wave to compute the number of Gaussians to fit.

For the 2D case, if you are feeling adventurous, you could try the sum-of-fit-functions approach, and use the built-in Gauss2D fit function. If you do this, you need to hold the Y0 coefficient for all but one of the Gaussians.

John Weeks
WaveMetrics, Inc.
support@wavemetrics.com
Just in case someone hits this topic:

I somehow got this to work for 3D & arbitrary number of gaussian functions (called "states" in the code). The FitFunc looks like this:

//number of states is set by length of w
Function FitMultiGauss3D(w, x1, x2, x3) : FitFunc
WAVE w
    Variable x1
    Variable x2
    Variable x3
   
    Variable returnValue = 0
    Variable state
    Variable NumStates = numpnts(w)/13
    Variable NumDims = 3
   
    if (mod(numpnts(w), 13) != 0)
        Print "Check length of W_coef."
        Abort
    endif
   
    //CustomFitDialog/ Independent Variables 3
    //CustomFitDialog/ x1
    //CustomFitDialog/ x2
    //CustomFitDialog/ x3
    //CustomFitDialog/ Coefficients NumState*13
    //CustomFitDialog/ w[0+12*state,11+12*state] = wVectorMu, wMatrixCoVar
    //CustomFitDialog/ w[12*NumStates,12*NumStates+3] = wPi
   
   
    Duplicate /O/R=[0,12*NumStates-1] w, b_params
    Redimension /N=(3,4,NumStates) b_params
    Duplicate /O /R=[12*NumStates,12*NumStates+3] w, wPi
   
   
   
    for (state=0; state<NumStates; state+=1)
        //extract means Mu and covariance matrix
        Duplicate /FREE /R=[0,*][0][state] b_params, wVectorMu
        Redimension /N=(-1) wVectorMu      
        Duplicate /FREE /R=[0,*][1, *][state] b_params, wMatrixCoVar
        Redimension /N=(-1, -1) wMatrixCoVar
       
        //Make wVectorVar
        Make /O/N=3 wVectorVar={x1, x2, x3}
       
       
        //multidim gauss with vectors and covariance matrix
        //wVectorMu contains center of gaussian
        //wMatrixCoVar is co-variance matrix
        //wVectorVar is vector of variables, i.e. {x1, x2, x3}
        MatrixOP /FREE intermediate1 = exp(-1/2 * ( (wVectorVar -wVectorMu)^t x Inv(wMatrixCoVar) x (wVectorVar -wVectorMu) ))
        MatrixOP /FREE intermediate2 = intermediate1 * 1/(sqrt( powR(2*pi, NumDims) * Det(wMatrixCoVar) ))
       
        returnValue += intermediate2[0] * wPi[state]
    endfor
   
    return returnValue
End


The W_coef has a fixed format how the 13 parameters per gaussian function are sorted. This helps extracting the vector of the center of the gaussian (wVectorMu) and the covariance matrix by just Redimension the appropriate range of the W_coef.

The fit is called by FuncFitMD /N /W=2 /NTHR=0 FitMultiGauss3D, W_coef, DataWave, but it is painfully slow.