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