# Fitting log-linear data

I am using NonlinearModelFit to extract the gradient of what appears to be linear data in a logplot:

data = {{-0.010133333333333334,
124.50000000000001}, {-0.006933333333333333,
610.}, {-0.005600000000000001,
75.58333333333333}, {-0.004266666666666669,
33.183673469387756}, {-0.0029333333333333295,
17.23926380368098}, {-0.0015999999999999973,
5.47681331747919}, {-0.00026666666666666505,
1.3872715510270095}, {0.0010666666666666672,
0.3445990722332671}, {0.0023999999999999994,
0.0713022981732469}, {0.0037333333333333316,
0.05300353356890459}, {0.005066666666666671,
0.021496815286624203}, {0.006400000000000003,
0.0028530670470756064}, {0.008266666666666665,
0.004938271604938271}};

expmodel =
NonlinearModelFit[data, a*Exp[b*x], {a, b}, x, MaxIterations -> 200];

Show[{
ListLogPlot[data],
LogPlot[expmodel[x], {x, -0.01, 0.005}]}]


The function returned by NonlinearModelFit, however, does not match the data at all. I even tried to give realistic initial values to parameters a and b, but that didn't help.

• Why not take a Log to Y-axis value and use LinearModelFit?
– Wjx
Jun 15, 2016 at 7:08
• If this help, I can post a detailed answer :)
– Wjx
Jun 15, 2016 at 7:08
• @Wjx That was a good idea :) Jun 15, 2016 at 7:12
• So I will write an answer as soon as I get home.
– Wjx
Jun 15, 2016 at 7:32

Usually we'll tend to fit linear system, and in this situaiton, add Log to data's y-axis will help: Log[a E^(b x)]=Log[a]+b x

Truely, after this transformation, the points lay on a line~ great for fitting!

It seems that this method could really do the work, so naturally, here comes the following code for fitting using normal linear fitting method:

ldata = {#1, Log@#2} & @@@ data;
ListPlot@ldata
f[x_] = E^Normal@LinearModelFit[ldata, x, x]

Show[ListPlot[data, PlotStyle -> Darker@Green, PlotLegends -> {"Data"}],
Plot[f[x], {x, data[[1, 1]], data[[-1, 1]]}, PlotLegends -> {"Fit"}]]
Show[ListLogPlot[data, PlotStyle -> Darker@Green,PlotLegends -> {"Data"}],
Plot[Log@f[x], {x, data[[1, 1]], data[[-1, 1]]}, PlotLegends -> {"Fit"}]]


The resultant function is: E^(-0.0888526 - 717.01 x) and the fitting curve is shown below:

The result seems to be a bit wierd in normal scale, but in Log scale, it's quite a good fit!

Will this help?

FindFit seems to work

f[a_, b_, x_] = a*Exp[b*x];
expmodel[x_] = f[a, b, x] /. FindFit[data,f[a, b, x],{a, b},x]


50.3816 E^(-167.73 x)

I will compare it with

f1[x_]=E^(-0.08885264746563443 - 717.0097150284254 x)


which can be found from Wjx's method.

Show[{ListPlot[data, PlotRange->All], Plot[{expmodel[x],f1[x]}, {x, -0.01, 0.01}]}]
Show[{ListLogPlot[data], LogPlot[{expmodel[x], f1[x]}, {x, -0.01, 0.01}]}]


Definitely f1 appears much closer to data. Now if you calculate the RMS deviation

RootMeanSquare[(#[[2]] - expmodel[#[[1]]]) &/@ data]
RootMeanSquare[(#[[2]] - f1[#[[1]]]) &/@ data]


137.858

354.308

expmodel turns out to be the winner.

All these mess is due to your second data point. If you start from third data point Wjx's method will come pretty close to FindFit.

• "FindFit seems to work" ??? With all of the data points very much below the fitted curve?
– JimB
Jun 15, 2016 at 14:58
• check my modified answer. It will clear your doubt. Jun 15, 2016 at 16:08
• But f1 is simply the same structure as expmodel: f1 == Exp[Log[a] + b*x] and should end up with the same fit. So that's why I wonder about "FindFit" working.
– JimB
Jun 15, 2016 at 16:14
• @JimBaldwin, the fitting algorithm is different in two cases. Jun 15, 2016 at 17:18
• Sorry. I see now. f1 is the antilog of the fit by @Wjx rather than a fit of f1 directly.
– JimB
Jun 15, 2016 at 17:27