Re: Controlling how Mathematica fits data
- To: mathgroup at smc.vnet.net
- Subject: [mg21496] Re: Controlling how Mathematica fits data
- From: Paul Abbott <paul at physics.uwa.edu.au>
- Date: Wed, 12 Jan 2000 08:35:40 -0500 (EST)
- Organization: University of Western Australia
- References: <85cn1p$lha@smc.vnet.net>
- Sender: owner-wri-mathgroup at wolfram.com
Steve wrote:
> 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.
There is no easy way I can think of to this.
> 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.
The first line should read
Needs["Statistics`NonlinearFit`"]
and in the second there should be a space (or *) between c and X. Note
that using capital variable names is not a great idea.
For your data
xraw = {437, 438, 439, 440, 548, 555, 563}
yraw = {-4.82, 2.72, 10.05, 16.84, 92.5, 92.5, 92.5}
data = Transpose[{xraw, yraw}];
a plot reveals that the data is rather poorly sampled:
dataplot = ListPlot[data, PlotStyle -> Hue[0]];
I assume that it must be difficult to get more data points between 440
and 548?
After loading the package,
Needs["Statistics`NonlinearFit`"]
you can do a nonlinear fit:
NonlinearFit[data, a - d/E^(b*(x - c)), x,
{{a, 100}, {d, 100}, {b, 0.3}, {c, 440}}]
I did a few plots of a - d/E^(b*(x - c)) for various values of a, b ,c,
and d to give NonlinearFit some good starting parameters. This fit is
very fast and it agrees well with the supplied data:
Plot[%, {x, Min[xraw], Max[xraw]}, PlotRange -> All, Epilog ->
First[dataplot]];
> I'm running version 3.0 on Win95.
Note that the NonlinearFit code has changed between 3.0 and 4.0. It is
now much faster and the output format is different.
Cheers,
Paul