- Provide your data, or a good example of it. Attach it in a .mat file to a comment or to your original question.
- Explain CLEARLY what you mean by fit, and what will be the purpose of this fit. What will you do with this curve fit? Do you just want a smooth curve that passes through the data as well as possible, while smoothing out the noise we see? A nice plot? Will you use it for predictive purposes? Do you want some pretty functional form you can write down in a report?
Curve fit or spline fit for a wavy function
2 ビュー (過去 30 日間)
古いコメントを表示
I have a data for which I need to fit a curve. The original data and the curve fit which I got using a 2nd order polynomial are shown below.
However, I need the fitted curve to be a smooth curve which lays on top of the original data (same form). What would be the best way to do it?
Thanks!
0 件のコメント
採用された回答
John D'Errico
2020 年 12 月 6 日
編集済み: John D'Errico
2020 年 12 月 6 日
If you really want help, then do several things.
That is, if you just want a reasonably smooth non-parametric curve drawn thrrough the data, then a good choice is something like a Savitsky Golay smooth. There are many other ways to do so too. You will NOT get any nice function out of this though.
If you want to draw a curve, and then use it for future purposes, I might recommend a least squares apline, or a smoothing spline. You can evaluate that spline at any point for predictive purposes. But again, a spline is NOT a model you can write down and have it look remotely pretty in a report. While you could write something down, that would take multiple pages just to write it all out.
Finally, you could postulate a nonlinear model, then estimate the coefficients of that model. It might fit reasonably well, but it will surely not be as good of a fit as the alternatives I have already recommended.
5 件のコメント
John D'Errico
2020 年 12 月 7 日
I don't think you paid any attention to what I said. You can evaluate the curve at ANY set of points. So what is the problem? I showed you eactly how to do that evaluation. Hint - what do you think these lines do:
spl(t)
or
slmeval(t,SLM)
Depending on which method you use for the fit.
Can you use polyfit otr polyval? NOOOOOOOOOOO!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
NO.
NO.
NO.
NO.
NO. PERIOD.
The curve you should completely lacks polynomial behavior. The result will be pure crap.
その他の回答 (3 件)
Ameer Hamza
2020 年 12 月 6 日
Use interp1(): https://www.mathworks.com/help/matlab/ref/interp1.html with 'spline' interpolation method.
1 件のコメント
John D'Errico
2020 年 12 月 6 日
編集済み: John D'Errico
2020 年 12 月 6 日
Note: this appears to be noisy data. interpolating splines tend to be bad ideas for noisy data. They don't smooth out the bumps, but in fact, will oscillate more wildly in the presence of noise.
Image Analyst
2020 年 12 月 6 日
編集済み: Image Analyst
2020 年 12 月 6 日
I'd simly use sgolayfilt() if you have the Signal Processing Toolbox. It's like a scanning polynomial filter. Pick an appropriate window, like 20 elements or whatever, and polynomial order, like 2 for quadratic, and get out the smoothed signal.
See 3 attached demos.
Attach your data if you need more help.
4 件のコメント
Image Analyst
2020 年 12 月 7 日
Well you posted 2 arrays, time and RPM both of which have 3670 elements, and one array t which has 983041 elements. Since you can't plot a 3670 RPM vs a 983041 element "t", I assumed the x axis was time and the y value was RPM and they matched up element for element. And the smoothed signal filteredSignal has the same number of elements as time and RPM, as it should.
One problem is that the range of t and time don't cover the same range, so you can't get values for RPM that are less than time(1) or more than time(end). They will show up as nan since there is nothing in RPM to interpolate in that range. But you can just simply add the line
filteredSignal2 = interp1(time, filteredSignal, t);
and get the values of filteredSignal for every value of t that is within the original time series which matches up with RPM. Again, if you have no values of RPM for those t, then the values will be nan there. Here is the new code:
% Read in and plot the original signal
load('RPM.mat')
load('t.mat')
load('Time.mat')
subplot(1, 2, 1);
plot(time, RPM,'r-','Linewidth',1)
title('Original Signal', 'fontSize', 20);
xlabel('t', 'fontSize', 20);
ylabel('RPM', 'fontSize', 20);
grid on;
% Filter the signal. Just one line of code!
filteredSignal = sgolayfilt(RPM, 2, 101); % 3670 elements.
filteredSignal2 = interp1(time, filteredSignal, t); % 983041 elements
% Done! Now make a fancy plot.
subplot(1, 2, 2);
plot(t, filteredSignal2,'b-','Linewidth',1)
title('Filtered Signal', 'fontSize', 20);
xlabel('t', 'fontSize', 20);
ylabel('RPM', 'fontSize', 20);
grid on;
g = gcf;
g.WindowState = 'maximized'
Bruno Luong
2020 年 12 月 6 日
編集済み: Bruno Luong
2020 年 12 月 6 日
You can use my tool
load('RPM.mat')
load('t.mat')
load('Time.mat')
% https://www.mathworks.com/matlabcentral/fileexchange/25872-free-knot-spline-approximation
pp = BSFK(time,RPM);
rpm = ppval(pp,t);
%plot(time,RPM,'b')
% hold on
plot(t,rpm,'r','Linewidth',1)
0 件のコメント
参考
カテゴリ
Help Center および File Exchange で Get Started with Curve Fitting Toolbox についてさらに検索
Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!
Start Hunting!