9
$\begingroup$

I am trying to fit my data to the following function,

$$\frac{a b t \left(\log \left(\frac{-a d t+a t-1}{a d t}\right)-2\right)}{4 (a t-1)}-c$$

data = {
    {0.275, 23.85}, {0.275, 22.03}, {0.2613, 21.13}, {0.2888, 20.77}, {0.3438, 18.71}, 
    {0.2475, 17.7}, {0.3301, 17.65}, {0.3163, 16.79}, {0.3713, 17.09}, {0.3851, 14.92},
    {0.4126, 14.37}, {0.4401, 12}, {0.3851, 11.7}, {0.4813, 11.14}, {0.4538, 10.64}, 
    {0.4676, 10.08}, {0.4951, 9.63}, {0.4951, 8.975}, {0.5639, 8.42}, {0.6601, 8.571},
    {0.5914, 7.311}, {0.5088, 7.613}, {0.5088, 7.361}, {0.5776, 6.756}, {0.7564, 6.807},
    {0.6464, 6.303}, {0.7426, 5.597}, {0.7014, 5.496}, {0.6189, 5.395}, {0.6464, 4.992},
    {0.7289, 4.891}, {0.7426, 4.437}, {0.8802, 4.689}, {0.8664, 4.235}, {0.7976, 3.933},
    {0.9077, 3.58}, {0.8664, 2.975}, {0.9627, 3.076}, {0.9352, 2.672}, {1.073, 2.773}, 
    {1.018, 2.269}, {1.073, 1.966}, {1.155, 2.218}, {1.169, 1.714}, {1.293, 1.866}, 
    {1.279, 1.613}, {1.306, 1.361}, {1.458, 1.563}, {1.458, 1.008}, {1.54, 1.059}, 
    {1.623, 1.261}, {1.788, 1.059}, {1.719, 1.16}, {1.802, 0.9076}, {2.008, 0.7563}, 
    {2.09, 0.8571}, {2.159, 1.008}, {2.242, 0.605}, {2.31, 0.6555}, {2.407, 0.8067}, 
    {2.544, 0.8067}, {2.599, 0.6555}, {2.682, 0.4538}, {2.792, 0.7563}, {2.888, 0.4034},
    {2.929, 0.7563}, {3.246, 0.5546}, {3.356, 0.4538}, {3.479, 0.4538}, {3.906, 0.4034},
    {4.029, 0.4538}, {4.181, 0.3529}, {4.332, 0.2521}, {4.621, 0.2521}, {4.855, 0.2521},
    {5.088, 0.3025}, {5.185, 0.3025}, {5.804, 0.3025}, {6.546, 0.3025}
};

using the following code:

nlm = NonlinearModelFit[
    data,
    {-c+(a b t (-2+Log[(-1+a t-a d t)/(a d t)]))/(4 (-1+a t)),a>0,b>0,c>0,d>0},
    {{a,10},{b,20},{c,36},{d,0.0001}},
    t
]

It gives me following fit which is obviously not correct,

$$\frac{50. t \left(\log \left(\frac{100. (9.99 t-1)}{t}\right)-2\right)}{10. t-1}-36.$$

Mathematica fit

I tried manually varying parameters and I can come up with the following fit,

Fit with real data

With parameters $a=10$, $b=20$, $c=36.5$, $d=0.0001$.

But I want to do it using Mathematica and find the right parameters for a proper fit and not just do it by trial and error.

$\endgroup$
2
  • 1
    $\begingroup$ Your model seems to very sensitive the initial search value of parameter d. I get a much better fit starting with d = 1/200. $\endgroup$
    – m_goldberg
    Mar 2, 2014 at 18:17
  • $\begingroup$ @m_goldberg that reduces the correlations between the parameters significantly and hence produces a result with far smaller errors. However, the end result is still not very good. $\endgroup$ Mar 2, 2014 at 19:05

1 Answer 1

23
$\begingroup$

I think as much discussion as can reasonably be had on this issue has already taken place on this site, although the solution might not be readily apparent without the benefit of experience. This is not in any way meant as a criticism of the question (which is well-posed and relates to a commonly-encountered, important issue), but rather will be my excuse for presenting a synthesis of two of my existing answers without very much accompanying discussion. If anything is unclear after reviewing the previous posts, please point it out and I will try to clarify matters.

You might already have found the question entitled Problem with NonlinearModelFit, and more specifically my answer in which I advocate using differential evolution when obtaining reasonable values for the parameters proves too difficult otherwise. This is especially important when performing constrained fits, for which the nonlinear interior point method is used by default. This normally has great difficulty in locating global minima simply on account of being constrained strictly to the feasible region.

The advice is equally valid in this case, but unfortunately leads immediately to problems due to the particular form of your model, which produces a complex result for certain values of the parameters. To avoid that, we may use the TransformedFit`/ComplexFit` package. I still have to update that answer with the latest changes, but in the mean time you can get the latest version of the notebook (not the package file, which also has yet to be updated) from the git repository.

Run the package as it appears in the notebook. Then, after defining data as in your question:

fit = ComplexFit[data,
  {
   model = -c + (a b t (-2 + Log[(-1 + a t - a d t)/(a d t)]))/(4 (-1 + a t)),
   TransformedParameter[Re, a] > 0, TransformedParameter[Re, b] > 0,
   TransformedParameter[Re, c] > 0, TransformedParameter[Re, d] > 0
  }, {a, b, c, d}, t,
  "CoordinateSystem" -> "Real",
  Method -> {NMinimize,
    Method -> {"DifferentialEvolution",
      "SearchPoints" -> 40, "ScalingFactor" -> 0.95, "CrossProbability" -> 0.05,
      "PostProcess" -> {FindMinimum, Method -> "QuasiNewton"}
     }
   }
 ]

(* -> {a -> 5.49939, b -> 30.6601, c -> 25.1868, d -> 0.00556649} *)

You can give initial guesses for the parameters if you like, but I found that it didn't really help. The result seems reasonable:

Show[{
 ListPlot[data, PlotStyle -> Red],
 Plot[model /. fit, {t, Min@data[[All, 1]], Max@data[[All, 1]]}, PlotRange -> All]
}]

Plot of data versus fitted model

The errors are rather large, but I suppose this is an issue you can probably deal with on your own:

Parameters with errors obtained using NonlinearModelFit

(To get the NonlinearModelFit result, just specify the option "FitFunction" -> NonlinearModelFit in the ComplexFit call. The default is FindFit. The above table is the result of asking for the "ParameterConfidenceIntervalTable" property.)

Finally the correlation matrix, which will hopefully give you an idea why the errors are as they are:

Correlation matrix

$\endgroup$
4
  • $\begingroup$ Was just looking at your answer. A heck of a lot easier to give you +1 rather than optimizing Methods of Methods of Methods... $\endgroup$ Mar 2, 2014 at 19:36
  • 4
    $\begingroup$ FWIW paying close attention to what is causing the generation of complex numbers allows this problem to be solved with NonlinearModelFit. Setting the constraints to {a > 4.2, b > 0, c > 0, d > 0, d < .02} keeps the Log term positive for the given values of t. Then your DifferentialEvolution parameters work well in NonlinearModelFit. $\endgroup$ Mar 2, 2014 at 19:53
  • $\begingroup$ it works for me. thanks a lot. $\endgroup$
    – nitin
    Mar 2, 2014 at 21:39
  • $\begingroup$ @oleksandr r.: how do you want to be cited with your package? $\endgroup$
    – Fabian
    Apr 20, 2020 at 19:21

Your Answer

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

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