Curve fit or spline fit for a wavy function
Show older comments
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!

Accepted Answer
More Answers (3)
Ameer Hamza
on 6 Dec 2020
0 votes
Use interp1(): https://www.mathworks.com/help/matlab/ref/interp1.html with 'spline' interpolation method.
1 Comment
John D'Errico
on 6 Dec 2020
Edited: John D'Errico
on 6 Dec 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.
Image Analyst
on 6 Dec 2020
Edited: Image Analyst
on 6 Dec 2020
0 votes
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 Comments
Siddharth Gopujkar
on 6 Dec 2020
Image Analyst
on 6 Dec 2020
Try this code using the sgolayfilt() function built into the Signal Processing Toolbox.
% 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);
% Done! Now make a fancy plot.
subplot(1, 2, 2);
plot(time, filteredSignal,'b-','Linewidth',1)
title('Filtered Signal', 'fontSize', 20);
xlabel('t', 'fontSize', 20);
ylabel('RPM', 'fontSize', 20);
grid on;
g = gcf;
g.WindowState = 'maximized'

Siddharth Gopujkar
on 6 Dec 2020
Image Analyst
on 7 Dec 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'
Bruno Luong
on 6 Dec 2020
Edited: Bruno Luong
on 6 Dec 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)

Categories
Find more on Multirate Signal Processing in Help Center and File Exchange
Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!
Start Hunting!
