fitting log normal

Hello

I would like to fit a lognormal curve to my data. Igor can do it, but it uses it's weird equation for fitting and it's confounding to extract sigma, miu values. 

I created my own fitting function that uses the "normal" log-normal expression and I can't fit it to my data points. Here is the expression:

f(x) = (B/(S*x*(2*PI)^0.5))*EXP(-((LN(x)-M)^2)/(2*(S)^2))

where M is miu and S is sigma,

What is wrong with this expression? Why can't it fit?

 

Here are the parameters from fitting using igor's lognormal equation

  fit_wave1= W_coef[0]+W_coef[1]*exp(-(ln(x/W_coef[2])/W_coef[3])^2)
  W_coef={1.5577,58.237,33.619,0.44161}
  V_chisq= 3.27861e-15;V_npnts= 199;V_numNaNs= 0;V_numINFs= 0;
  V_startRow= 0;V_endRow= 198;
  W_sigma={3.59e-10,1.13e-09,2.42e-10,1.06e-11}
  Coefficient values ± one standard deviation
  	y0   	= 1.5577 ± 3.59e-10
  	A    	= 58.237 ± 1.13e-09
  	x0   	= 33.619 ± 2.42e-10
  	width	= 0.44161 ± 1.06e-11

How do I change A,x0 and width into more commonly known values?

 Why can't it fit?

 

Have you tried if your user defined function produces the desired curve shape?

You are confusing the use of second wave iks for the x axis and the x value of a wave itself. Look for help on the SetScale operation.

make/N=101/D igrek
SetScale/P x 0,0.1,"", igrek
display igrek
igrek = (1/(4*x*(2*Pi)^0.5))*exp(-((ln(x) - 0)^2)/(2*(0.25)^2))

testlognormal.png

not sure if line 10 does what you expect: you have x and iks on the right-hand-side and the are not the same. I assume you want only one of them.

But how does your user-defined fit function look like that is created by the curve fitting dialogue?

 

you should have something like 

Function myLogNormal(w,x) : FitFunc
    Wave w
    Variable x

    //CurveFitDialog/ These comments were created by the Curve Fitting dialog. Altering them will
    //CurveFitDialog/ make the function less convenient to work with in the Curve Fitting dialog.
    //CurveFitDialog/ Equation:
    //CurveFitDialog/ f(x) = (1 / (x * sigma * sqrt(2*pi))) * exp(-(ln(x) - mu)^2/ (2 * sigma^2) )
    //CurveFitDialog/ End of Equation
    //CurveFitDialog/ Independent Variables 1
    //CurveFitDialog/ x
    //CurveFitDialog/ Coefficients 2
    //CurveFitDialog/ w[0] = sigma
    //CurveFitDialog/ w[1] = mu

    return (1 / (x * w[0] * sqrt(2*pi))) * exp(-(ln(x) - w[1])^2/ (2 * w[0]^2) )
End

you can test the validity:

make/D fitCheck
SetScale x 0, 10, FitCheck
Make/D testCoefs ={0.25,1}
FitCheck = myLogNormal(testCoefs,x)
display fitCheck

 

Yes you are right. I used both x and "iks" wave in the equation.

Regardless the equation in correct:

Y = (1/(0.25*x*(2*Pi)^0.5))*exp(-((ln(x) - 0)^2)/(2*(0.25)^2))

or

Y = (1/(0.25*iks*(2*PI)^0.5))*EXP(-((LN(iks)-0)^2)/(2*(0.25)^2))

And it produces lognormal distribution.

But that is beside the point. I can fit using igor's lognormal fitting, but I can't extract commonly used parameters. I read the help file, but the parameters I get, don't make any sense.

 

igor explanation.png

In reply to by ChrLie

ChrLie wrote:

you should have something like 

Function myLogNormal(w,x) : FitFunc
    Wave w
    Variable x

    //CurveFitDialog/ These comments were created by the Curve Fitting dialog. Altering them will
    //CurveFitDialog/ make the function less convenient to work with in the Curve Fitting dialog.
    //CurveFitDialog/ Equation:
    //CurveFitDialog/ f(x) = (1 / (x * sigma * sqrt(2*pi))) * exp(-(ln(x) - mu)^2/ (2 * sigma^2) )
    //CurveFitDialog/ End of Equation
    //CurveFitDialog/ Independent Variables 1
    //CurveFitDialog/ x
    //CurveFitDialog/ Coefficients 2
    //CurveFitDialog/ w[0] = sigma
    //CurveFitDialog/ w[1] = mu

    return (1 / (x * w[0] * sqrt(2*pi))) * exp(-(ln(x) - w[1])^2/ (2 * w[0]^2) )
End

you can test the validity:

make/D fitCheck
SetScale x 0, 10, FitCheck
Make/D testCoefs ={0.25,1}
FitCheck = myLogNormal(testCoefs,x)
display fitCheck

 

 

Thank you, but it doesn't work. It requires initial coefficient values and fails to fit the line.

Certainly you will need initial guesses. Otherwise you are asking to fit the equation starting from nothing. Or, equivalently, you are asking Igor to find the right answer from an infinite possibility of answers. Igor is smart, but not all knowing.

Post your example data set in the experiment that you used. It seems that somehow your problem is more complex than simply a mistake in the fitting function itself.

Also, I might address some sense of negative undertones in your postings (with apologies if you don't overtly mean them in this way). As far as extracting "commonly used parameters", consider an alternate. In spectroscopy, the Gaussian distribution is defined for a peak is defined by position, peak height, and peak full width at half maximum. In probability, the distribution uses mean, standard deviation, and area. Which one should you want us to have WaveMetrics define as "common"? And should the other half of the community raise an outcry when their choice is not provided?

Here are the parameters from fitting using igor's lognormal equation

  fit_wave1= W_coef[0]+W_coef[1]*exp(-(ln(x/W_coef[2])/W_coef[3])^2)
  W_coef={1.5577,58.237,33.619,0.44161}

 

If I plot the results from Igors curve fit, it does not look like it can be fitted with, say 0.5 and 1, as initial guesses in myLogNormal (although I don't know what the x-scaling of fit_wave1 is). 

Can there be some scaling issues with your data?

In reply to by Innuendo

The answer is in the help file screenshot that you posted.

Function logn(w,x) : FitFunc
    Wave w
    Variable x

    //CurveFitDialog/ These comments were created by the Curve Fitting dialog. Altering them will
    //CurveFitDialog/ make the function less convenient to work with in the Curve Fitting dialog.
    //CurveFitDialog/ Equation:
    //CurveFitDialog/ variable mu = ln(x0) + w^2/2
    //CurveFitDialog/ variable sigma = w/sqrt(2)
    //CurveFitDialog/ variable B = A*x0*sigma*sqrt(2*pi)/exp(-w^2/4)
    //CurveFitDialog/
    //CurveFitDialog/
    //CurveFitDialog/ f(x) = y0 + B/(x*sigma*sqrt(2*pi))*exp(-(ln(x) - mu)^2/(2*sigma^2))
    //CurveFitDialog/ End of Equation
    //CurveFitDialog/ Independent Variables 1
    //CurveFitDialog/ x
    //CurveFitDialog/ Coefficients 4
    //CurveFitDialog/ w[0] = A
    //CurveFitDialog/ w[1] = w
    //CurveFitDialog/ w[2] = x0
    //CurveFitDialog/ w[3] = y0

    variable mu = ln(w[2]) + w[1]^2/2
    variable sigma = w[1]/sqrt(2)
    variable B = w[0]*w[2]*sigma*sqrt(2*pi)/exp(-w[1]^2/4)
   
   
    return w[3] + B/(x*sigma*sqrt(2*pi))*exp(-(ln(x) - mu)^2/(2*sigma^2))
End

this uses the lognormal PDF equation and produces the same curve as the lognormal fit function.

you can do the same thing in reverse if you want to use sigma and mu as fit coefficients.

In reply to by tony

Function logn(w,x) : FitFunc
    Wave w
    Variable x

    //CurveFitDialog/ These comments were created by the Curve Fitting dialog. Altering them will
    //CurveFitDialog/ make the function less convenient to work with in the Curve Fitting dialog.
    //CurveFitDialog/ Equation:
    //CurveFitDialog/ variable width = sqrt(2)*sigma
    //CurveFitDialog/ variable x0 = exp(mu - width^2/2)
    //CurveFitDialog/ variable A = 1/x0 * exp(-(width^2/4)) * B/(sigma*sqrt(2*pi))
    //CurveFitDialog/
    //CurveFitDialog/ f(x) = y0 + A * exp(- (ln(x/x0)/width)^2 )
    //CurveFitDialog/ End of Equation
    //CurveFitDialog/ Independent Variables 1
    //CurveFitDialog/ x
    //CurveFitDialog/ Coefficients 4
    //CurveFitDialog/ w[0] = y0
    //CurveFitDialog/ w[1] = B
    //CurveFitDialog/ w[2] = mu
    //CurveFitDialog/ w[3] = sigma
   
    int usePDF = 1

    if (usePDF)
        return w[0] + w[1]/(x*w[3]*sqrt(2*pi))*exp(-(ln(x) - w[2])^2/(2*w[3]^2))
    else
        variable width = sqrt(2)*w[3]
        variable x0 = exp(w[2] - width^2/2)
        variable A = 1/x0 * exp(-(width^2/4)) * w[1]/(w[3]*sqrt(2*pi))
        return w[0] + A * exp(- (ln(x/x0)/width)^2 )
    endif
   
End
y0   	= 1.5577
B    	= 1609.1
mu   	= 3.6126
sigma	= 0.31227

edit: I changed the fit function so that you can switch between the two equations and see for yourself that the results are the same.

An Igor experiment file with a data set you are trying to fit and your fitting function would allow us to more fully investigate your problem. It seems like Tony has provided you with a pretty good answer.