Filter löschen
Filter löschen

Curve fit or spline fit for a wavy function

5 Ansichten (letzte 30 Tage)
Siddharth Gopujkar
Siddharth Gopujkar am 6 Dez. 2020
Kommentiert: Image Analyst am 7 Dez. 2020
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!

Akzeptierte Antwort

John D'Errico
John D'Errico am 6 Dez. 2020
Bearbeitet: John D'Errico am 6 Dez. 2020
If you really want help, then do several things.
  1. Provide your data, or a good example of it. Attach it in a .mat file to a comment or to your original question.
  2. 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?
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 Kommentare
John D'Errico
John D'Errico am 7 Dez. 2020
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.
Siddharth Gopujkar
Siddharth Gopujkar am 7 Dez. 2020
Ok, I uderstood now. It works!
Thank you so much, John!

Melden Sie sich an, um zu kommentieren.

Weitere Antworten (3)

Ameer Hamza
Ameer Hamza am 6 Dez. 2020
Use interp1(): https://www.mathworks.com/help/matlab/ref/interp1.html with 'spline' interpolation method.
  1 Kommentar
John D'Errico
John D'Errico am 6 Dez. 2020
Bearbeitet: John D'Errico am 6 Dez. 2020
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.

Melden Sie sich an, um zu kommentieren.


Image Analyst
Image Analyst am 6 Dez. 2020
Bearbeitet: Image Analyst am 6 Dez. 2020
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 Kommentare
Siddharth Gopujkar
Siddharth Gopujkar am 6 Dez. 2020
Thanks for this!
The plot looks good, but the filtered signal needs to have the same number of values as the vector 't'. So the filtered signal needs 98304 values.
Image Analyst
Image Analyst am 7 Dez. 2020
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'

Melden Sie sich an, um zu kommentieren.


Bruno Luong
Bruno Luong am 6 Dez. 2020
Bearbeitet: Bruno Luong am 6 Dez. 2020
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)

Community Treasure Hunt

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

Start Hunting!

Translated by