# Function fitting on a set of data points

4 ビュー (過去 30 日間)
Alessandro Ruda 2021 年 1 月 14 日
コメント済み: John D'Errico 2021 年 1 月 15 日
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:
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 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 件のコメント表示非表示 2 件の古いコメント
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
plot(t,F(x,t))
##### 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)
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!