MathGroup Archive 2011

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

Search the Archive

Re: NonlinearFit for specific data

  • To: mathgroup at smc.vnet.net
  • Subject: [mg117820] Re: NonlinearFit for specific data
  • From: Darren Glosemeyer <darreng at wolfram.com>
  • Date: Fri, 1 Apr 2011 02:31:13 -0500 (EST)

On 3/31/2011 4:01 AM, Alexandre Souza wrote:
> Dear Group,
> I have the following data :
> data2 = {  {0, 773.59},{30, 2351.12},{60, 4205.8}, {90, 4222.69},{120,
> 4222.69},{150, 704.328},
> {180, 1388.28},{210, 1388.28},{240, 1821.23},{270, 1821.23},{300,
> 754.109},{330, 773.59},{360, 773.59}};
> I want the following curve fit :
>   NonlinearFit[data2, Exp[ a + b x + c x^2], x, {a, b, c}]
> Unfortunatelly I get some "FindFit::sszero
> FindMinimum::sszero" message, and the given result is ackward.
> I also tried FindFit and NonlinearRegress without success.
> Any comment would be very welcome.
> Alex
>

In nonlinear optimization, choosing good starting values can make a big 
difference. These nonlinear optimization functions will start all 
parameters at 1 if no starting values are given, and 1 will not be very 
good for any of the parameters in this particular example. Some 
knowledge of what the parameters are expected to be can be very useful 
in choosing them. Without that knowledge, I typically resort to a 
mathematical bag of tricks I've built up over the years. Here are two 
approaches that will work in this case.

One is to look at limiting behaviors for the model function and use data 
points at or near those limits to solve for starting values for some 
parameters. In this model for x==0, the model would be Exp[a] and as x 
gets large the model should go to Exp[c*x^2], so we could use the first 
and last data points to solve for starting values for a and c.

In[1]:= data2 = {{0, 773.59}, {30, 2351.12}, {60, 4205.8}, {90,
             4222.69}, {120, 4222.69}, {150, 704.328}, {180, 1388.28}, 
{210,
             1388.28}, {240, 1821.23}, {270, 1821.23}, {300, 754.109}, 
{330,
             773.59}, {360, 773.59}};

In[2]:= astart = Log[data2[[1, 2]]]

Out[2]= 6.65104

In[3]:= cstart = Log[data2[[-1, 2]]]/data2[[-1, 1]]^2

Out[3]= 0.0000513198


Now we could use another data point and those starting values to get a 
starting value for b from another data point.


In[4]:= bstart =
          With[{x = data2[[2, 1]]},
           b /. Solve[(Exp[a + b x + c x^2] /. {a -> astart, c -> 
cstart}) ==
               data2[[2, 2]], b, Reals][[1]]]

Solve::ratnz: Solve was unable to solve the system with inexact 
coefficients. The
     answer was obtained by solving a corresponding exact system and 
numericizing
     the result.

Out[4]= 0.0355139



We can now use these as starting values for the optimization:



In[5]:= FindFit[data2, Exp[a + b x + c x^2],
          Transpose[{{a, b, c}, {astart, bstart, cstart}}], x,
          MaxIterations -> 1000]

Out[5]= {a -> 6.97238, b -> 0.0332337, c -> -0.000192787}



Another possibility in this case is to take advantage of the fact that 
Log of the model is a linear model, so we could take the Log of the y 
values, fit the linear model, and use the estimates from that 
linearization as starting values.


In[6]:= logdata = data2;

In[7]:= logdata[[All, 2]] = Log[logdata[[All, 2]]];

In[8]:= start2 = CoefficientList[Fit[logdata, {1, x, x^2}, x], x]

Out[8]= {7.45656, 0.00453122, -0.0000207059}

In[9]:= FindFit[data2, Exp[a + b x + c x^2], Transpose[{{a, b, c}, start2}],
           x]

Out[9]= {a -> 6.97238, b -> 0.0332337, c -> -0.000192787}



Darren Glosemeyer
Wolfram Research


  • Prev by Date: Re: Subject: Re: Rational[a,b] vs Rational[1,2]
  • Next by Date: Re: CAS that uses convert/binary/decimal ..... / Retraction.
  • Previous by thread: Re: NonlinearFit for specific data
  • Next by thread: Re: NonlinearFit for specific data