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[1]:= 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*) instead of 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[4]:= ClearAll[f,x]; f[x_]=Fit[data1,{1/(x-400),1},{x}] Out[5]= 120.275 + 4297.46/(-400 + x) ---------------------- Next we see the difference between f[x] and (yraw). In[6]:= yraw-Map[f,xraw] Out[6]= {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[7]:= ClearAll[f,x]; f[x_]=Fit[data1,{1/(x-350),1},{x}] Out[8]= 156.234 + 13065.8/(-350 + x) --------------------------------- Next wee see the difference between f[x] and (yraw) using this fit. In[9]:= yraw-Map[f,xraw] Out[9]= {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[10]:= <<Statistics`NonlinearFit` In[11]:= ClearAll[x,f]; f[x_]=NonlinearFit[data1,c1+c2/(x+c3),{x},{c1,c2,c3}] Out[12]= 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[13]:= yraw-Map[f,xraw] Out[13]= {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[14]:= ClearAll[f,x]; f[x_]=Fit[data1,{1/(425.093+x),1},{x}] Out[15]= 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[16]:= yraw-Map[f,xraw] Out[16]= {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 had a major update