MathGroup Archive 2000

[Date Index] [Thread Index] [Author Index]

Search the Archive

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


  • Prev by Date: Re: 3D vector plots and shading
  • Next by Date: Cyclic decimal periods.
  • Previous by thread: RE: Controlling how Mathematica fits data
  • Next by thread: Re: Controlling how Mathematica fits data