How can I fit to a growing spiral

4 views (last 30 days)
Bryan
Bryan on 11 Sep 2015
Answered: Star Strider on 11 Sep 2015
So far my function looks like this
function [x,y] = fitspiral(th, param)
a = param(1);
b = param(2);
c = param(3);
d = param(4);
e = param(5);
f = param(5);
g = param(5);
R=((a+(f+g).*th).^2.*(b+(f+g).*th).^2./((a+(f+g).*th).^2.*sin(th).^2+(b+(f+g).*th).^2.*cos(th).^2)).^(.5);
x=R.*cos(th)+c;
y=R.*sin(th)+d+(th/pi).^e;
end
I've been trying to do a lsqcurvefit, but I can't seem to set it up to work. It's a bit of a crazy equation but it fits very close to my current data.
th=linspace(0,2.2*pi);
xdata=[399 347 292 235 167 109 76 96 197 262 323 410 463 559 566 557 527];
ydata= [413 434 440 435 410 367 325 184 106 70 70 80 128 278 338 381 458];
const=[ 196 156 301 266 5.40 10 .8];
param = lsqcurvefit(@fitspiral, const, th, xdata,ydata)

Answers (1)

Star Strider
Star Strider on 11 Sep 2015
There are a few problems with your code, the most significant of which is that in all nonlinear curve fitting functions in MATLAB, the parameter argument comes first and the xdata argument second:
function [xy] = fitspiral(param, th)
Beyond that, lsqcurvefit will easily fit multiple dependent variables, but you have to concatenate them into one matrix:
xydata = [xdata; ydata]';
and be sure your objective function returns a vector of the same size:
xy = [x; y]';
Your independent variable has to be the same length as your dependent variable:
th=linspace(0, 2.2*pi, length(xdata));
With those changes, it works and produces what looks to me as an acceptable fit.
The full code, with revisions (and a plot):
function [xy] = fitspiral(param, th)
a = param(1);
b = param(2);
c = param(3);
d = param(4);
e = param(5);
f = param(5);
g = param(5);
R=((a+(f+g).*th).^2.*(b+(f+g).*th).^2./((a+(f+g).*th).^2.*sin(th).^2+(b+(f+g).*th).^2.*cos(th).^2)).^(.5);
x=R.*cos(th)+c;
y=R.*sin(th)+d+(th/pi).^e;
xy = [x; y]';
end
xdata = [399 347 292 235 167 109 76 96 197 262 323 410 463 559 566 557 527];
ydata = [413 434 440 435 410 367 325 184 106 70 70 80 128 278 338 381 458];
xydata = [xdata; ydata]';
th=linspace(0, 2.2*pi, length(xdata));
const=[ 196 156 301 266 5.40 10 .8];
param = lsqcurvefit(@fitspiral, const, th, xydata)
[xyfit] = fitspiral(param,th);
figure(1)
plot(xdata, ydata, 'bp')
hold on
plot(xyfit(:,1), xyfit(:,2), '-m')
hold off
grid

Community Treasure Hunt

Find the treasures in MATLAB Central and discover how the community can help you!

Start Hunting!