Fast and simple trend

6 vues (au cours des 30 derniers jours)
Azura Hashim
Azura Hashim le 17 Déc 2017
Commenté : Azura Hashim le 18 Déc 2017
Hi,
I need a fast and simple way to calculate the trend of a variable at each point in time for data over the preceding 1 hour. All I need is whether the trend is increasing or decreasing and to what degree. At the moment I am using fitlm to return the slope for each row but have found this to be too slow. Below is a simple example but my application has a much bigger dataset and I need at least an order of magnitude speedup. Appreciate some help please, especially if there are ways to vectorize the calculation. Thank you.
time=[0.2,0.8,0.9,1.1,1.2,1.7,1.8,2.1,2.2];
x=[0.2,0.4,0.5,0.7,1.1,0.7,0.6,1.7,2.1];
slopes=repmat(NaN,length(x),1);
for row=1:length(x)
startrow=find(time >= time(row)-1,1);
%calculate slope if there are more 2 or more data points
if row > startrow
temptime=time(startrow:row);
tempx=x(startrow:row);
mdl = fitlm(temptime,tempx);
slopes(row)=mdl.Coefficients.Estimate(2);
end
end

Réponse acceptée

the cyclist
the cyclist le 17 Déc 2017
Modifié(e) : the cyclist le 17 Déc 2017
You can do the fit directly with matrix operations. It should be roughly a gazillion times faster.
coeffs = [ones(size(temptime')) temptime']\tempx';
slopes(row) = coeffs(2);
There are presumably other efficiencies if you restructure your data ahead such that you do not need to do the transposes, or create the "ones" matrix inside the loop.
  1 commentaire
Azura Hashim
Azura Hashim le 18 Déc 2017
Thank you, this worked well!

Connectez-vous pour commenter.

Plus de réponses (1)

Jan
Jan le 17 Déc 2017
What about the faster polyfit:
time = [0.2,0.8,0.9,1.1,1.2,1.7,1.8,2.1,2.2];
x = [0.2,0.4,0.5,0.7,1.1,0.7,0.6,1.7,2.1];
slopes = NaN(length(x), 1);
for row = 1:length(x)
startrow = find(time >= time(row)-1,1);
if row > startrow
P = polyfit(time(startrow:row), x(startrow:row), 1);
slopes(row) = P(1);
end
end
If this is still too slow, use a leaner version of polyfit:
function p = LeanPolyFit1(x, y)
V = [x(:), ones(numel(x), 1)];
% Solve least squares problem:
[Q, R] = qr(V, 0);
p = transpose(R \ (transpose(Q) * y(:)));
end

Catégories

En savoir plus sur Curve Fitting Toolbox dans Help Center et File Exchange

Community Treasure Hunt

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

Start Hunting!

Translated by