       RE: Controlling how Mathematica fits data

• To: mathgroup at smc.vnet.net
• Subject: [mg21465] RE: [mg21450] Controlling how Mathematica fits data
• From: "Ersek, Ted R" <ErsekTR at navair.navy.mil>
• Date: Tue, 11 Jan 2000 04:17:46 -0500 (EST)
• Sender: owner-wri-mathgroup at wolfram.com

```Steve wanted to fit a function f[x] to (data1) below and ensure
f[x]<=92.5  for all x between (437,563).

In:=
xraw={437, 438, 439, 440, 548, 555, 563};
yraw={4.82, 2.72, 10.05, 16.84, 92.5, 92.5, 92.5};
data1=Transpose[{xraw,yraw}];

-------------------------------------------
Notice I use f[x_]=(*expr*)
As I discuss under (Rule versus RuleDelayed) on my web site, this ensures
Fit or NonlinearFit isn't computed each time f[x] is used. As I also mention
at the same place on my web site we could get the wrong result if we don't
clear values from (x) before the definition for (f) is given. However, there
is no need to Clear (x) when using f[x_]:=(*expr*).

Steve, you have a long gap in the middle of your data samples and as you
noticed a polynomial fit may do wild things in the middle of this gap. I
think your best bet is to "fit" using a small number of functions that more
or less have the shape you are looking for. Here is one that works fairly
well.

In:=
ClearAll[f,x];
f[x_]=Fit[data1,{1/(x-400),1},{x}]

Out=
120.275 + 4297.46/(-400 + x)

----------------------
Next we see the difference between f[x] and (yraw).

In:=
yraw-Map[f,xraw]

Out=
{0.692785, 4.46373, 0.0335034, 4.00171, 1.26206, 0.0492813, 1.41005}

--------------------------------
Next I give you a fit using a slightly different function.

In:=
ClearAll[f,x];
f[x_]=Fit[data1,{1/(x-350),1},{x}]

Out=
156.234 + 13065.8/(-350 + x)

---------------------------------
Next wee see the difference between f[x] and (yraw) using this fit.

In:=
yraw-Map[f,xraw]

Out=
{1.23195, 5.03856, 0.623182, 5.78199, 2.25524, 0.00195817, 2.39187}

----------------------------------
OK, now what are you to do if you want to find the best of all possible
functions with the form used in the above solutions? That is where
NonlinearFit is needed. Below I find the values of (c1,c2,c3) that give the
"best" fit. I don't know why Nonlinear fit choked on the Weibull function.

In:=
<<Statistics`NonlinearFit`

In:=
ClearAll[x,f];
f[x_]=NonlinearFit[data1,c1+c2/(x+c3),{x},{c1,c2,c3}]

Out=
109.632 + 2406.77/(414.623 + x)

---------------------------------
Below we see that the difference between f[x] and (yraw) is better than with
the solutions above. I did a little tinkering to look for other algebraic or
elementary functions that would work better and couldn't find one.

In:=
yraw-Map[f,xraw]

Out=
{2.74393, 3.95701, 0.850474, 2.04892, 0.912893, 0.0130714, 0.911334}

---------------------------------
This next part has me puzzled. I expected Fit to give the same solution that
NonlinearFit did in this next example, but it doesn't.

In:=
ClearAll[f,x];
f[x_]=Fit[data1,{1/(425.093+x),1},{x}]

Out=
711.106 + 606593./(425.093 + x)

Next we see the difference between f[x] and (yraw) is much worse than it was
with the function NonlinearFit returned. I don't know what went wrong.

In:=
yraw-Map[f,xraw]

Out=
{2.65764, 5.57288, 0.943765, 6.92229, 4.75994, 0.307749, 4.70323}

---------------------------------------
With any of the results above you can use the following to see how nice the
curve fits the data.

Plot[f[x],{x,435,565},
Epilog->{RGBColor[1,0,0],PointSize[0.02],Point/@data1}
];

Warnings:
Use Epilog, Prolog with caution. They can give results you don't want. For
more on that look up Epilog, Prolog under Graphics Tricks on my web page.

You are really going out on a limb if you make any claim about the value of
f[x] in the middle of a wide data gap unless you have a good justification.

--------------------
Regards,
Ted Ersek

On 12-18-99 Mathematica tips, tricks at
http://www.dot.net.au/~elisha/ersek/Tricks.html