Path: news.mathworks.com!not-for-mail
From: "John D'Errico" <woodchips@rochester.rr.com>
Newsgroups: comp.soft-sys.matlab
Subject: Re: 3d surface fitting
Date: Wed, 23 Apr 2008 12:16:02 +0000 (UTC)
Organization: John D'Errico (1-3LEW5R)
Lines: 69
Message-ID: <fun9a2$1mp$1@fred.mathworks.com>
References: <fum3b2$nc9$1@fred.mathworks.com> <fum7lp$sh9$1@fred.mathworks.com> <fun86d$o8a$1@fred.mathworks.com>
Reply-To: "John D'Errico" <woodchips@rochester.rr.com>
NNTP-Posting-Host: webapp-03-blr.mathworks.com
Content-Type: text/plain; charset="ISO-8859-1"
Content-Transfer-Encoding: 8bit
X-Trace: fred.mathworks.com 1208952962 1753 172.30.248.38 (23 Apr 2008 12:16:02 GMT)
X-Complaints-To: news@mathworks.com
NNTP-Posting-Date: Wed, 23 Apr 2008 12:16:02 +0000 (UTC)
X-Newsreader: MATLAB Central Newsreader 869215
Xref: news.mathworks.com comp.soft-sys.matlab:464742



"Arjun Chennu" <arjun.chennu@gmail.com> wrote in message 
<fun86d$o8a$1@fred.mathworks.com>...
> 
> > [x,y] = meshgrid(1:240,1:320);
> > fun = @(c)
> c(!)*besselj(0,c(2)*sqrt((x-c(3)).^2+(y-c(4)).^2)).^2+c(5);
> > 
> > John
> 
> 
> Hi John,
> 
> Thanks a lot for your quick reply!
> 
> Indeed, I have defined my function as:
> 
> function err = myfit(p, realdata)
> [x,y] = meshgrid(1:240,1:320);
> calcval = p(1)*besselj(0,
> p(2)*sqrt((x-p(3)).^2+(y-p(4)).^2)).^2 +p(5);
> size(calcval)
> err = (calcval - realdata).^2;
> return
> 
> However, when I use lsqcurvefit:
> 
> [p, resnorm] = lsqcurvefit(@myfit,p_start,dd)
> 
> it says it needs a fourth argument. (dd is the experimental
> data to which I'm trying to fit my function myfit).
> 
> The help file says:
> x = lsqcurvefit(fun,x0,xdata,ydata) starts at x0 and finds
> coefficients x to best fit the nonlinear function
> fun(x,xdata) to the data ydata (in the least-squares sense).
> ydata must be the same size as the vector (or matrix) F
> returned by fun.
> 
> so here ydata is dd.
> 
> But what is xdata? I'm not sure what I'm supposed to pass as
> xdata.
> 
> Help muchos appreciated! Thanks again.
> 
> Arjun
> 

There are two things to do here. First, Do NOT
square the residuals. lsqcurvefit will subtract
the aim (ydata) and square the residuals itself.

Next, you can probably save some small amount
of time by not generating the meshgrid for every
call into your function. Since you must pass in
xdata anyway, this should already contain x
and y.

Using an anonymous function, the call might
look like this:

[x,y] = meshgrid(1:240,1:320);
xdata = {x,y};
fun = @(c,xdata) c(1)*besselj(0, ...
     c(2)*sqrt((xdata{1}-c(3)).^2+(xdata{2}-c(4)).^2)).^2+c(5);

[p, resnorm] = lsqcurvefit(fun,p_start,xdata,dd);

John