4
$\begingroup$

Probably a very simple fix, but I'm trying to fit a simple exponential. Even when I put in good guesses, the model won't fit the data. Any suggestions?

<< StandardAtmosphere`
data = Table[{alt, MeanFreePath[alt Quantity[1, "Kilometers"]][[1]]}, {alt, 0, 110, 0.5}];
nlm = NonlinearModelFit[data, A*Exp[(x - B)*C], {A, B, C}, x];
Show[ListLogPlot[data, PlotStyle -> Blue], 
 LogPlot[nlm[x], {x, 0, 110}, PlotStyle -> Black], Frame -> True, 
 FrameLabel -> {Style["Altitude (km)", 14], Style["MFP (m)", 14]}]

enter image description here

$\endgroup$
6
  • 1
    $\begingroup$ Please provide your Mathematica code, not an image! $\endgroup$ Commented Dec 2, 2023 at 13:21
  • 1
    $\begingroup$ Your data does not seem to have a unique value for an given altitude. $\endgroup$ Commented Dec 2, 2023 at 13:22
  • $\begingroup$ Added code. The data is the exponential line and the nlm result is the flat line. $\endgroup$
    – icebox207
    Commented Dec 2, 2023 at 13:40
  • 1
    $\begingroup$ @icebox207 You should probably use LogPlot instead of Plot, to match the ListLogPlot you used for your data. We can't investigate further because MeanFreePath is not defined in your code, so we can't run it. $\endgroup$
    – MarcoB
    Commented Dec 2, 2023 at 14:21
  • $\begingroup$ MeanFreePath is loaded with the StandardAtmosphere package, added. $\endgroup$
    – icebox207
    Commented Dec 2, 2023 at 14:35

2 Answers 2

8
$\begingroup$
$Version

(* "13.3.1 for Mac OS X ARM (64-bit) (July 24, 2023)" *)

Clear["Global`*"]

Needs["StandardAtmosphere`"]

data = Table[{alt, MeanFreePath[alt Quantity[1, "Kilometers"]][[1]]}, 
     {alt, 0, 110, 0.5}];

Fit the log of the data

Exp[(nlm2 = 
    NonlinearModelFit[{#[[1]], Log[#[[2]]]} & /@ data, a*x + b, {a, b}, x]) //
   Normal]

(* E^(-16.8632 + 0.147609 x) *)

Show[
 ListLogPlot[data,
  PlotStyle -> Blue],
 LogPlot[Exp[nlm2[x]], {x, 0, 110},
  PlotStyle -> Black],
 Frame -> True,
 FrameLabel -> {Style["Altitude (km)", 14], Style["MFP (m)", 14]}]

enter image description here

EDIT: Alternatively, since

A*Exp[(x - B)*C] == Exp[Log[A]]*Exp[C*x - B*C] == 
  Exp[C*x - (B*C - Log[A])] // Simplify

(* True *)

The model has only two parameters. Use Exp[a*x + b]

To determine initial estimates for the NonlinearModelFit, use two widely separated data points

paramEst = 
 SolveValues[Exp[a*#[[1]] + b] == #[[2]] & /@ data[[{1, -1}]], {a, b}][[1]] //
   Quiet

(* {0.148094, -16.5286} *)

(nlm3 = NonlinearModelFit[data, Exp[a*x + b], Transpose[{{a, b}, paramEst}], 
    x]) // Normal

(* E^(-17.0152 + 0.153491 x) *)

Show[ListLogPlot[data, PlotStyle -> Blue], 
 LogPlot[nlm3[x], {x, 0, 110}, PlotStyle -> Black], Frame -> True, 
 FrameLabel -> {Style["Altitude (km)", 14], Style["MFP (m)", 14]}]

enter image description here

$\endgroup$
0
$\begingroup$

To long for a comment:

Mathematica v12.2 evaluates much better result as shown in your question. Try

<< StandardAtmosphere`
data = Table[{alt, MeanFreePath[alt Quantity[1, "Kilometers"]][[1]]}, {alt,0, 110, 0.5}];
nlm = NonlinearModelFit[data, A*Exp[(x - B)*C], {A, B, C}, x];
Show[ListLogPlot[data, PlotStyle -> Blue], 
LogPlot[nlm[x], {x, 0, 110}, PlotStyle -> Black], Frame -> True, 
FrameLabel -> {Style["Altitude (km)", 14], Style["MFP (m)", 14]}]

enter image description here

$\endgroup$
1
  • 1
    $\begingroup$ Thanks Ulrich! Unfortunately I just tried this verbatim in Mathematica 13.3 and I get the same result as in my post. $\endgroup$
    – icebox207
    Commented Dec 2, 2023 at 16:59

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.