1
$\begingroup$

I believe I have encountered a case in Mathematica where the FindFit function is not able to capture the fitting parameter value even when the starting value is approximately equal to the best-fit paremeter value.

I have data I am trying to fit:

data = {{0., 1.}, {0.0001, 0.0946391}, {0.0002, 0.050354}, {0.0003, 
  0.034469}, {0.0004, 0.0262545}, {0.0005, 0.0212236}, {0.0006, 
  0.0178217}, {0.0007, 0.0153659}, {0.0008, 0.0135088}, {0.0009, 
  0.0120546}, {0.001, 0.0108848}, {0.0011, 0.00992321}, {0.0012, 
  0.00911858}, {0.0013, 0.00843532}, {0.0014, 0.00784783}, {0.0015, 
  0.00733724}, {0.0016, 0.00688935}, {0.0017, 0.00649325}, {0.0018, 
  0.00614043}, {0.0019, 0.00582415}, {0.002, 0.005539}, {0.0021, 
  0.00528059}, {0.0022, 0.00504532}, {0.0023, 0.00483021}, {0.0024, 
  0.00463277}, {0.0025, 0.0044509}, {0.0026, 0.00428282}, {0.0027, 
  0.00412703}, {0.0028, 0.00398222}, {0.0029, 0.00384727}, {0.003, 
  0.00372119}, {0.0031, 0.00360315}, {0.0032, 0.0034924}, {0.0033, 
  0.00338827}, {0.0034, 0.0032902}, {0.0035, 0.00319767}, {0.0036, 
  0.00311021}, {0.0037, 0.00302743}, {0.0038, 0.00294896}, {0.0039, 
  0.00287446}, {0.004, 0.00280365}, {0.0041, 0.00273626}, {0.0042, 
  0.00267204}, {0.0043, 0.00261077}, {0.0044, 0.00255226}, {0.0045, 
  0.00249633}, {0.0046, 0.0024428}, {0.0047, 0.00239152}, {0.0048, 
  0.00234236}, {0.0049, 0.00229519}, {0.005, 0.00224988}, {0.0051, 
  0.00220634}, {0.0052, 0.00216445}, {0.0053, 0.00212413}, {0.0054, 
  0.00208529}, {0.0055, 0.00204785}, {0.0056, 0.00201173}, {0.0057, 
  0.00197686}, {0.0058, 0.00194319}, {0.0059, 0.00191065}, {0.006, 
  0.00187919}, {0.0061, 0.00184874}, {0.0062, 0.00181927}, {0.0063, 
  0.00179073}, {0.0064, 0.00176307}, {0.0065, 0.00173626}, {0.0066, 
  0.00171025}, {0.0067, 0.00168501}, {0.0068, 0.00166051}, {0.0069, 
  0.00163671}, {0.007, 0.00161359}, {0.0071, 0.00159111}, {0.0072, 
  0.00156925}, {0.0073, 0.00154798}, {0.0074, 0.00152729}, {0.0075, 
  0.00150714}, {0.0076, 0.00148752}, {0.0077, 0.0014684}, {0.0078, 
  0.00144977}, {0.0079, 0.00143161}, {0.008, 0.0014139}, {0.0081, 
  0.00139662}, {0.0082, 0.00137976}, {0.0083, 0.00136331}, {0.0084, 
  0.00134724}, {0.0085, 0.00133155}, {0.0086, 0.00131622}, {0.0087, 
  0.00130124}, {0.0088, 0.0012866}, {0.0089, 0.00127228}, {0.009, 
  0.00125828}, {0.0091, 0.00124459}, {0.0092, 0.00123119}, {0.0093, 
  0.00121808}, {0.0094, 0.00120524}, {0.0095, 0.00119267}, {0.0096, 
  0.00118037}, {0.0097, 0.00116831}, {0.0098, 0.0011565}, {0.0099, 
  0.00114493}, {0.01, 0.00113358}}

This data, above, is basically a type of exponential decay with y-intercept at 1.

The fitting function I am using is:

fit[a_,T_] = 1/(1 + 9.58814*10^7 T^(3/2))

A quick plot of the data and the fitting function shows that the fitting parameter, a, should be relatively close to 2*10^-2.

Show[
     data,
     Plot[
          fit[0.02,T], {T, 0, 0.01}, 
          PlotStyle -> Red
          ]
 ]

which gives

enter image description here

However, even when providing a starting value of 0.02 in the FindFit function, Mathematica is still not able to find a best-fit value...

FindFit[
        data,
        fit[a,T],
        {
        {a, 0.02}
        },
        T
        ][[1]]

which yields the error

FindFit::fmgz: Encountered a gradient that is effectively zero. The result returned may not be a minimum; it may be a maximum or a saddle point.
a -> 0.02

Is this a fundamental flaw in the fitting procedure used by FindFit, or is there something I'm neglecting to incorporate into the function FindFit?

$\endgroup$
3
  • $\begingroup$ Correction: the plot code should read...Show[ ListPlot[data], Plot[ fit[0.02,T], {T, 0, 0.01}, PlotStyle -> Red ] ] $\endgroup$
    – KirkLab
    Aug 25, 2022 at 10:36
  • 5
    $\begingroup$ Your function: fit[a_,T_] does not depend on a $\endgroup$ Aug 25, 2022 at 10:41
  • $\begingroup$ Please provide the function you actually used. Also, the first point {0.,1.} which corresponds to the restriction that the function be 1 at time 0 is usually not a real data point (i.e., it typically is "assumed" rather than "measured"). If that's the case, it should be removed from the rest of the data. $\endgroup$
    – JimB
    Aug 25, 2022 at 13:42

2 Answers 2

3
$\begingroup$

For the data, f = 1/(a + b*T) fits well.

Clear[f,a,b,sol];
f = 1/(a + b*T);
sol = FindFit[data, f, {a, b}, T];
Show[ListPlot[data], Plot[f /. sol, {T, 0, .01}, PlotStyle -> Red]]

enter image description here

If we remove the first of the data,then we can use f = 1/(a + b*T^c)

Clear[f, fit];
f = 1/(a + b*T^c);
fit = NonlinearModelFit[Rest@data, f, {a, b, {c, .5}}, T]
Show[ListPlot[data], Plot[Normal@fit, {T, 0, 0.01}, PlotStyle -> Red]]

enter image description here enter image description here

$\endgroup$
1
$\begingroup$

In short: the model is completely inadequate for the data and FindFit worked just fine.

It appears that your model is

fit[a_, T_] := 1/(1 + a 9.58814*10^7 T^(3/2))

When you plot the data against fit[0.2, T] (where you have chosen 0.2 for the parameter I assume for the reason because it overestimates roughly equally to the underestimates to the left and right, respectively, of the middle of the predictor values), you get a very wrong picture of that fit because you don't show the first 8 data points. (The first point {0, 1} isn't really a data point but something the model demands.) Here's what that figure should look like with the appropriate result from FindFit given the model you chose:

fit[a_, T_] := 1/(1 + a 9.58814*10^7 T^(3/2))

results = FindFit[data[[2 ;;]], fit[a, T], a, T]
(* {a -> 0.0858187} *)

Show[ListPlot[data[[2 ;;]], PlotRange -> {All, {0, 0.1}}, ImageSize -> Large],
 Plot[{fit[0.02, t], fit[a /. results, t]}, {t, 0, 0.01},
  PlotStyle -> {Red, Green}, PlotRange -> All,
  PlotLegends -> {"Wrong fit", "Correct fit"}]]

Data and right and wrong fit

When finding the fit that minimizes the sum of squares, the points with the smallest T values have much more influence on the curve chosen. The root mean squares of the two fits are as follows:

(* a = 0.02  *)
Sqrt[((data[[2 ;;, 2]] - fit[0.02, data[[2 ;;, 1]]])^2 // Total)/(Length[data] - 2)]
(* 0.0281204 *)

(* a = result from `FindFit` *)
Sqrt[((data[[2 ;;, 2]] - fit[a /. results, data[[2 ;;, 1]]])^2 // Total)/(Length[data] - 2)]
(* 0.00401312 *)

The guess of 0.02 for a results in a root mean square error of about 7 times that of the result from FindFit.

In short: the model is completely inadequate for the data and FindFit worked just fine.

To describe the data in an adequate compact form, use @cvgmt 's answer.

$\endgroup$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

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