0
$\begingroup$

I have read some of the threads in the forum and tried to fit my data using nonlinearmodelfit, but the fitting result doesn't match the data at all. I set the initial fitting parameter values according to the experimental data, however, the fitting parameters were too off, especiall tm, which should be way much smaller than 1. I am posting the function below and my codes, and would really appreciate anyone who can help me solve this.

The function is: enter image description here

where enter image description here is a Lorentzian distribution. Here is my code

ClearAll["Global`*"]
data = {{9.72762*10^-8, 0.27573624}, {1.9357175*10^-7,0.35856727}, {3.0400054*10^-7, 0.42113978}, {3.851921*10^-7,0.4413983}, {4.675645*10^-7, 0.45245874}, {7.664082*10^-7,0.529744}, {9.5011717*10^-7, 0.5628668}, {1.8910378*10^-6,0.6365067}, {2.9057892*10^-6, 0.7101052}, {6.445126*10^-6,0.75986505}, {0.000011039828, 0.796716}, {0.000057973855,0.8705107}, {0.000103733146, 0.8834713}, {0.00045879057, 0.9223119}, {0.0015340322, 0.93537235}, {0.007241259, 0.9540027}};
f[tm_?NumericQ, gamma_?NumericQ, t_?NumericQ] := Simplify[NIntegrate[(1 - Exp[-(t/tsw)^2])/tsw*PDF[CauchyDistribution[Log[tm], gamma], Log[tsw]], {tsw, 10^-20,Infinity},WorkingPrecision -> 16,MaxRecursion -> 500]]
nlm = NonlinearModelFit[data, {f[tm, gamma, t],tm > 0 && gamma > 0}, {{tm, 10^-5}, {gamma, 1}}, t]
nlm["BestFitParameters"]
Show[ListLogLinearPlot[data],LogLinearPlot[nlm[t], {t, 10^-7, 0.01}, PlotStyle -> Orange]]

The result is posted here as well. enter image description here

$\endgroup$
  • $\begingroup$ As an update, I tried to add more constraints to the fitting parameters, but ended up with many errors: nlm = NonlinearModelFit[data, {f[tm, gamma, t], 1 > tm > 0 && gamma > 0}, {{tm, 10^-5}, {gamma, 1}}, t]. $\endgroup$ – fermiano Jun 24 at 11:01
  • $\begingroup$ These are the errors: CauchyDistribution::realprm: Parameter -18.4207+3.14159 I at position 1 in CauchyDistribution[-18.4207+3.14159 I,12.9138] is expected to be real. NIntegrate::inumr: The integrand ((1-E^(-(<<23>>/tsw^2))) PDF[CauchyDistribution[-18.4207+3.14159 I,12.9138],<<1>>])/tsw has evaluated to non-numerical values for all sampling points in the region with boundaries {{1.000000000000000,1.000000000000000*10^-20}}. $\endgroup$ – fermiano Jun 24 at 11:02
4
$\begingroup$

There are three modifications that I would suggest:

  1. Use better starting values
  2. Fit using logtm rather than tm.
  3. Add in the option Method-> NMinimize, Method->"DifferentialEvolution"} to NonlinearModelFit.

Good starting values can make all the difference in the world. When there is lack of convergence or you get a really bad fit as you did, then exploring with ContourPlot when you have just two parameters can be helpful.

When parameters have a very wide range of scales, then including some scaling can be helpful. For example, if one parameter p1 has a value around 3 and another p2 has a value around 4000000, then reparameterize with 10^6 p2. Then p2 will have a value around 4. Sometimes (as in this case) replacing Log[tm] with a variable named logtm is a simple modification.

Using Method = NMinimize is many times more stable than the default method.

ClearAll["Global`*"]
data = {{9.72762*10^-8, 0.27573624}, {1.9357175*10^-7, 
    0.35856727}, {3.0400054*10^-7, 0.42113978}, {3.851921*10^-7, 
    0.4413983}, {4.675645*10^-7, 0.45245874}, {7.664082*10^-7, 
    0.529744}, {9.5011717*10^-7, 0.5628668}, {1.8910378*10^-6, 
    0.6365067}, {2.9057892*10^-6, 0.7101052}, {6.445126*10^-6, 
    0.75986505}, {0.000011039828, 0.796716}, {0.000057973855, 
    0.8705107}, {0.000103733146, 0.8834713}, {0.00045879057, 
    0.9223119}, {0.0015340322, 0.93537235}, {0.007241259, 0.9540027}};

f[logtm_?NumericQ, gamma_?NumericQ, t_?NumericQ] := 
 NIntegrate[(1 - Exp[-(t/tsw)^2])/tsw*PDF[CauchyDistribution[logtm, gamma], Log[tsw]], {tsw, 10^-20, Infinity}, WorkingPrecision -> 16, MaxRecursion -> 500]
nlm = NonlinearModelFit[data, {f[logtm, gamma, t], gamma > 0}, {{logtm, -14}, {gamma, 1.9}}, t, 
Method -> {NMinimize, Method -> "DifferentialEvolution"}];

nlm["BestFitParameters"]
(* {logtm -> -14.2019, gamma -> 1.90857} *)

Show[ListLogLinearPlot[data], 
 LogLinearPlot[nlm[t], {t, 10^-7, 0.01}, PlotStyle -> Orange]]

Data and fit

NonlinearModelFit took many minutes. Don't know how long. I got tired of waiting and went to breakfast. It was finished when I got back.

| improve this answer | |
$\endgroup$
  • $\begingroup$ thanks a lot for your suggestions. It finally worked, and really took a long time, with these error-like messages "NIntegrate::slwcon: Numerical integration converging too slowly; suspect one of the following: singularity, value of the integration is 0, highly oscillatory integrand, or WorkingPrecision too small." I know this fitting function is quite complicated, and maybe that's why it took ages to finish. Do you know any method to speed it up? $\endgroup$ – fermiano Jun 25 at 3:05
  • $\begingroup$ I would have to imagine the slowdown is with the NIntegrate portion. If it's a difficult integral, then you should ask that as a separate question where someone much more knowledgeable about such things than me could answer that. $\endgroup$ – JimB Jun 25 at 3:14

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.