Re: NMinimize fails to find a minimum value
- To: mathgroup at smc.vnet.net
- Subject: [mg120805] Re: NMinimize fails to find a minimum value
- From: Frank K <fkampas at gmail.com>
- Date: Thu, 11 Aug 2011 05:11:23 -0400 (EDT)
- Delivered-to: l-mathgroup@mail-archive0.wolfram.com
- References: <j1im1r$cmu$1@smc.vnet.net>
On Aug 6, 2:13 am, Hovhannes Babayan <bhovhan... at gmail.com> wrote: > Hello, > > I am solving the following task. I have set of points (list of pair of > X, Y coordinates) and list of weights for the each point. If for some > point weight=1, that point is very important of weight=0, that point > is not important. Weight ranges from 0 to 1. > The task is to construct a curve, which will fit given list of points > taking weights into account. The analytic form of function is known, > but I have to find parameters z,u,a,b, which will give the best > fitting curve. > To do that, I am using NMinimize to minimize the following expression: > Sum[ ((f[x[[i]],z,u,a,b]-y[[i]])^2)*weights[[i]], {i= , n} ] > where "n" is a number of points, "x" and "y" are point coordinates, > and "f(r, z,u,a,b)" is my function, where z,u,a,b are parameters which > should be found and "r" (x) is the only argument. > > NMinimize finds something, but does stupid things: > 1) when I declare function "f" as f[r_, z_,u_,a_,b_] := z*(r^(-a/ > 110)*(1+r/u)^(b/100)); I got normal results > 2) when I declare function "f" as f[r_, z_,u_,a_,b_] := z*(r^(-a/ > 10)*(1+r/u)^(b/10)); I got worse results > 3) when I declare function "f" as f[r_, z_,u_,a_,b_] := z*(r^(-a)*(1+r/ > u)^(b)); I got the worst results > > Why I have to divide "a" to get better results?? Is it possible to > avoid using such tricks and get NMinimize work with the 3rd case? > Calculated values of parameters are not very small or very large, > normal numbers.... > I'll be grateful for any remarks/suggestions/ideas. To try, just copy/ > paste the code below into Mathematica and run it. > > points = { > { 4.68, 0.156}, > { 7.63, 0.100}, > {10.56, 0.074}, > {13.48, 0.061}, > {16.55, 0.048}, > {20.33, 0.029}, > {25.39, 0.023}, > {30.28, 0.018}, > {36.05, 0.016}, > {42.60, 0.016}, > {55.49, 0.028}} ; > > weights = {0.2523, 0.4007, 0.5801,0.6193, 0.6798, 1, 0.7957, 0.5144, > 0.37030, 0.1079, 0.0189}; > > f[r_, z_,u_,a_,b_] := z*(r^(-a/110)*(1+r/u)^(b/100)); (* Here z,u,a,b > are parameters *) > > x = points[[All,1]]; > y = points[[All,2]]; > n = Length[points]; > bestFitVals = NMinimize[ > Sum[ > ((f[x[[i]],z,u,a,b]-y[[i]])^2)*weights[[i= ]], > {i, n} > ], > {z,u,a,b} > ] > Show[ > Plot[ > Tooltip[f[r,z,u,a,b] /. bestFitVals[[2]]]= , > {r, Max[xdata], Max[ydata]} > ], > ListPlot[points], > PlotRange->{{0,Automatic},{0,0.2}}, > AxesLabel->{"r", "f[r]"} > ] NMinimize has a default starting search range of -1 to 1 for the variables. That may be why you get better results when you scale. You can change the default range in the variable specification, for example {{x, -10,10},{y,-10,10}} etc.