-1
$\begingroup$

I have a set of data and I am trying to find the best fitting function. However, a polynomial expansion doesn't seem to help. Should I use an exponential fit? How?

data={{0.99823, 1.005}, {1.0221, 1.31}, {1.0469, 1.76}, {1.0727, 
2.5}, {1.0993, 3.72}, {1.1263, 6.}, {1.1538, 10.8}, {1.1675, 
15.2}, {1.173, 17.7}, {1.18125, 22.5}, {1.19485, 35.5}, {1.2085, 
60.1}, {1.2218, 109.}, {1.2351, 219.}, {1.2377, 259.}, {1.24035, 
310.}, {1.243, 367.}, {1.2456, 437.}, {1.24825, 523.}, {1.2508, 
624.}, {1.25335, 765.}, {1.2559, 939.}, {1.2585, 1150.}, {1.26108, 
1410.}};

fit = Fit[data, {x^2, x^4, x^5, x^6}, x]

Show[Flatten[{Plot[fit, {x, 1, 1.28}, PlotStyle -> Red, 
PlotRange -> {{1, 1.28}, {-200, 1400}}], ListPlot[import[[1]]]}], 
Frame -> True, 
FrameLabel -> {"Density [g/cm^3]", "Viscosity [mPas]"}]
$\endgroup$
  • $\begingroup$ Take the log of the dependent variable and you'll obtain a much better fit. $\endgroup$ – JimB Aug 21 '17 at 15:37
  • $\begingroup$ @JimBaldwin could you write some code? $\endgroup$ – Andrea G Aug 21 '17 at 15:38
  • $\begingroup$ you could try a transformation of your y's and then do a linear regression on the transformed values ie lmf = LinearModelFit[MapAt[Log, data, {All, -1}], {x}, {x}] and ListPlot[{Exp[lmf["Response"]], Exp[lmf["Response"] - lmf["FitResiduals"]]}] $\endgroup$ – user42582 Aug 21 '17 at 15:39
  • $\begingroup$ I think you'll have no problem writing the necessary one line of code. $\endgroup$ – JimB Aug 21 '17 at 15:42
  • $\begingroup$ @JimBaldwin the fact is that i don't understand your suggestion $\endgroup$ – Andrea G Aug 21 '17 at 15:49
1
$\begingroup$

One option is to use FindFormula

$Version

(*  "11.1.1 for Mac OS X x86 (64-bit) (April 18, 2017)"  *)

data = {{0.99823, 1.005}, {1.0221, 1.31}, {1.0469, 1.76}, {1.0727, 
    2.5}, {1.0993, 3.72}, {1.1263, 6.}, {1.1538, 10.8}, {1.1675, 
    15.2}, {1.173, 17.7}, {1.18125, 22.5}, {1.19485, 35.5}, {1.2085, 
    60.1}, {1.2218, 109.}, {1.2351, 219.}, {1.2377, 259.}, {1.24035, 
    310.}, {1.243, 367.}, {1.2456, 437.}, {1.24825, 523.}, {1.2508, 
    624.}, {1.25335, 765.}, {1.2559, 939.}, {1.2585, 1150.}, {1.26108,
     1410.}};

f[x_] = Exp[FindFormula[{#[[1]], Log[#[[2]]]} & /@ data, x]]

(*  E^(0.0182879 - 2.93441 Cot[4.68 x])  *)

{xmin, xmax} = MinMax[data[[All, 1]]];

Plot[f[x], {x, xmin, xmax},
 Epilog -> {Red, AbsolutePointSize[6], Point[data]},
 Frame -> True,
 FrameLabel -> (Style[#, Bold, 14] & /@
    {"Density [g/cm^3]", 
     "Viscosity [mPas]"}),
 PlotRange -> All]

enter image description here

EDIT: In subsequent evaluations of FindFormula I obtained a different result that corresponds to your observed result mentioned in your comment.

FindFormula[{#[[1]], Log[#[[2]]]} & /@ data, x]

(*  -2.93441 Cot[4.68 x]  *)

I suspect that this may be due to the fact that FindFormula has the option RandomSeed.

Options[FindFormula]

(*  {Method -> Automatic, TargetFunctions -> All, TimeConstraint -> Automatic, 
 SpecificityGoal -> 0.8, RandomSeed -> Automatic, "Monitor" -> False, 
 PerformanceGoal -> Automatic}  *)

The internal state of the RandomSeed can affect the result. Consequently, use a fixed RandomSeed, request multiple functions, and look at their properties

fit = FindFormula[{#[[1]], Log[#[[2]]]} & /@ data, x, 3, All, 
  PerformanceGoal -> "Quality", RandomSeed -> 1]

enter image description here

While 0.0182879 -2.93441 Cot[4.68 x] has a lower Error property, -2.93862 Cot[4.68 x] has a higher Score due to its lower Complexity

keys = (fit // Normal // Keys)

(*  {-2.93862 Cot[4.68 x], 
 0.0182879 - 2.93441 Cot[4.68 x], -0.893811 + x^(7.11223 x)}  *)

For better error performance choose

f[x_] = Exp[keys[[2]]]

(*  E^(0.0182879 - 2.93441 Cot[4.68 x])  *)
$\endgroup$
  • $\begingroup$ why do you write (E^(0.0182879-2.93441 Cot[4.68 x]))? My output from f[x_]is only: (E^(-2.93441 Cot[4.68 x])) $\endgroup$ – Andrea G Aug 21 '17 at 17:11
  • $\begingroup$ @AndreaG - I didn't "write" it, that is the output provided by my version (11.1.1) of Mma. What version are you using? $\endgroup$ – Bob Hanlon Aug 21 '17 at 17:32
  • 1
    $\begingroup$ @AndreaG - With my version, Options[FindFormula] evaluates to {Method -> Automatic, TargetFunctions -> All, TimeConstraint -> Automatic, SpecificityGoal -> 0.8, RandomSeed -> Automatic, "Monitor" -> False, PerformanceGoal -> Automatic} If your default options are the same then depending on the speed of the processor, the default TimeConstraint could return a different result. You could try extending the time constraint. $\endgroup$ – Bob Hanlon Aug 21 '17 at 17:40
  • $\begingroup$ @AndreaG - With v10.4.1 I get your results but by extending the time constraint I get the same result as v11.1.1. f[x_] = Exp[ FindFormula[{#[[1]], Log[#[[2]]]} & /@ data, x, TimeConstraint -> 5]] $\endgroup$ – Bob Hanlon Aug 21 '17 at 17:59
  • $\begingroup$ While it is not a panacea, you might consider the common practice of using AIC to rank the model fits. (But you'd need to use NonlinearModelFit to get that option.) I wouldn't rely on "complexity" as that is a Mathematica-centric term. $\endgroup$ – JimB Aug 22 '17 at 4:38

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.