Function fitting on a set of data points

24 次查看(过去 30 天)
Hello,
I am trying to fit a function on a set of data point using some parameters to be optimized and the function lsqcurvefit.
The function is essentially:
y = a+b*cos(x)+c*cos(2*x)+d*sin(x)-e*sin(2*x);
So I first defined the parameters in terms on one variable, as following:
x(1) = a
x(2) = b
x(3) = c
x(4) = d
x(5) = e
And here goes the code:
DATA = load('data_f.txt');
t = DATA(:,1);
y = DATA(:,2);
plot(t,y,'ro')
F = @(x,xdata) +x(1) - x(2)*cos(xdata*(pi/180)) + x(3)*cos(2*xdata*(pi/180)) - x(4)*sin(xdata*(pi/180)) - x(5)*sin(2*xdata*(pi/180));
x0 = [1 1 1 1 1];
[x,resnorm,~,exitflag,output] = lsqcurvefit(F,x0,t,y)
hold on
plot(t,F(t,y))
hold off
Problem is that the curve looks horrible but the parameters look fine compared to the fitting done in other programs. Is there something I am not seeing?
Thank you very much in advance!
Stay safe,
Alex

采纳的回答

John D'Errico
John D'Errico 2021-1-14
编辑:John D'Errico 2021-1-14
What did you do wrong? It looks like Jon may be correct, in that you did not use the newly estimated set of parameters from the fit.
xy = [0.0 6.08
15 5.3
30 4.28
45 2.89
60 1.31
75 -0.16
90 -0.47
105 0.23
120 1.68
135 3.55
150 5.32
165 6.51
180 6.86
195 6.29
210 4.92
225 3.04
240 1.19
255 0
270 -0.09
285 0.75
300 2.21
315 3.89
330 5.29
345 6.09
360 6.08];
x = xy(:,1);
y = xy(:,2);
FIRST, PLOT YOUR DATA. LOOK AT IT. Does this simple trig model make sense?
plot(x,y,'ro')
And, yes, the result does seem to be a very simple sinusoidally varying curve.
However, there is no need to use lsqcurvefit to fit this, since it is a linear model in the parameters. Using a nonlinear estimation tool to fit a linear model is like using a Mack truck to carry a pea to Boston. A bit of over kill. But, yes, you could use lsqcurvefit. I won't bother to do so here.
A = [ones(size(x)),sind(x),sind(2*x),cosd(x),cosd(2*x)];
coefs = A\y
coefs = 5×1
3.1957 -0.1826 -0.4175 -0.2026 3.3489
plot(x,y,'ro')
hold on
fun = @(u,coefs) coefs(1) + coefs(2)*sind(u) + coefs(3)*sind(2*u) + coefs(4)*cosd(u) + coefs(5)*cosd(2*u);
plot(x,fun(x,coefs),'b-')
hold off
While there is a little lack of fit, it is not terrible. Look at the residual errors.
plot(x,y - fun(x,coefs),'o-')
Lack of fit is usually seen as patterning in the residuals. Here we see exactly that. So your model is probably not the correct model for this data, merely a good approximation to that data. By way of comparison, how much of the information in your original signal has been explained by the model?
[var(y),var(y - fun(x,coefs))]
ans = 1×2
6.1724 0.0445
As a percentage of the total variance...
100*(1 - var(y - fun(x,coefs))/var(y))
ans = 99.2797
So around 99% of the total variance in y has been explained by your model. So pretty good, but not perfect.
  3 个评论
Alessandro Ruda
Alessandro Ruda 2021-1-15
Thank you guys for your time! I didn't consider this way of solving it
John D'Errico
John D'Errico 2021-1-15
Yes. I think that too often people overlook that point, that a "linear" regression refers to the parameters. If the model is linear in the parameters, then it is a linear regression problem. Instead, people look at what they see as a NONLINEAR model, and accept that this must be a nonlinear regression. Not the end of the world, but this is, as I am known to say, is like using a Mack truck to carry a pea to Boston. (Don't ask where I learned the phrase.) You don't want to use a nonlinear estimation tool to solve a linear problem if you can avoid it, as that carries its own set of issues.

请先登录,再进行评论。

更多回答(1 个)

Jon
Jon 2021-1-14
It seems like you are not using the parameters you just solved for when evaluating your function to plot it.
Maybe you meant
plot(t,F(x,t))
  1 个评论
Jon
Jon 2021-1-14
编辑:Jon 2021-1-14
or if you want to compare the data points to the fitted curve
numFit = 1000; % for example
tfit = linspace(t(1),t(end),numFit)
plot(t,y,'o',tfit,F(x,tfit))

请先登录,再进行评论。

标签

产品

Community Treasure Hunt

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

Start Hunting!

Translated by