Re: Controlling how Mathematica fits data
- To: mathgroup at smc.vnet.net
- Subject: [mg21470] Re: [mg21450] Controlling how Mathematica fits data
- From: Daniel Lichtblau <danl at wolfram.com>
- Date: Tue, 11 Jan 2000 04:17:50 -0500 (EST)
- References: <200001100856.DAA21039@smc.vnet.net>
- Sender: owner-wri-mathgroup at wolfram.com
com3 at ix.netcom*NOSPAM*.com wrote: > > Hello all, > > I have 7 (x,y) data points that I need to fit to an equation. My first > attempt was as follows: > > xraw={437,438,439,440,548,555,563} > yraw={-4.82,2.72,10.05,16.84,92.5,92.5,92.5} > dataraw={xraw,yraw}; > data1=Transpose[dataraw]; > fitcurve1=Fit[data1,{1,X,X^2,X^3},X] > > This works in that it returns the best set of coefficients for cubic > equation on a least-squares basis. The problem is that when this > equation is used at some x values that weren't provided in xraw, it > returns y values that are physically not possible in my application. > For example, when x=500, y is greater that 92.5 due to the "bump" in > the curve. > > Question 1: Is it possible to place constraints on Fit[] such that the > results of the returned equation can be constrained ? In my case, the > constraint would be that no computed y value can exceed 92.5 when > given x values that range from 437 to 563. I'm only interested in the > performance of the equation between these x values. > > My second attempt at this was to use NonlinearFit with a Weibull > formula as a starting point as follows: > > Needs['Statistics`NonlinearFit'"] > fitcurve1=NonlinearFit[data1, a-(b*Exp[-cX^d]),X,{a,b,c,d}] > > Mathematica simply echos this back and does no computing. > > Question 2: What am I doing wrong with NonlinearFit ? Sloppy typing. First, your quotes in the Needs[] are messed up. Needs["Statistics`NonlinearFit`"] Second, there is no space between c and X in your model, so it has an unknown "parameter" cX and no "variable" X. In[13]:= InputForm[fitcurve1=NonlinearFit[data1, a-(b*Exp[-c*X^d]),X,{a,b,c,d}]] Out[13]//InputForm= 44.502366852830825 - 1.3232910552186383* E^(31.454166393712903/X^196.34923759283828) In[14]:= fitcurve1 /. X->500 Out[14]= 43.1791 I always try to use explicit '*' rather than the implicit white-space for multiplication. Among other things, it helps in elluding exactly this pitfall you found. A plot indicates that this is not a very good fit for your data. > Question 3: Is there a better method of accomplishing this task ? > > I found a FAQ that talks about the difficulties of using "penalty > functions" so as a new user I would prefer a safer approach if one > exists. > > I'm running version 3.0 on Win95. > > > Thanks in advance. > > Steve > For any e-mail responses, please remove *NOSPAM* from my address. Here are a few ideas. First, you probably have too many degrees of freedom in your linear least-squares attempt. One hint is the relatively low coefficient of the cubic term. If you do a quadratic fit and plot it, you'll get something more reasonable. Second, you might use splines instead of a least squares fit. Whether this is acceptable or not depends on your problem. Third, you might try other nonlinear models. A ListPlot indicates a graph that looks a bit like a log so I tried the one below, in our development version. The plot was reasonable if imperfect at the high end. Unfortunately I do not get this in version 4 where instead it appears to hang. In[22]:= fitcurve1=NonlinearFit[data1, a + b*X +c*Log[d+X], X, {a,b,c,d}] FindMinimum::fmlim: The minimum could not be bracketed in 30 iterations. Out[22]= -1071.34 - 1.58384 X + 376.67 Log[-328.446 + X] Looking more closely, another possibility is to look at a curve with a translated reciprocal term, and to give NonlinearFit more iterations. Some fooling around in our development version lead me to: In[33]:= InputForm[fitcurve1 = NonlinearFit[data1, a + b*X +c/(X+d), X, {a,b,c,d}, MaxIterations->200]] Out[33]//InputForm= 162.84975361990658 - 1691.8881050020104/(-423.2086252503201 + X) - 0.103567225321947*X which gave a very good plot with respect to the data points. Unfortunately this also seems to take a long time in version 4, and it gives useless result (with a warning message) in version 3. My guess is that you can use FindMinimum directly, possibly with nondefault options such as Method, in order to get reasonable results in your version. Daniel Lichtblau Wolfram Research