MATLAB Answers

Function fitting on a set of data points

조회 수: 4(최근 30일)
Alessandro Ruda
Alessandro Ruda 2021년 1월 14일
댓글: John D'Errico 2021년 1월 15일
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);
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
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,

채택된 답변

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?
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
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);
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
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 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
  댓글 수: 1
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)

댓글을 달려면 로그인하십시오.



Community Treasure Hunt

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

Start Hunting!

Translated by