Polyfit isn't adjusting to decreasing sinoidal data
Show older comments
Data is uploaded via excel and plots properly, finding peaks properly. Simply what am I doing wrong that polyfit produces such nonsense? I already tried inputing a dummy sinoidal wave in the command window and polyfit easily does it. I've tried with up to 100th degrees and nothing even comes close.
% Read the file
data = readtable("File Path");
% Extract time and gyroscope y columns
timeData = data.Time;
gyroYData = data.GyroscopeY;
% Filter data no longer than 16 seconds
idx = timeData <= 16;
timeData = timeData(idx);
gyroYData = gyroYData(idx);
% Plot the relevant data
figure;
plot(timeData, gyroYData, 'b-', 'LineWidth', 1.5);
xlabel('Time (s)');
ylabel('Gyroscope Y (rad/s)');
title('Gyroscope Y vs Time');
grid on;
% Find the peaks for the data
% Identify the peaks in the gyroscope data
[peaks, locs] = findpeaks(gyroYData, 'MinPeakHeight', 0.5, 'MinPeakDistance', 10);
peakTimes = timeData(locs);
% Plot the peaks alongside the data
hold on;
plot(peakTimes, peaks, 'ro', 'MarkerSize', 8, 'DisplayName', 'Detected Peaks');
% Find a polynomial aproximation and evaluate it
% Fit a polynomial to the gyroscope data
[p, S] = polyfit(timeData, gyroYData, 50);
fittedValues = polyval(p, timeData);
% Plot the polynomial alongside the original data and the peaks
plot(timeData, fittedValues, 'g--', 'LineWidth', 1.2, 'DisplayName', 'Polynomial Fit');
legend('Gyroscope Y Data', 'Detected Peaks', 'Polynomial Fit');
hold off;
This is the output I get:

Accepted Answer
More Answers (2)
Polynomial fitting above 10 degrees or so is a famously ill-conditioned numerical task, see also,
It is not clear why you would be modeling as a polynomial when you already know it is a sinusoid.
4 Comments
Ander
on 17 Sep 2025
David Goodmanson
on 17 Sep 2025
Edited: David Goodmanson
on 18 Sep 2025
Hi Ander,
AI has its uses for sure, but there are innumerable cases like this one, where copilot is more than happy to recommend something, anything, but copilot has absolutely no clue of what it is talking about.
Sam Chak
on 17 Sep 2025
Hi @Ander
You mentioned "modeling". However, it is necessary to distinguish between modeling the gyroscope system and fitting the gyroscope response. Fitting the curve involves finding the mathematical function
that describes the input-output relationship. If you intend to use the fitted function
to predict other time responses, that is not modeling. Modeling the system is about determining the governing differential equation,
or
that produces the time response of the system from arbitrary initial conditions, such as initial position and initial velocity.
Do not rely 100% on Copilot. While Copilot may interpret your intention as fitting the data, your objective is probably to identify the governing model of the mechanical gyroscope, which may be a 2nd-order differential equation.
@Ander if you have the Curve Fitting Toolbox, one approach would be:
STEP 1: FIt an envelope function to the (locs,peaks) data extracted in your code. For example an exponential function, if that's what the decay is supposed to be, would be:
x = locs(:); % ensure column vector
y = peaks(:); % ensure column vector
% Fit the exponential model y = a*exp(b*x)
fenv = fit(x, y, 'exp1');
STEP 2: Use step 1 to undo the decay of gyroData, convering it to a pure sinusoid. Then fit with that:
x = timeData(:);
y = gyroData(:)./fenv(gyroData(:)); % Flatten the decay
% Fit the sinusoidal model y=a*sin(b*x+c)
fsin = fit(x, y, 'sin1');
STEP 3: Refine the above parameter estimates by fitting with a simultaneous custom model. Use the the parameters from fenv and fsin to get a good startpoint for the iterative solution process:
ft = fittype('A*exp(-alpha*x).*sin(omega*x + phi)', ...
'independent', 'x', ...
'coefficients', {'A','alpha','omega','phi'});
startPoints = [fenv.a*fsin.a, -fenv.b, fsin.b, fsin.c];
% Redo fit with a comprehensive model
fTotal = fit(timeData(:), gyroData(:), ft, 'StartPoint', startPoints);
plot(fTotal, timeData(:), gyroData(:))
Walter Roberson
on 16 Sep 2025
[p, S] = polyfit(timeData, gyroYData, 50);
Your time data ranges from 0 to 16.
With a 50 degree polynomial, and without using centering and scaling, the contribution of the x coefficient would be from 0^50 to 16^50, which is a range from 0 to 1.607e60
Values in the range 1e60 completely wash out values in the range 0 to 8^50 . You are using a garbage fit.The maximum degree that can be used with your data without washing away coefficients is degree 13.
1 Comment
Walter Roberson
on 17 Sep 2025
On the right hand side of the graph, you have a section that is clearly going to zero.
Polynomial fits of data will go to +infinity or -infinity, because the leading coefficient a*x^n will eventually overwhelm everything else as x goes to infinity.
Therefore the only fit that makes sense for this graph, is the everywherre-zero polynomial.
Categories
Find more on Spline Postprocessing in Help Center and File Exchange
Products
Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!
Start Hunting!