fitting log normal
Innuendo
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?
Have you tried if your user defined function produces the desired curve shape?
March 24, 2022 at 04:54 am - Permalink
Yes; the equation is a proper lognormal density function.
Here is when I input B=1, miu=0, sigma=0.25. It creates a proper curve.
March 24, 2022 at 05:54 am - Permalink
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.
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))
March 24, 2022 at 06:19 am - Permalink
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?
March 24, 2022 at 06:22 am - Permalink
you should have something like
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:
SetScale x 0, 10, FitCheck
Make/D testCoefs ={0.25,1}
FitCheck = myLogNormal(testCoefs,x)
display fitCheck
March 24, 2022 at 06:34 am - Permalink
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.
March 24, 2022 at 06:35 am - Permalink
In reply to you should have something… by ChrLie
Thank you, but it doesn't work. It requires initial coefficient values and fails to fit the line.
March 24, 2022 at 06:49 am - Permalink
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?
March 24, 2022 at 07:25 am - Permalink
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?
March 24, 2022 at 07:28 am - Permalink
In reply to Yes you are right. I used… by Innuendo
The answer is in the help file screenshot that you posted.
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.
March 24, 2022 at 07:28 am - Permalink
In reply to The answer is in the help… by tony
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
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.
March 24, 2022 at 08:21 am - Permalink
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.
March 24, 2022 at 09:46 am - Permalink