Finding Steepest Linear Portion of Data
Afficher commentaires plus anciens
I've been trying to use fitlm as a way of finding the steepest linear portion of a graph but cannot get it to work correctly. Perhaps there is a better way I could be finding this out?
Essentially I have data (stress and strain) which looks like the following:

I'm trying to use Matlab to automatically find the steepest linear portion of the graph. This is what I have been trying so far using the fitlm function.
R=0;
for x = 100:size(strain)
fitlm(strain(10:x),stress(10:x));
if ans.Rsquared.Ordinary > R
R=ans.Rsquared.Ordinary;
index=x;
end
end
I can get the code to go along the data and find out where the r-squared value seems to fit best and identify a linear region of the data, but how can I get Matlab to identify the steepest linear region?
This is the output of plotting from the start of the data to the index point:

1 commentaire
Oliver Ramos
le 17 Déc 2020
Hi Jonathan,
I have the same problem, I need to find the linear portion from my data points (quadratic) by finding the best R^2 based on a fixed window (number of data that forms a line). May I know how did you plot the resulting best linear portion from the code?
R=0;
for x = 100:size(strain)
fitlm(strain(10:x),stress(10:x));
if ans.Rsquared.Ordinary > R
R=ans.Rsquared.Ordinary;
index=x;
end
end
Réponse acceptée
Plus de réponses (1)
Image Analyst
le 1 Sep 2015
Steepest over what range of x? From one element to the next? Over 5 or 10 elements? Can you attach numerical data?
How about just scanning the data and fitting a line over the range, and keeping track of which location has the highest slope? Something like (untested):
maxSlope = -inf;
windowWidth = 5; % Whatever...
maxk = 1;
for k = 1 : length(x) - windowWidth
% Get a subset of the data that is just within the window.
windowedx = x(k:k+windowWidth-1);
windowedy = y(k:k+windowWidth-1);
% Fit a line to that chunk of data.
coefficients = polyfit(windowedx, windowedy, 1);
% Get the slope.
slope = coefficients(1);
% See if this slope is steeper than any prior slope.
if slope > maxSlope
% It is steeper. Keep track of this one.
maxSlope = slope
maxk = k;
end
end
2 commentaires
Pietro Picerno
le 5 Nov 2024
Modifié(e) : Pietro Picerno
le 5 Nov 2024
very smart! Just tested. It works fine. I'd have preferred as an output an array of indices containing the less steep region, but I assume that maxk is the beginning of such a region. Thanks @Image Analyst
Image Analyst
le 5 Nov 2024
@Pietro Picerno for the least steep sections, you can do the obvious modifications:
minSlope = inf;
windowWidth = 5; % Whatever...
minSlopeIndex = 1;
for k = 1 : length(x) - windowWidth
% Get a subset of the data that is just within the window.
windowedx = x(k:k+windowWidth-1);
windowedy = y(k:k+windowWidth-1);
% Fit a line to that chunk of data.
coefficients = polyfit(windowedx, windowedy, 1);
% Get the slope.
slope = abs(coefficients(1)); % Use abs so it doesn't matter if it's a + or - slope.
% See if this slope is flatter than any prior slope.
if slope < minSlope
% It is steeper. Keep track of this one.
minSlope = slope
minSlopeIndex = k;
end
end
Not sure what you mean by an array. There is only one flattest portion, unless you have multiple sections where the slope is the same, like a slope value of 0. You can do that also if that's the case by doing something like this:
minSlope = inf;
windowWidth = 5; % Whatever...
minSlopeIndex = 1;
% First scan all the data to collect slopes everywhere.
% Need to do this first so we can determine the overall globa minimum slope.
for k = 1 : length(x) - windowWidth
% Get a subset of the data that is just within the window.
windowedx = x(k:k+windowWidth-1);
windowedy = y(k:k+windowWidth-1);
% Fit a line to that chunk of data.
coefficients = polyfit(windowedx, windowedy, 1);
% Get the slope.
thisSlope = abs(coefficients(1)); % Use abs so it doesn't matter if it's a + or - slope.
% Store the kth slope
allSlopes(k) = thisSlope;
end
% From the vector of all the slopes, find the minimum slope
minSlope = min(allSlopes)
% Now find the indexes where the slopes occur.
% Use find() because there may be more than one location.
minSlopeIndexes = find(allSlopes == minSlope)
If you want, you can examine allSlopes to determine all the slopes. You can sort them if you want.
Catégories
En savoir plus sur Correlation and Convolution dans Centre d'aide et File Exchange
Produits
Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!
Start Hunting!

